iOS的loadNibNamed混乱,什么是最好的做法?(iOS loadNibNamed conf

2019-07-04 01:49发布

我所熟悉的大多数创造我自己的UIView子类的厦门国际银行的过程中,但不是一切都为我工作正常 - 它主要与IBOutlets连接起来做。 我可以让他们在什么似乎是一种迂回的方式工作。

我的设置是这样的:

  • 我有MyClass.h和MyClass.m。 他们有一个UIView(称为视图)和一个UILabel(称为myLabel)IBOutlets。 我添加了“查看”属性,因为一些在线的例子似乎表明,你需要这个,它实际上解决了我在那里得到一个崩溃,因为它找不到视图属性的问题,我想甚至在UIView的父类。
  • 我有一个名为MyClass.xib一个XIB文件,其文件的所有者自定义类是MyClass的,这对于该类存在我的.h和.M之后正确预填。

我的init()方法是在那里我遇到的问题。

我试图用一个NSBundle mainBundle的“loadNibNamed”的方法,并设置所有者“自我”,希望我会创建视图的一个实例,它会自动获取其网点匹配班里的人(我知道如何做到这一点,我很小心的话)。 那么我想我要在笔尖,使“自我”等于子视图索引0,而不是做

self = [super init];

或类似的东西。

我感觉到,我做的事情错在这里,但在线的例子有过类似的事情在init方法回事,但他们是子视图0分配给视图属性,并将其添加为一个孩子 - 但不是那么总的2个MyClass的实例? 一个基本上切断了与IBOutlets,含有通过loadNibNamed实例孩子MyClass的? 或者最好,是不是包含所有我本来想为MyClass的直接儿童IBOutlets一个额外的中介UIView的一个MyClass的实例? 这造成了轻微的烦恼,当谈到做这样的事情instanceOfMyClass.frame.size.width,因为它返回0,当一个已经推出了孩子的UIView返回真正的帧大小我一直在寻找。

是事我做错了,我要和loadNibNamed搞乱的init方法里面? 我应该做的事情更是这样?

MyClass *instance = [[MyClass alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:instance options:nil];  

还是这样吗?

MyClass *instance = [[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:nil options:nil] objectAtIndex:0]; 

感谢您事先的任何assitance。

Answer 1:

第二个选项是正确的。 最抗跌的代码,你可以做的是这样的:

+ (id)loadNibNamed:(NSString *)nibName ofClass:(Class)objClass {
    if (nibName && objClass) {
        NSArray *objects = [[NSBundle mainBundle] loadNibNamed:nibName 
                                                         owner:nil 
                                                       options:nil];            
        for (id currentObject in objects ){
            if ([currentObject isKindOfClass:objClass])
                return currentObject;
        }
    }

    return nil;
}

并调用是这样的:

MyClass *myClassInstance = [Utility loadNibNamed:@"the_nib_name" 
                                         ofClass:[MyClass class]]; 
// In my case, the code is in a Utility class, you should 
// put it wherever it fits best

我假设你的MyClass的是子类UIView ? 如果是这样的话,那么你需要确保UIView你的.xib实际上是MyClass的类。 这是指对在界面生成器右侧部分的第三个选项卡中,选择视图后



Answer 2:

所有你需要做的是通过创建子视图loadNibNamed ,设置框架,并把它添加到子视图。 例如,我将用我的三个子视图MyView类,它是一个UIView子类,其接口的NIB,定义MyView.xib

所以,我定义initWithFrameUIView子类:

- (id)initWithFrame:(CGRect)frame
{
    NSLog(@"%s", __FUNCTION__);

    self = [super initWithFrame:frame];
    if (self)
    {
        NSArray *nibContents = 
          [[NSBundle mainBundle] loadNibNamed:@"MyView" 
                                        owner:self 
                                      options:nil];
        [self addSubview:nibContents[0]];
    }
    return self;
}

因此,举例来说,在我UIViewController ,我可以加载了几个子类,这些的UIView ,像这样的对象:

for (NSInteger i = 0; i < 3; i++)
{
    CGRect frame = CGRectMake(0.0, i * 100.0 + 75.0, 320.0, 100.0);
    MyView *myView = [[MyView alloc] initWithFrame:frame];
    [self.view addSubview:myView];

    // if you want, do something with it: 
    // Here I'm initializing a text field and label

    myView.textField.text = [NSString stringWithFormat:@"MyView textfield #%d",
                              i + 1];
    myView.label.text = [NSString stringWithFormat:@"MyView label #%d", 
                          i + 1];
}

我本来建议使用控制器,我会继续低于答案作为历史参考。


原来的答案:

我看不出有任何引用到这里查看控制器。 通常你想有一个子类UIViewController ,你会再与实例

MyClassViewController *controller = 
  [[MyClassViewController alloc] initWithNibName:@"MyClass" 
                                          bundle:nil];

// then you can do stuff like
//
// [self presentViewController:controller animated:YES completion:nil];

笔尖文件, MyClass.xib ,可以指定的基类的UIView ,如果你想要,你拥有所有的视图相关的代码(例如,假设MyClass的是类的子类UIView )。



Answer 3:

这里有一个方法,我使用:

  1. 创建一个子类UIView ,将其称为MyClass
  2. 创建一个视图厦门国际银行文件。 打开界面生成器中,单击文件拥有者和身份检查,类更改为你的父视图控制器,例如ParentViewController
  3. 点击查看已在对象列表和身份检查改变它的类MyClass
  4. 您在声明任何网点/行动MyClass将通过单击并拖动从View连接(不是文件的所有者)。 如果你想从他们连接到变量ParentViewController然后单击并拖动从文件的所有者。
  5. 现在,在您的ParentViewController你需要声明一个实例变量MyClass

ParentViewController.h添加以下内容:

@class MyClass

@interface ParentViewController : UIViewController {
    MyClass *myClass;
}

@property (strong, nonatomic) MyClass *myClass;

在您的实现综合这和您的加入下面viewDidLoad方法:

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:self options:nil];
    self.myClass.frame = CGRectMake(X,Y,W,H); //put your values in.
    [self.view addSubview:self.myClass];
}


文章来源: iOS loadNibNamed confusion, what is best practice?