我正在尝试为UIView定制初始化程序的最佳方法,以便可以将值传递给初始化程序,并立即将其存储为UIView子类中的iVar,因为此值是绘图所需的drawRect
。
目前我正在使用默认的initWithFrame
,然后创建此UIView的类会在调用initWithFrame
后将其iVar设置为值,并且它实际上正在工作;不知何故,drawRect
获得此iVar的值,即使在初始化之后设置了。
所以我需要两件事之一:
1)有信心知道这是可以的:我可以依赖drawRect
以某种方式延迟绘图,以便在初始化UIView之后由另一个对象设置iVars。在这种情况下,只有在UIView初始化时才会调用drawRect
吗?
或者,
2)我需要在初始化期间传递值:这是创建自定义初始化程序的最佳方法,该初始化程序需要(CGRect)frame
作为initWithFrame.
的参数,这可能就像这样简单:
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
之前值已存在。
答案 0 :(得分:4)
1。)您可以依赖drawRect:
来init
之后调用drawRect:
。实际上,在完成视图绘制和合成时将调用super initWithFrame:
,这通常是由于核心动画提交而发生的(如果修改任何CALayer或UIView,则在runloop结束时完成(总是如此)由CALayer支持))。
2。)从架构的角度来看,这种方法更好。如果你认为这个变量是你的类功能的一个组成部分(并且没有它,类就无法正常工作),它绝对应该是一个init参数。您也可以考虑在其他init-Methods中抛出NSInternalInconsistencyException(或任何其他异常)和/或将它们标记为已弃用(使用{{1}}调用时,超类的init-Methods仍然可以正常工作。)
答案 1 :(得分:2)
当您使用指定的指定初始化程序以编程方式显式创建视图时,第二种方法是理想的。警告:如果视图是通过NIB构建的,那么不是就是这种情况。
答案 2 :(得分:1)
简短的回答:你的两种方法都可以正常工作。
更长的答案:
在runloop中调用drawRect:
方法,因此在完成所有初始化然后放弃控制回到runloop之前不会调用。当然,如果你初始化视图,然后立即设置属性,你就不会有问题。
你的第二种方法应该可以正常工作。
我会使用第二种方法。
答案 3 :(得分:1)
Martin Ullrich 正确地解决了这个问题。 但我想补充一点。
如果您在视图上致电initWithFrame
或init
。这不会调用drawRect
方法。
将该视图添加到窗口时,以及in the next runLoop it will call this method
,它会生成一个在屏幕上显示的位图。