241

少し手の込んだことをしようとしていますが、可能なはずです。ですから、ここに専門家の皆さんへの挑戦があります (このフォーラムは多くの皆さんの集まりです :) )。

NavigationContoller(my )にロードしたいアンケート「コンポーネント」を作成していますQuestionManagerViewController。「コンポーネント」は「空」UIViewControllerであり、回答が必要な質問に応じてさまざまなビューをロードできます。

私がやっている方法は次のとおりです。

  1. UIViewサブクラスとして Question1View オブジェクトを作成し、 some を定義しますIBOutlets
  2. (Interface Builder を使用して) Question1View.xib (HERE IS WHERE MY PROBLEM PROBABLY IS ) を作成します。UIViewControllerと の両方をUIViewQuestion1View クラスに設定しました。
  3. アウトレットをビューのコンポーネントにリンクします (IB を使用)。
  4. initWithNibmyをオーバーライドして、次のQuestionManagerViewControllerようにします。

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        if (self = [super initWithNibName:@"Question1View" bundle:nibBundleOrNil]) {
            // Custom initialization
        }
        return self;
    }
    

コードを実行すると、次のエラーが発生します。

2009-05-14 15:05:37.152 iMobiDines[17148:20b] *** 例外がキャッチされなかったためアプリを終了します ' NSInternalInconsistencyException', 理由: ' -[UIViewController _loadViewFromNibNamed:bundle:]「Question1View」ペン先をロードしましたが、ビュー アウトレットが設定されていませんでした.'

viewController クラスを作成する必要なく、nib ファイルを使用してビューをロードする方法があると確信しています。

4

24 に答える 24

224

nib を配列として扱う代わりに、ビューにアクセスする簡単な方法もあります。

1 ) 後でアクセスしたいアウトレットを含むカスタム View サブクラスを作成します。 - 私の見解

2 ) nib をロードして処理する UIViewController で、ロードされた nib のビューを保持する IBOutlet プロパティを作成します。

MyViewController (UIViewController サブクラス) 内

  @property (nonatomic, retain) IBOutlet UIView *myViewFromNib;

(合成して .m ファイルでリリースすることを忘れないでください)

3) IB で nib (「myViewNib.xib」と呼びます) を開き、ファイルの所有者をMyViewControllerに設定します。

4)ファイルの Owner アウトレット myViewFromNib を nib のメイン ビューに接続します。

5) MyViewController に次の行を記述します。

[[NSBundle mainBundle] loadNibNamed:@"myViewNib" owner:self options:nil];

これを行うとすぐに、プロパティ「self.myViewFromNib」を呼び出すと、ペン先からビューにアクセスできるようになります!

于 2010-10-29T19:45:48.413 に答える
72

一部の回答が何について話しているのかわかりませんが、次回 Google で検索するときのために、この回答をここに入れる必要があります。キーワード: 「ペン先から UIView をロードする方法」または「NSBundle から UIView をロードする方法」。

これは、Apress Beginning iPhone 3 book (page 247, "Using The New Table View Cell")からほぼ 100% そのままのコードです。

- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:@"Blah"
                                                 owner:self options:nil];
    Blah *blah;
    for (id object in bundle) {
        if ([object isKindOfClass:[Blah class]]) {
            blah = (Blah *)object;
            break;
        }
    }   
    assert(blah != nil && "blah can't be nil");
    [self.view addSubview: blah];
} 

これは、クラスが に設定されているを含むnib という名前のUIViewサブクラスがあると仮定します。BlahBlahUIViewBlah


カテゴリ: NSObject+LoadFromNib

#import "NSObject+LoadFromNib.h"

@implementation NSObject (LoadFromNib)

+ (id)loadFromNib:(NSString *)name classToLoad:(Class)classToLoad {
    NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:name owner:self options:nil];
    for (id object in bundle) {
        if ([object isKindOfClass:classToLoad]) {
            return object;
        }
    }
    return nil;
}

@end

スウィフト拡張

extension UIView {
    class func loadFromNib<T>(withName nibName: String) -> T? {
        let nib  = UINib.init(nibName: nibName, bundle: nil)
        let nibObjects = nib.instantiate(withOwner: nil, options: nil)
        for object in nibObjects {
            if let result = object as? T {
                return result
            }
        }
        return nil
    }
}

そして使用例:

