4

我正在尝试确定为 UIView 自定义初始化程序的最佳方法,以便可以将一个值传递给初始化程序,并立即将其作为 iVar 存储在 UIView 子类中,因为在drawRect.

目前我正在使用默认值,创建此 UIView 的类调用initWithFrame后将其 iVar 设置为一个值,它实际上正在工作;不知何故,即使在 UIView 初始化后设置了这个 iVar 的值。initWithFramedrawRect

所以我需要两件事之一:

1)有信心知道这一点是可以的:我可以依靠drawRect某种方式延迟绘图,以便在 UIView 初始化后由另一个对象设置 iVar。在这种情况下,只是在 UIView 初始化时才drawRect被调用?

或者,

2)我需要在初始化期间传递值:这是创建自定义初始化程序的最佳方式(CGRect)frameinitWithFrame.

 myNewView=[[MyCustomView alloc] initWithFrame:myRect andMore:myValue];

然后在 MyCustomView.m 中:

 - (id)initWithFrame:(CGRect)frame andMore:(int)someValue
  {
     self = [super initWithFrame:frame];
     if (self) {
       myIvar=someValue;
       ... //continue as normal
     }
  }

这段代码会是一个好方法吗?然后我会很舒服地知道该值在drawRect被调用之前就在那里。

4

4 回答 4

4

1.) 你可以依赖在drawRect:any 之后被调用init。事实上,drawRect:当视图绘制和合成完成时会被调用,这通常是作为核心动画提交的结果发生的(如果你修改任何 CALayer 或 UIView(它们总是由 CALayer 支持),则在运行循环结束时完成) )。

2.) 从架构的角度来看,这种方法更好。如果你认为这个变量是你的类功能的一个组成部分(没有它类就不能正常工作),它绝对应该是一个 init 参数。您还可以考虑在其他 init-Methods 中抛出 NSInternalInconsistencyException(或任何其他异常)和/或将它们标记为已弃用(使用 调用时,超类的 init-Methods 仍然可以正常工作super initWithFrame:)。

于 2012-04-11T08:41:03.627 回答
2

当您使用您指定的指定初始化程序以编程方式显式创建视图时,第二种方法是理想的。警告:如果视图是通过 NIB 构建的,则情况并非如此。

于 2012-04-11T07:41:32.810 回答
1

简短的回答:您的两种方法都应该可以正常工作。

更长的答案:

  1. drawRect:方法在运行循环中调用,因此在您完成所有初始化然后将控制权交还给运行循环之前不会被调用。当然,如果您初始化视图然后立即设置属性,您将不会有问题。

  2. 您的第二种方法应该几乎可以正常工作。

我会使用第二种方法。

于 2012-04-11T07:37:44.407 回答
1

Martin Ullrich恰当地解决了这个问题。但我想补充一点。

如果您调用initWithFrameinit在您的视图中。这不会drawRect调用方法。
当您将该视图添加到窗口时,in the next runLoop it will call this method会生成一个位图以显示在屏幕上。

于 2014-06-03T14:24:45.947 回答