使用InterfaceBuilder配置自定义UIView

Wal*_*ldo 5 objective-c interface-builder xib uiview

很多人都提出了类似的问题,但是回答要么只是模糊不清,要么不是我需要去的方向,所以我会尝试尽可能具体地问这个问题.此问题的上下文适用于使用XCode 4进行iOS开发.

我有一个应用程序,我多次使用相同的Widget.在这个简单的练习中,小部件将是一个固定大小的红色框,顶部有一个标签,根视图控制器将改变,但你可以想象它有很多ImageViews和ScrollViews,看起来很漂亮.最后一点是关键,因为非编码艺术设计师希望能够全局调整此视图,而无需在UI的每个重复部分上反复执行相同的操作.

在应用程序中,我已经用单个UIView替换了用于组成窗口小部件的ImageViews和ScrollViews,并使用InterfaceBuilder将自定义类设置为Widget.我在根视图控制器中有这些Widget对象正确连接的插座.Widget类是UIView的子类,代码如下:

@interface Widget : UIView {
    UILabel     *label;
}

@property (nonatomic, retain) IBOutlet  UILabel *label;
@property (nonatomic, copy) NSString *labelName;
@end


@implementation Widget
@synthesize label, labelName;

- (id)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super initWithCoder:aDecoder])) { 
        // This is the code that I want to disappear    
        CGRect pos = CGRectMake(5, 5, 90, 30);
        label = [[UILabel alloc] initWithFrame:pos];
        [self addSubview:label];
        self.backgroundColor = [UIColor redColor];
    }
    return self;
}

- (NSString *)labelName {
    return label.text;
}

// This live updates the label in this custom view
- (void)setLabelName:(NSString *)name {
    label.text = name;
}

- (void)dealloc {
    [super dealloc];
}
@end
Run Code Online (Sandbox Code Playgroud)

代码工作得很好,我可以从主视图控制器实时更新自定义视图中的文本.但是,initWithCoder中的四行代码是问题所在.还记得设计师吗?我有他们的地步,他们可以工作的魔术与界面生成器,但我不能为我的生活弄清楚如何获得的UIView把自己从他们设计了一个笔尖加载.要手动尝试和不断复制单个项目的定位和属性并不十分令人兴奋,非常耗时的(是的,我知道我会被现在已经完成了,如果我没有写这个帖子).

非常简单,我如何获取任意.xib文件并让它完成我在initWithCoder中手工处理的工作?我认为在那个时候为UILabel连接IBOutlet是微不足道的,但如果我过于乐观,请对此发表评论.

作为第二个问题,一旦在真实用户界面上启动并运行,我就会把UIScrollViews等东西连接起来.Widget是否成为UIScrollViewDelegate或此代码停在何处.根视图控制器应该忽略这一点,但将传统上放在View Controller中的代码放入UIView对象中感觉不合适.

Vla*_*vic 0

是的,您应该将 与标签挂钩IBOutlet,然后设计人员可以从 Interface Builder 中定位标签。

关于UIScrollViewDelegate,您还应该为滚动视图设置IBOutlet,然后在控制器内部执行widgetView.scrollView.delegate = self,将当前控制器设置为滚动视图的委托。

作为替代方案,您可以使Widget视图成为滚动视图的委托,但在我看来,这样做会破坏 MVC 合规性(处理滚动视图事件的代码是控制器代码)。