class SomeView: UIView {
    class func loadFromNib() -> SomeView? {
        return self.loadFromNib(withName: "SomeView")
    }
}
于 2010-07-07T01:54:42.173 に答える
22

For all those that need to manage more than one instance of the custom view, that is an Outlet Collection, I merged and customized the @Gonso, @AVeryDev and @Olie answers in this way:

  1. Create a custom MyView : UIView and set it as "Custom Class" of the root UIView in the desired XIB; custom class

  2. Create all outlets you need in MyView (do it now because after point 3 the IB will propose you to connect outlets to the UIViewController and not to the custom view as we want); custom class outlet

  3. Set your UIViewController as "File's Owner" of the custom view XIB; enter image description here

  4. In the UIViewController add a new UIViews for each instance of MyView you want, and connect them to UIViewController creating an Outlet Collection: these views will act as "wrapper" views for the custom view instances; enter image description here

  5. Finally, in the viewDidLoad of your UIViewController add the following lines:

NSArray *bundleObjects;
MyView *currView;
NSMutableArray *myViews = [NSMutableArray arrayWithCapacity:myWrapperViews.count];
for (UIView *currWrapperView in myWrapperViews) {
    bundleObjects = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
    for (id object in bundleObjects) {
        if ([object isKindOfClass:[MyView class]]){
            currView = (MyView *)object;
            break;
        }
    }

    [currView.myLabel setText:@"myText"];
    [currView.myButton setTitle:@"myTitle" forState:UIControlStateNormal];
    //...

    [currWrapperView addSubview:currView];
    [myViews addObject:currView];
}
//self.myViews = myViews; if need to access them later..
于 2012-09-24T16:07:33.537 に答える
19

UINib を使用して、再利用するカスタム UIView をインスタンス化します。

UINib *customNib = [UINib nibWithNibName:@"MyCustomView" bundle:nil];
MyCustomViewClass *customView = [[customNib instantiateWithOwner:self options:nil] objectAtIndex:0];
[self.view addSubview:customView];

この場合に必要なファイルは、 MyCustomView.xibMyCustomViewClass.h、およびMyCustomViewClass.mです。これは配列 を[UINib instantiateWithOwner]返すため、再利用する UIView を反映する要素を使用する必要があります。この場合、それは最初の要素です。

于 2014-02-24T15:14:03.880 に答える
11

UIViewView ControllerのクラスをInterface Builderのサブクラスに設定しないでください。それは間違いなくあなたの問題の少なくとも一部です。UIViewController、そのサブクラス、または他のカスタムクラスのいずれかのままにしておきます。

xib からビューのみをロードすることに関しては、ある種のビュー コントローラーが必要であると想定してました (たとえそれが拡張されていなくてもUIViewController、ニーズに対して重すぎる可能性があります) インターフェイスのファイルの所有者として設定Builder を使用してインターフェースを定義する場合。私もこれを確認するために少し調査を行いました。これは、そうしないと、 のインターフェイス要素にアクセスする方法がなくUIView、コード内の独自のメソッドをイベントによってトリガーする方法がないためです。

UIViewControllerビューのファイルの所有者としてa を使用する場合は、initWithNibName:bundle:それをロードしてビュー コントローラー オブジェクトを取得するために使用できます。IB ではview、xib のインターフェイスを使用して、アウトレットをビューに設定していることを確認してください。ファイルの所有者として他のタイプのオブジェクトを使用する場合は、NSBundleloadNibNamed:owner:options:メソッドを使用して nib をロードし、ファイルの所有者のインスタンスをメソッドに渡す必要があります。すべてのプロパティは、IB で定義したアウトレットに従って適切に設定されます。

于 2009-05-14T13:42:29.313 に答える
9

loadNibNamed の代わりに UIViewController の initWithNibName を使用することもできます。それはもっと簡単だと思います。

UIViewController *aViewController = [[UIViewController alloc] initWithNibName:@"MySubView" bundle:nil];
[self.subview addSubview:aViewController.view];
[aViewController release];  // release the VC

あとは、MySubView.xib と MySubView.h/m を作成するだけです。MySubView.xib で、File's Owner クラスを UIViewController に設定し、ビュー クラスを MySubView に設定します。

subview親の xib ファイルを使用して、の位置とサイズを指定できます。

于 2011-10-15T15:39:55.130 に答える
8

