使用NIB创建自定义UIView

时间:2013-07-06 23:38:11

标签: ios

通常,我会通过覆盖drawRect来创建自定义UIViews。是否可以创建一个与其关联的笔尖的自定义UIView? (不要求从笔尖创建自定义UIView)。或者这通常是由第二个视图控制器完成的,它包含在第一个?

我仍然希望能够调用initWithFrame来实例化它。

THX

编辑#1 我想要有与其上的按钮相关的自定义操作等....这个功能只能在VC中使用,还是自定义视图可以工作?

2 个答案:

答案 0 :(得分:1)

是的,你可以这样做,但要注意nib文件存储在磁盘而不是RAM中,因此它比不使用nib慢~10,000倍。如果您要创建大量视图,请不要这样做。

基本上你的init方法加载nib文件,抓取nib中的视图(应该定义为同一个类),而不是像大多数init方法一样返回self,它返回nib中的视图。

如果您查找语言文档,您会发现init方法返回与“self”不同的对象是很常见的。

如果您不使用ARC,则必须释放self并保留您要返回的视图。

以下是我将如何实现它(nib文件必须与类名匹配):

- (instancetype)initWithFrame:(CGRect)frame
{
  if (!(self = [super initWithFrame:frame]))
    return nil;

  NSArray *loadedObjects = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:@{}];
  id newView = nil;
  for (id loadedObject in loadedObjects) {
    if ([loadedObject isMemberOfClass:[self class]]) {
      newView = loadedObject;
      break;
    }
  }

  // if ARC is disabled, you must do this:
  // [self release];
  // [newView retain];

  self = newView;

  self.frame = frame;

  return self
}

答案 1 :(得分:1)

很难完全达到你想要的目标。使用nib是加载视图的一种方法,另一种是以编程方式创建它们。

所以,试着回答你的问题:

  1. 是的,可以通过IB中的 Identity Inspector 将笔尖与自定义视图相关联。但是,这也是“从笔尖创建自定义UIView”。这不是你想要的吗?
  2. 您不必使用视图控制器包含来从nib加载视图。
  3. 能够调用initWithFrame:根本不是使用nib的一部分,因为nib需要使用NSCoder并从磁盘中膨胀。应该使用-initWithCoder:
  4. 是的,您绝对可以在笔尖中使用自定义视图来响应子视图中的事件(UIButtons等)。您可以照常将IBActions连接到自定义视图子类。这不仅仅是视图控制器的一部分,尽管根据MVC,这可能会破坏“规则”。
  5. 从笔尖加载自定义视图是前进的。

    为自定义视图创建一个强大的属性(在视图控制器中是一个好地方)

    @property (strong, nonatomic) BBCustomView *customView;
    

    然后实例化它:

    self.customView = [[[NSBundle mainBundle] loadNibNamed:@"View" owner:nil options:nil] lastObject];
    

    此时将在自定义视图上调用initWithCoder。然后,您可以照常将该自定义视图添加到现有视图层次结构中。

    不要忘记在nib文件中为自定义视图设置正确的类。

    希望能稍微清理一下!