2013-07-06 56 views
1

通常,我通过重写drawRect来创建自定义UIViews。是否有可能创建一个自定义UIView有一个与它相关的笔尖? (不问有关从笔尖创建自定义UIView)。或者,这通常是在第一个包含第二个视图控制器的情况下完成的?用NIB创建自定义UIView

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

THX

编辑#1 我想有一个与它等按钮相关的自定义操作....这是唯一的功能,能够在VC或能自定义视图的工作?

+0

您是否创建自定义UIView并将其与nib关联(假设您可以这样做)或从nib载入自定义UIView有什么区别? –

+0

像在检查器中设置自定义类,然后做loadNibNamed?老实说,我的iOS编程很少。这是人们做这件事的标准方式吗?我有点不同的技术迷路了。 – timpone

+0

是的,这是一种常见的做法。 –

回答

1

它实现正是你所追求的是很难。使用nib是加载视图的一种方法,另一种是以编程方式创建它们。

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

  1. 是的,这是可能的笔尖与通过身份检查在IB的自定义视图关联。但是,这也是“从笔尖创建自定义UIView”。这不是你在找什么?
  2. 您不必使用视图控制器遏制来从nib加载视图。
  3. 能够呼叫initWithFrame:根本不是使用笔尖的一部分,因为笔尖需要使用NSCoder并从磁盘充气。应该使用-initWithCoder:
  4. 是的,你绝对可以在自己的子视图(UIButtons等)的笔尖响应事件的自定义意见。正常情况下,您会将IBActions连接到自定义视图子类。这不仅仅是视图控制器的一部分,但根据MVC,这可能会打破“规则”。

从笔尖加载自定义视图是海峡前进。

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

@property (strong, nonatomic) BBCustomView *customView; 

然后初始化它:

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

此时initWithCoder将被叫自定义视图。然后,您可以将该自定义视图正常添加到现有的视图层次结构中。

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

希望这可以清理一些东西!

+0

thx回答,这将引发其他问题,但一个良好的起点 – timpone

1

是的,你可以做到这一点,但要留意nib文件存储在磁盘而不是RAM中,因此它比不使用nib慢约10,000倍。如果你创造了很多观点,不要这样做。

基本上你的init方法加载nib文件,在nib中抓取视图(它应该被定义为同一个类),而不像大多数init方法那样返回自我,它返回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 
} 
+0

那么如何将笔尖与自定义视图相关联?我是否需要在UIView的子类中执行loadNibNamed,或者是在想要实例化这个自定义视图的控制器中调用? – timpone

+0

我会在UIView的子类中执行它。一切都应该在init方法内。 –

+0

@timpone我编辑我的答案,包括示例代码。 –