これはもっと簡単なはずです。セレクターを拡張UIViewControllerして追加することになりました。loadNib:inPlaceholder:今私は言うことができます

self.mySubview = (MyView *)[self loadNib:@"MyView" inPlaceholder:mySubview];

カテゴリのコードは次のとおりです(Gonsoによって説明されているのと同じリガマロールを実行します)。

@interface UIViewController (nibSubviews)

- (UIView *)viewFromNib:(NSString *)nibName;
- (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder;

@end

@implementation UIViewController (nibSubviews)

- (UIView *)viewFromNib:(NSString *)nibName
{
  NSArray *xib = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil]; 
  for (id view in xib) { // have to iterate; index varies
    if ([view isKindOfClass:[UIView class]]) return view;
  }
  return nil;
}

- (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder
{
  UIView *nibView = [self viewFromNib:nibName];
  [nibView setFrame:placeholder.frame];
  [self.view insertSubview:nibView aboveSubview:placeholder];
  [placeholder removeFromSuperview];
  return nibView;
}

@end
于 2011-08-30T00:20:00.557 に答える
8

これは素晴らしい質問 (+1) であり、回答はほとんど役に立ちました ;) 申し訳ありませんが、Gonso と AVeryDev の両方が良いヒントを提供してくれましたが、私はこれに苦労しました。うまくいけば、この答えは他の人に役立ちます。

MyVCこれらすべてのものを保持するView Controllerです。

MySubviewxibからロードしたいビューです

  • MyVC.xib でMySubView、適切なサイズ、形状、および必要な場所に配置されたタイプのビューを作成します。
  • MyVC.h には、

    IBOutlet MySubview *mySubView
    // ...
    @property (nonatomic, retain) MySubview *mySubview;
    
  • MyVC.m で、@synthesize mySubView;でリリースすることを忘れないでくださいdealloc

  • MySubview.h に、アウトレット/プロパティを用意しますUIView *view(不要かもしれませんが、私にとってはうまくいきました)。.m で合成してリリースします。
  • MySubview.xib 内
    • ファイル所有者タイプを に設定しMySubview、ビュー プロパティをビューにリンクします。
    • すべてのビットをレイアウトし、必要に応じて に接続しIBOutletます
  • MyVC.m に戻ります。

    NSArray *xibviews = [[NSBundle mainBundle] loadNibNamed: @"MySubview" owner: mySubview options: NULL];
    MySubview *msView = [xibviews objectAtIndex: 0];
    msView.frame = mySubview.frame;
    UIView *oldView = mySubview;
    // Too simple: [self.view insertSubview: msView aboveSubview: mySubview];
    [[mySubview superview] insertSubview: msView aboveSubview: mySubview]; // allows nesting
    self.mySubview = msView;
    [oldCBView removeFromSuperview];
    

私にとってトリッキーな点は、他の回答のヒントがxibからビューをロードしましたが、MyVCのビューを置き換えませんでした(当たり前です!)-私はそれを自分で交換する必要がありました。

mySubviewまた、のメソッドにアクセスするviewには、.xib ファイルのプロパティを に設定する必要がありますMySubview。それ以外の場合は、昔ながらの として返されUIViewます。

mySubview独自の xib から直接ロードする方法があれば、それは素晴らしいことですが、これで必要な場所にたどり着きました。

于 2011-07-08T23:33:09.803 に答える
7

迅速に

実際、この問題に対する私の解決策は、ビューを次のように使用したい CustonViewController の viewDidLoad にビューをロードすることでした。

myAccessoryView = NSBundle.mainBundle().loadNibNamed("MyAccessoryView", owner: self, options: nil)[0] as! MyAccessoryView

メソッドでビューをロードしないでくださいloadView()! loadView メソッドは、カスタム ViewController のビューをロードするために使用されます。

于 2016-02-05T09:42:49.463 に答える
6

