SwiftのAppearanceWhenContainedIn


125

アプリをSwift言語に変換しようとしています。

私はこのコード行を持っています:

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil]
                     setTitleTextAttributes:textDictionary
                                   forState:UIControlStateNormal];

Swiftに変換する方法は?

では、Appleのドキュメントは、そのような方法がありません。


1
@LukeTheObscureは以下の私の答えをチェックしてください...醜いですが、動作します。
tcd

回答:


230

iOS 9のアップデート:

iOS 9+をターゲットにしている場合(Xcode 7 b1以降)、UIAppearancevarargsを使用しないプロトコルに新しいメソッドがあります。

static func appearanceWhenContainedInInstancesOfClasses(containerTypes: [AnyObject.Type]) -> Self

これは次のように使用できます:

UITextField.appearanceWhenContainedInInstancesOfClasses([MyViewController.self]).keyboardAppearance = .Light

それでもiOS 8以前をサポートする必要がある場合は、この質問に対する次の元の回答を使用してください。

iOS 8および7の場合:

Obj-C varargsメソッドはSwiftと互換性がないため、これらのメソッドはSwiftでは使用できません(http://www.openradar.me/17302764を参照)。

私はSwiftで機能する非多様な回避策を書きました(私はUIBarItemから派生しない同じ方法を繰り返しましたUIView):

// UIAppearance+Swift.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIView (UIViewAppearance_Swift)
// appearanceWhenContainedIn: is not available in Swift. This fixes that.
+ (instancetype)my_appearanceWhenContainedIn:(Class<UIAppearanceContainer>)containerClass;
@end
NS_ASSUME_NONNULL_END

// UIAppearance+Swift.m
#import "UIAppearance+Swift.h"
@implementation UIView (UIViewAppearance_Swift)
+ (instancetype)my_appearanceWhenContainedIn:(Class<UIAppearanceContainer>)containerClass {
    return [self appearanceWhenContainedIn:containerClass, nil];
}
@end

ちょうど#import "UIAppearance+Swift.h"あなたのブリッジングヘッダーにあることを確認してください。

次に、(たとえば)Swiftから呼び出すには:

# Swift 2.x:
UITextField.my_appearanceWhenContainedIn(MyViewController.self).keyboardAppearance = .Light

# Swift 3.x:
UITextField.my_appearanceWhenContained(in: MyViewController.self).keyboardAppearance = .light

15
UIBarButtonItemはUIViewではないため、個別に拡張する必要があります
Sergey Skoblikov

7
少なくともiOS8では、UIAppearance + Swift.hはUIKit / UIKit.hをインポートする必要があることに注意してください
Chase

UIViewの代わりにUIBarButtonItemをターゲットとする別のメソッドを作成するだけでも、UIBarButtonItemをサポートできます。@interface UIBarButtonItem(UIViewAppearance_Swift)
Michael Peterson

1
@rptwsthi:Swift 3の例を追加しましたが、少し異なります
Alex Pretzlav

1
Swift 3.2のiOS 9バージョンは、UIBarButtonItem.appearance(whenContainedInInstancesOf:[UISearchBar.self])。title = "Done"
Eli Burke

31

ios 10 swift 3

UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Kapat"

1
これがiOS10 Swift 3で行う方法であるため、なぜこれが反対票なのかわからない。ありがとう
Vassily

14

iOS 8および7の場合:

Alexの回答に基づくカテゴリを使用して、複数のコンテナを指定します。これは、Apple appearanceWhenContainedInがSwiftで正式にサポートするまでの回避策です。

UIAppearance + Swift.h

@interface UIView (UIAppearance_Swift)
/// @param containers An array of Class<UIAppearanceContainer>
+ (instancetype)appearanceWhenContainedWithin: (NSArray *)containers;
@end

UIAppearance + Swift.m

@implementation UIView (UIAppearance_Swift)

+ (instancetype)appearanceWhenContainedWithin: (NSArray *)containers
{
    NSUInteger count = containers.count;
    NSAssert(count <= 10, @"The count of containers greater than 10 is not supported.");
    
    return [self appearanceWhenContainedIn:
            count > 0 ? containers[0] : nil,
            count > 1 ? containers[1] : nil,
            count > 2 ? containers[2] : nil,
            count > 3 ? containers[3] : nil,
            count > 4 ? containers[4] : nil,
            count > 5 ? containers[5] : nil,
            count > 6 ? containers[6] : nil,
            count > 7 ? containers[7] : nil,
            count > 8 ? containers[8] : nil,
            count > 9 ? containers[9] : nil,
            nil];
}
@end

次に#import "UIAppearance+Swift.h"、ブリッジヘッダーに追加します。

Swiftから使用するには

TextField.appearanceWhenContainedWithin([MyViewController.self, TableViewController.self]).keyboardAppearance = .Light

CVarArgTypeを使用して方法を見つけることができれば良かったのですが、明確な解決策が見つかりませんでした。


varargsの壊れ具合に対する適切な回避策!AppleのiOS 9のみの方法を(現在)使用する以外に、一般的な解決策はありません。
Alex Pretzlav

12

ここでは、@ tdunに触発された、見苦しくはありませんが、見苦しい回避策を示します。

  1. Objective-Cの外観を保持するクラスを作成します。この例では、これを呼び出しますAppearanceBridger
  2. このクラスをブリッジヘッダーに追加します。ブリッジヘッダーがない場合は、作成します
  3. AppearanceBridger名前付きでクラスメソッドを作成し、+(void)setAppearanceこのメソッドにObjective-Cの外観コードを配置します。例えば:


+ (void)setAppearance {
    [[UIView appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setBackgroundColor:[UIColor whiteColor]];
}

  1. 外観を設定したSwiftコードで、を呼び出すAppearanceBridger.setAppearance()と、準備完了です。

これがそれを見る人々にとってうまくいくことを願っています。


4

これは私が使った醜い回避策の解決策です...

Objective-C Cocoaタッチクラス(UIViewController)を作成し、好きな名前を付けます。

私の名前はWorkaroundViewController...

現在(WorkaroundViewController.m)内:

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

Objective-Cの外観コードを実行します.appearanceWhenContainedIn()(これが私の例です)。

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Avenir-Light" size:16.0f]}];

次に、Swiftプロジェクトのブリッジヘッダー作成し、SwiftコードでObjective-C ViewControllerを次のように初期化します(ここでも、例を示します)。

var work : WorkaroundViewController = WorkaroundViewController()

これで完了です。それがあなたのために働くかどうか私に知らせてください...私が言ったように、それは醜いですが、うまくいきます!


これはtmpソリューションです。いくつかのより良い方法を見つけるか、待つ必要があると思います:)
AlexZd

@AlexZd、絶対に、私はそれが迅速に含まれることを願っています...しかし、今のところ、あなたがそれを必要とするなら、そこに行きます!
TCD

4

これは、UIViewsだけでなく、UIAppearanceプロトコルに準拠する任意のクラスに拡張できます。より一般的なバージョンは次のとおりです。

UIAppearance + Swift.h

#import <UIKit/UIKit.h>

@interface NSObject (UIAppearance_Swift)

+ (instancetype)appearanceWhenContainedWithin:(Class<UIAppearanceContainer>)containerClass;

@end

UIAppearance + Swift.m

#import "UIAppearance+Swift.h"

@implementation NSObject (UIAppearance_Swift)

+ (instancetype)appearanceWhenContainedWithin:(Class<UIAppearanceContainer>)containerClass {
    if ([self conformsToProtocol:@protocol(UIAppearance)]) {
        return [(id<UIAppearance>)self appearanceWhenContainedIn:containerClass, nil];
    }
    return nil;
}

@end

3

私はあなたが使用したいあなたのためにレポを作成しましたCocoaPods

  1. これをあなたの中に追加してくださいPodfile

    pod 'UIViewAppearanceSwift'
  2. クラスにインポート:

    import UIViewAppearanceSwift
    
    func layout() {
        UINavigationBar.appearanceWhenContainedWithin(MFMailComposeViewController.self).barStyle = .Black
        UIBarButtonItem.appearanceWhenContainedWithin(UISearchBar.self).setTitleTextAttributes([NSFontAttributeName: UIFont.systemFontOfSize(15)], forState: UIControlState.Normal)
    }
  3. リファレンス:https : //github.com/levantAJ/UIViewAppearanceSwift



0

Swift(少なくともBeta5以降)は、私には知られていない理由でそれをサポートできないようです。おそらく、必要な言語機能はまだ進行中です。私はそれらが適切な理由でインターフェースから除外されているとしか想定できないからです。あなたが言ったように、ドキュメントによると、それはまだObjCで利用可能です。本当に残念です。


これは、@ spinillosメソッドを使用してBeta 5で私に働きました。
Jason Crump 2014

そうappearanceWhenContainedIn:です、まだテーブルから外れています。
hlfcoding 2014

-3

あなたはこれを使うことができます:

UIBarButtonItem.appearance().setTitleTextAttributes(textDictionary, forState: UIControlState.Normal)

編集:AppearanceWhenContainedInはSwiftから削除されました。この回答は、ベータ5がすべてのバーボタンのテキストの外観を変更するためのものでした。


1
また、使用するUIControlState.Normal必要はなく、.NormalSwiftは推論によってタイプを知っているだけで使用できます。
ベンラックマン2014

12
これは、特定のUIBarButtonItemの外観ではなく、すべてのUIBarButtonItemの外観を変更します
Kostiantyn Koval

@KonstantinKovalまさに-それが外観プロキシの目的です。すべてのビューコントローラーに定型コード/メソッド呼び出しを含める必要なく、アプリケーション全体のスタイルを設定できます。
Craig Otis、

3
これは実際には質問に答えません。Swift appearanceWhenContainedInでは削除されました。
Tim Windsor Brown、

-7

Objective-C構文をSwift構文に変換するだけでよいはずです。

迅速に、メソッドは次のように宣言されるべきです:

func appearanceWhenContainedIn(containerClass : <UIAppearanceContainer>)
func setTitleTextAttributes(_ attributes: NSDictionary!, forState state: UIControlState)

だからあなたはこれを試すことができます:

UIBarButtonItem.appearanceWhenContainedIn(UINavigationBar).setTitleTextAttributes(textDictionary, forState: UIControlStateNormal)

Swiftただし、これがクラスメソッドを呼び出すためのクリーンな方法であるかどうかはまだわかりません。

お役に立てれば、


1
コンパイルされていない迅速な方法では、このメソッドのAppearanceWhenContainedInはありません。エラー:「UIBarButtonItem.Type」には「appearanceWhenContainedIn」という名前のメンバーがありません
AlexZd

こんにちは@AlexZdです。コメントは実際のXCode 6ベータに基づいていますが、UIAppearanceプロトコルドキュメント(UIBarButtonItem準拠)を見ると、 `appearanceWhenContainedIn(_ :)メソッドが存在します(Swiftにはまだ実装されていません):developer.apple .com / library / prerelease / ios / documentation / UIKit /…
Zedenem 14

@Zedenemは、私はそれが本当にばかだ、知っているとあなたは私たちを信じたくない-しかし、文字通りスウィフトから呼び出すことはできませんこの方法では、ドキュメントをチェック:developer.apple.com/library/ios/documentation/UIKit/Reference/...を -メソッドはSwiftから隠されています
powerj1984

@ powerj1984さん、こんにちは。私はあなたを信じたくないわけではありません。回答を書いた時点で、これはSwiftのベータ版のステータスによるものだと思っていました。このメソッドは廃止されておらず、Swiftから隠されているだけというのは本当に奇妙なことで、Appleからの説明がないと最悪です...しかし、理由がわからなくても、あなたの言うとおりです。私の答え間違っている。たぶんSwiftにある機能で私はそれだけでそれができるとは思っていません...
Zedenem

はは、ごめんなさい-私は本当に私を信じたくないという意味です。Appleが失敗するのは、とんでもないことだ。一体なんか変!
powerj1984 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.