为 UIView 子类加载 Nib 的正确方法 [英] Correct way to load a Nib for a UIView subclass

查看:19
本文介绍了为 UIView 子类加载 Nib 的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道以前有人问过这个问题,但答案是矛盾的,我很困惑,所以请不要喷我.

I am aware this question has been asked before but the answers are contradicting and I am confused, so please don't flame me.

我希望在整个应用程序中都有一个可重用的 UIView 子类.我想用一个nib文件来描述界面.

I want to have a reusable UIView subclass throughout my app. I want to describe the interface using a nib file.

现在假设它是一个加载指示器视图,其中包含一个活动指示器.我想在某个事件中实例化这个视图并动画到视图控制器的视图中.我可以以编程方式描述视图的界面,以编程方式创建元素并在 init 方法中设置它们的框架等.

Now let's say it's a loading indicator view with an activity indicator in it. I would like on some event to instantiate this view and animate in to a view controller's view. I could describe the view's interface no problem programmatically, creating the elements programmatically and setting their frame inside an init method etc.

我怎么能用笔尖做到这一点?保持界面生成器中给定的大小,而无需设置框架.

How can I do this using a nib though? Maintaining the size given in interface builder without having to set a frame.

我已经设法这样做了,但我确定这是错误的(它只是一个带有选择器的视图):

I've managed to do it like this, but I'm sure it is wrong (it's just a view with a picker in it):

 - (id)initWithDataSource:(NSDictionary *)dataSource {
        self = [super init];
        if (self){
            self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
            self.pickerViewData = dataSource;
            [self configurePickerView];
        }
        return self;
    }

但是我覆盖了 self,当我实例化它时:

But I'm overwriting self, and when I instantiate it:

FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
    selectView.delegate = self;

    selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);

我必须手动设置框架,而不是从 IB 获取它.

I have to manually set the frame rather than have it picked up from IB.

我想在视图控制器中创建这个自定义视图,并有权控制视图的元素.我不想要一个新的视图控制器.

I want to create this custom view in a view controller, and have access to control the view's elements. I don't want a new view controller.

谢谢

我不知道这是否是最佳实践,我确定不是,但我是这样做的:

FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
    selectView.delegate = self;
    [selectView configurePickerViewWithData:ds];
    selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
    selectView.alpha = 0.9;
    [self.view addSubview:selectView];
    [UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
                            selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
                            selectView.alpha = 1;
                        } completion:^(BOOL finished) {
                        }];

仍然需要正确的做法

这是否应该使用视图控制器和带有 nib 名称的 init 来完成?我应该在代码中的某些 UIView 初始化方法中设置笔尖吗?还是我做的没问题?

Should this have been done using a view controller and init with nib name? Should I have set the nib in some UIView initialisation method in the code? Or is what I have done ok?

推荐答案

MyViewClass *myViewObject = [[[NSBundle mainBundle] loadNibNamed:@"MyViewClassNib" owner:self options:nil] objectAtIndex:0]

我正在使用它来初始化我拥有的可重用自定义视图.

I'm using this to initialise the reusable custom views I have.

请注意,您可以在末尾使用 "firstObject",这样更简洁一些."firstObject" 是 NSArray 和 NSMutableArray 的一个方便的方法.

Note that you can use "firstObject" at the end there, it's a little cleaner. "firstObject" is a handy method for NSArray and NSMutableArray.

这是一个典型的例子,加载一个 xib 用作表头.在你的文件 YourClass.m

Here's a typical example, of loading a xib to use as a table header. In your file YourClass.m

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return [[NSBundle mainBundle] loadNibNamed:@"TopArea" owner:self options:nil].firstObject;
}

通常,在TopArea.xib 中,您会单击文件所有者并将文件所有者设置为YourClass.然后实际上 在 YourClass.h 中,您将拥有 IBOutlet 属性.在 TopArea.xib 中,您可以将控件拖动到这些出口.

Normally, in the TopArea.xib, you would click on File Owner and set the file owner to YourClass. Then actually in YourClass.h you would have IBOutlet properties. In TopArea.xib, you can drag controls to those outlets.

不要忘记在 TopArea.xib 中,您可能必须点击视图本身并将其拖到某个出口,这样您就可以控制它,如有必要.(一个非常有价值的提示是,当您对表格单元格行执行此操作时,您绝对必须这样做 - 您必须将视图本身连接到代码中的相关属性.)

Don't forget that in TopArea.xib, you may have to click on the View itself and drag that to some outlet, so you have control of it, if necessary. (A very worthwhile tip is that when you are doing this for table cell rows, you absolutely have to do that - you have to connect the view itself to the relevant property in your code.)

这篇关于为 UIView 子类加载 Nib 的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