設計可能なオプションを持つ Swift ユーザーの場合:

  1. カスタムUIViewサブクラスと xib ファイルを作成し、独自のクラス名にちなんで名前を付けます: この場合は MemeView. @IBDesignableMeme View クラス内では、クラス宣言の前に属性でデザイン可能として定義することを忘れないでください
  2. UIViewRember は、Indetity Inspector パネルのカスタム サブクラスを使用して、xib でファイルの所有者を設定します。

    ここに画像の説明を入力

  3. xib ファイルでは、インターフェイスを構築し、制約を作成し、アウトレットやアクションなどを作成できます。 ここに画像の説明を入力

  4. 初期化された xib を開くには、カスタム クラスにいくつかのメソッドを実装する必要があります。

    class XibbedView: UIView {

    weak var nibView: UIView!
    
    override convenience init(frame: CGRect) {
        let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
        self.init(nibName: nibName)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
        let nib = loadNib(nibName)
        nib.frame = bounds
        nib.translatesAutoresizingMaskIntoConstraints = false
        addSubview(nib)
        nibView = nib
        setUpConstraints()
    }
    
    init(nibName: String) {
        super.init(frame: CGRectZero)
        let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
        let nib = loadNib(nibName)
        nib.frame = bounds
        nib.translatesAutoresizingMaskIntoConstraints = false
        addSubview(nib)
        nibView = nib
        setUpConstraints()
    }
    
    func setUpConstraints() {
        ["V","H"].forEach { (quote) -> () in
            let format = String(format:"\(quote):|[nibView]|")
            addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(format, options: [], metrics: nil, views: ["nibView" : nibView]))
        }
    }
    
    func loadNib(name: String) -> UIView {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: name, bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    
        return view
    }
    

    }

  5. カスタム クラスでは、インターフェイス ビルダーからそれらを完全に制御するために、いくつかの inspecatable プロパティを定義することもできます。

    @IBDesignable class MemeView: XibbedView {

    @IBInspectable var memeImage: UIImage = UIImage() {
        didSet {
            imageView.image = memeImage
        }
    }
    @IBInspectable var textColor: UIColor = UIColor.whiteColor() {
        didSet {
            label.textColor = textColor
        }
    }
    @IBInspectable var text: String = "" {
        didSet {
            label.text = text
        }
    }
    @IBInspectable var roundedCorners: Bool = false {
        didSet {
            if roundedCorners {
                layer.cornerRadius = 20.0
                clipsToBounds = true
            }
            else {
                layer.cornerRadius = 0.0
                clipsToBounds = false
            }
        }
    }
    
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var imageView: UIImageView!
    

}

いくつかの例:
ここに画像の説明を入力 ここに画像の説明を入力

ストーリーボードまたは別の xib 内に表示されている間にビューにさらに情報を追加する必要がある場合は、実装できますprepareForInterfaceBuilder()。このメソッドは、インターフェイス ビルダーでファイルを開いているときにのみ実行されます。私が書いたすべてを実行しても何も機能しない場合は、実装にブレークポイントを追加して単一のビューをデバッグする方法です。 これがビューの階層です。 ここに画像の説明を入力
階層を表示

これが役立つことを願っています 完全なサンプルはここからダウンロードできます

于 2016-06-18T08:00:50.373 に答える
6

私も似たようなことをしたかったのですが、これが私が見つけたものです:(SDK 3.1.3)

ボタンを押すとVC BをロードするView Controller A(Navコントローラーが所有)があります:

AViewController.m 内

BViewController *bController = [[BViewController alloc] initWithNibName:@"Bnib" bundle:nil];
[self.navigationController pushViewController:bController animated:YES];
[bController release];

現在、VC B には Bnib からのインターフェイスがありますが、ボタンを押すと、別の nib とは別の UI を持つ「編集モード」に移動したいのですが、編集モード用の新しい VC は必要ありません。新しい nib を既存の B VC に関連付けたいです。

ということで、BViewController.mで(ボタン押下メソッドで)

NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"EditMode" owner:self options:nil];
UIView *theEditView = [nibObjects objectAtIndex:0];
self.editView = theEditView;
[self.view addSubview:theEditView];

次に、別のボタンを押して (編集モードを終了します):

[editView removeFromSuperview];

元の Bnib に戻りました。

これは正常に動作しますが、私の EditMode.nib には最上位の obj、UIView obj が 1 つしかないことに注意してください。この nib の File's Owner が BViewController またはデフォルトの NSObject として設定されているかどうかは問題ではありませんが、File's Owner の View Outlet が何も設定されていないことを確認してください。そうである場合、exc_bad_access クラッシュが発生し、xcode は 6677 のスタック フレームをロードし、内部の UIView メソッドが繰り返し呼び出されていることを示します...したがって、無限ループのように見えます。(ただし、View Outlet は元の Bnib に設定されています)

