[解決済み] xibで再利用可能なUIViewを作成する(storyboardから読み込むことも可能)。
質問
StackOverflow にこの件に関する投稿が何十件もありますが、解決策について特に明確なものはありません。私は、カスタム
UIView
を作成したいのですが、付属の xib ファイルが必要です。要件は次のとおりです。
-
個別の
UIViewController
- 完全に自己完結したクラス - ビューのプロパティを設定/取得できるようにするためのクラス内のアウトレット。
これを行うための私の現在のアプローチは
-
オーバーライド
-(id)initWithFrame:
-(id)initWithFrame:(CGRect)frame { self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] objectAtIndex:0]; self.frame = frame; return self; }
-
を使用してプログラム的にインスタンス化します。
-(id)initWithFrame:
でインスタンス化します。MyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; [self.view insertSubview:myCustomView atIndex:0];
これは問題なく動作します(ただし、決して
[super init]
を呼び出さず、ロードされた nib の内容を使って単にオブジェクトを設定するのは、少し疑わしいと思われます。
でサブビューを追加するアドバイスがあります。
というアドバイスがありますが、これも問題なく動作します)。しかし、私はストーリーボードからビューをインスタンス化することができるようにしたいと思います。だから私はできる。
-
を配置する。
UIView
をストーリーボード内の親ビューに配置します。 -
そのカスタムクラスを
MyCustomView
-
オーバーライド
-(id)initWithCoder:
- のようなコードで、私が最もよく目にするのは、以下のようなパターンに当てはまります。-(id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self initializeSubviews]; } return self; } -(id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self initializeSubviews]; } return self; } -(void)initializeSubviews { typeof(view) view = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] objectAtIndex:0]; [self addSubview:view]; }
もちろん、これはうまくいきません。上記の方法を使おうが、プログラムでインスタンス化しようが、どちらも再帰的に
-(id)initWithCoder:
に入った後
-(void)initializeSubviews
と入力し、ファイルからnibを読み込む。
他のいくつかのSOの質問は、このようなことを扱っています。 ここで , ここ , ここ そして はこちら . しかし、与えられた答えのどれも満足のいく形で問題を解決することはできません。
- 一般的な提案は、クラス全体を UIViewController に埋め込み、そこで nib の読み込みを行うことのようですが、これはラッパーとして別のファイルを追加する必要があるため、私には最適とは思えません。
どなたか、この問題を解決する方法、およびカスタム
UIView
でアウトレットを動作させる方法を教えてください。あるいは、最小限の定型的なコードで物事を行う、よりクリーンな代替方法があるのでしょうか?
どのように解決するのですか?
あなたの問題は
loadNibNamed:
の子孫)から
initWithCoder:
.
loadNibNamed:
は内部で
initWithCoder:
. もし、ストーリーボードコーダーをオーバーライドして、常にxibの実装をロードしたいのであれば、次のテクニックをお勧めします。ビュークラスにプロパティを追加し、xibファイルの中で、(User Defined Runtime Attributesに)あらかじめ決められた値を設定するのです。ここで
[super initWithCoder:aDecoder];
を呼び出したら、プロパティの値を確認します。あらかじめ決められた値であれば
[self initializeSubviews];
.
ということで、こんな感じ。
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self && self._xibProperty != 666)
{
//We are in the storyboard code path. Initialize from the xib.
self = [self initializeSubviews];
//Here, you can load properties that you wish to expose to the user to set in a storyboard; e.g.:
//self.backgroundColor = [aDecoder decodeObjectOfClass:[UIColor class] forKey:@"backgroundColor"];
}
return self;
}
-(instancetype)initializeSubviews {
id view = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];
return view;
}
関連
-
[iOS]コンパイルエラー:ld: アーキテクチャ x86_64 のシンボルが見つかりません。
-
[エラー処理】iOSのエラー、アーキテクチャx86_64の未定義シンボルについて
-
iOS classic error Undefined symbols for architecture XXX:
-
[解決済み] Xcode 6.3 - 現在の iOS Development 証明書または保留中の証明書要求がすでにあります。
-
[解決済み] App Storeのアプリと連動させる方法
-
[解決済み] NSの接頭辞はどういう意味ですか?
-
[解決済み] IBOutletsはARCのもとで強くなるべきか、弱くなるべきか?
-
[解決済み] UILabelで複数行のテキストを表示する
-
[解決済み] Cocoapods警告 - CocoaPodsがプロジェクトの基本構成を設定しなかった理由は、プロジェクトに既にカスタム構成が設定されているためです。
-
[解決済み】ストーリーボードで、複数のコントローラで使用するためのカスタムセルを作成する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] iOSのバージョンを確認する方法を教えてください。
-
[解決済み] Xcodeにおけるバージョンとビルドの比較
-
[解決済み] UIViewに角丸をつける
-
[解決済み] iPhone UITextField - プレースホルダーの文字色を変更する
-
[解決済み] Swift 3でディスパッチキューを作成する方法
-
[解決済み] iPhoneでナビゲーションバーを1ページ目だけ非表示にする
-
[解決済み] iOSのカスタムビュークラスを作成し、その複数のコピーを(IBで)インスタンス化するにはどうすればよいですか?
-
[解決済み] UIView で xib ファイルを読み込む方法
-
[解決済み] UIViewサブクラスのNibをロードする正しい方法
-
[解決済み] Objective-Cのクラスタとは何ですか?