お役に立てれば。

于 2010-04-21T13:14:40.570 に答える
4

Aaron Hillegass (著者、インストラクター、Cocoa ninja) によるこのブログ投稿は非常に啓発的であることがわかりました。指定されたイニシャライザを介して NIB ファイルをロードするという彼の修正されたアプローチを採用しなくても、少なくとも進行中のプロセスをよりよく理解できるでしょう。私は最近この方法を使って大成功を収めています!

于 2010-03-25T19:33:26.173 に答える
3

私には同じこと (プログラムで XIB ファイルからビューをロードする) を行う理由がありましたが、これを a のサブクラスのサブクラスのコンテキストから完全に行う必要がありましたUIView(つまり、ビュー コントローラーを一切関与させずに)。これを行うために、次のユーティリティ メソッドを作成しました。

+ (id) initWithNibName:(NSString *)nibName withSelf:(id)myself {

    NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:nibName
                                                    owner:myself options:nil];
    for (id object in bundle) {
        if ([object isKindOfClass:[myself class]]) {
            return object;
        }
    }  

    return nil;
} 

次に、サブクラスのinitWithFrameメソッドから次のように呼び出します。

- (id)initWithFrame:(CGRect)frame {

    self = [Utilities initWithNibName:@"XIB1" withSelf:self];
    if (self) {
        // Initialization code.
    }
    return self;
}

一般的な関心のために投稿されました。このようにしないと問題が発生する場合は、お知らせください。

于 2011-10-25T19:33:46.953 に答える
3

これを Swift で行う方法を次に示します (現在、XCode 7 ベータ 5 で Swift 2.0 を作成しています)。

Interface Builder で「カスタム クラス」として設定したサブクラスから、UIView次のようなメソッドを作成します (私のサブクラスは RecordingFooterView と呼ばれます)。

class func loadFromNib() -> RecordingFooterView? {
    let nib = UINib(nibName: "RecordingFooterView", bundle: nil)
    let nibObjects = nib.instantiateWithOwner(nil, options: nil)
    if nibObjects.count > 0 {
        let topObject = nibObjects[0]
        return topObject as? RecordingFooterView
    }
    return nil
}

次に、次のように呼び出すことができます。

let recordingFooterView = RecordingFooterView.loadFromNib()

于 2015-08-22T12:37:58.053 に答える
2

この質問の根源であるスタンドアロンの XIB を作成する方法を説明する回答はありません。Xcode 4「新しい XIB ファイルを作成する」オプションはありません。

これをする

1) Choose "New File..."
2) Choose the "User Interface" category under the iOS section
3) Choose the "View" item
4) You will then be prompted to choose an iPhone or iPad format

これは簡単に思えるかもしれませんが、「XIB」という単語がどこにも表示されないため、数分で検索できるようになります。

于 2011-04-26T20:06:56.097 に答える
2

@AVeryDev

6)ロードされたビューをビュー コントローラーのビューにアタッチするには:

[self.view addSubview:myViewFromNib];

おそらく、メモリリークを避けるためにビューから削除する必要があります。

明確にするために、View ControllerにはいくつかのIBOutletがあり、そのうちのいくつかは元のnibファイルのアイテムに接続され(通常どおり)、一部はロードされたnibのアイテムに接続されます。どちらのペン先も同じオーナー クラスです。ロードされたビューは元のビューをオーバーレイします。

ヒント: ロードされた nib のメイン ビューの不透明度をゼロに設定すると、元の nib のアイテムが隠れなくなります。

于 2010-11-25T07:13:48.580 に答える
1

何時間も費やした後、次の解決策を打ち出しました。カスタム を作成するには、次の手順に従いますUIView

1) UIViewから継承したクラスmyCustomViewを作成します。
ここに画像の説明を入力

2) myCustomViewという名前で.xibを作成します。
ここに画像の説明を入力

3) .xib ファイル内のUIViewのクラスを変更し、そこにmyCustomViewクラスを割り当てます。
ここに画像の説明を入力

4) IBOutlets を作成する
ここに画像の説明を入力

5) myCustomView * customViewに .xib をロードします。次のサンプル コードを使用します。

myCustomView * myView = [[[NSBundle mainBundle] loadNibNamed:@"myCustomView" owner:self options:nil] objectAtIndex:0];
[myView.description setText:@"description"];

注: まだ問題が発生している場合は、コメントしてください。サンプル プロジェクトとmyCustomViewのリンクを提供します。

于 2016-06-18T07:44:31.757 に答える
0

ビューと同じように、ビューを含むxibに名前を付ける規則があります。ビューコントローラーの場合と同じです。そうすれば、クラス名をコードに書き出す必要がなくなります。同じ名前の nib ファイルから UIView をロードします。

MyView というクラスの例。

  • Interface Builder で MyView.xib という nib ファイルを作成します。
  • Interface Builder で、UIView を追加します。そのクラスを MyView に設定します。心ゆくまでカスタマイズし、MyView のインスタンス変数を、後でアクセスする可能性のあるサブビューに関連付けます。
  • コードで、次のように新しい MyView を作成します。

    MyView *myView = [MyView nib_viewFromNibWithOwner:所有者];

このカテゴリは次のとおりです。

@implementation UIView (nib)

+ (id) nib_viewFromNib {
    return [self nib_viewFromNibWithOwner:nil];
}

+ (id) nib_viewFromNibWithOwner:(id)owner {
    NSString *className = NSStringFromClass([self class]);
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:className owner:owner options:nil];
    UIView *view = nil;
    for(UIView *v in nib) {
        if ([v isKindOfClass:[self class]]) {
            view = v;
            break;
        }
    }
    assert(view != nil && "View for class not found in nib file");
    [view nib_viewDidLoad];
    return view;
}

// override this to do custom setup
-(void)nib_viewDidLoad {

}

次に、使用しているコントローラーのアクションでボタンを接続し、カスタム ビュー サブクラスのアウトレットを使用してラベルに設定します。

于 2013-12-09T04:27:07.210 に答える
0

Swift 4 で nib/xib からプログラムでビューをロードするには:

// Load a view from a Nib given a placeholder view subclass
//      Placeholder is an instance of the view to load.  Placeholder is discarded.
//      If no name is provided, the Nib name is the same as the subclass type name
//
public func loadViewFromNib<T>(placeholder placeholderView: T, name givenNibName: String? = nil) -> T {

    let nib = loadNib(givenNibName, placeholder: placeholderView)
    return instantiateView(fromNib: nib, placeholder: placeholderView)
}

// Step 1: Returns a Nib
//
public func loadNib<T>(_ givenNibName: String? = nil, placeholder placeholderView: T) -> UINib {
    //1. Load and unarchive nib file
    let nibName = givenNibName ?? String(describing: type(of: placeholderView))

    let nib = UINib(nibName: nibName, bundle: Bundle.main)
    return nib
}

// Step 2: Instantiate a view given a nib
//
public func instantiateView<T>(fromNib nib: UINib, placeholder placeholderView: T) -> T {
    //1. Get top level objects
    let topLevelObjects = nib.instantiate(withOwner: placeholderView, options: nil)

    //2. Have at least one top level object
    guard let firstObject = topLevelObjects.first else {
        fatalError("\(#function): no top level objects in nib")
    }

    //3. Return instantiated view, placeholderView is not used
    let instantiatedView = firstObject as! T
    return instantiatedView
}
于 2018-01-05T08:04:49.283 に答える
-1

私はこれのためにUIViewにカテゴリを追加することになりました:

 #import "UIViewNibLoading.h"

 @implementation UIView (UIViewNibLoading)

 + (id) loadNibNamed:(NSString *) nibName {
    return [UIView loadNibNamed:nibName fromBundle:[NSBundle mainBundle] retainingObjectWithTag:1];
 }

 + (id) loadNibNamed:(NSString *) nibName fromBundle:(NSBundle *) bundle retainingObjectWithTag:(NSUInteger) tag {
    NSArray * nib = [bundle loadNibNamed:nibName owner:nil options:nil];
    if(!nib) return nil;
    UIView * target = nil;
    for(UIView * view in nib) {
        if(view.tag == tag) {
            target = [view retain];
            break;
        }
    }
    if(target && [target respondsToSelector:@selector(viewDidLoad)]) {
        [target performSelector:@selector(viewDidLoad)];
    }
    return [target autorelease];
 }

 @end

ここでの説明:viewcontrollerはios&macでのビューの読み込みが少ない

于 2013-03-19T06:21:11.657 に答える