是否可以创建一个在Xcode中呈现的UIView
子类(通过添加IB_DESIGNABLE
属性,如解释here)但是没有自定义{{1方法?
我们有一个自定义drawRect:
子类,它使用一些UIView
来添加到CAShapeLayer
进行绘制(因此,无需覆盖self.layer
)。这个类在App上工作正常,但不能在Xcode上呈现。
如果我们复制drawRect:
中的代码,那么它可以正常工作,但我们更愿意让图纸自动发生在图层上。
可以这样做吗?
我也尝试过做
drawRect:
似乎可以在设备上运行,但不适用于Xcode的IB。
答案 0 :(得分:4)
即使UIView
未被覆盖,您也可以预览IB中的IB_DESIGNABLE
子类(使用drawRect:
宏)。
我在XCode 6.1中添加了您的code,并在OEProgressIndicator
文件中添加了xib
。然后我通过在Editor
选择器中设置断点来调试它(使用菜单Debug Selected View
/ commonProgressIndicatorInit
)。
以下是您在预览中看不到当前代码的原因:调用commonProgressIndicatorInit
时(来自initWithFrame:(CGRect)frame
构造函数), frame
等于CGRectZero
(x:0 y:0 width:0 height:0
),因此您的中心变量实际上等于(0, 0)
,而半径为-1
。
在设备上,根据类的使用方式,可以使用正确的框架直接调用,这就是它可以在设备上工作而不在IB中工作的原因。
要解决此问题,我会实施layoutSubviews
选择器(从UIView
覆盖它)以正确组织子图层。当frame
将从CGRectZero
更改为Interface Builder中设置的正确值时,将调用此选择器。
答案 1 :(得分:2)
我一直在使用- (void)prepareForInterfaceBuilder
方法告诉IB实时渲染视图。
见这里:Creating a Live View of a Custom Object
另外,你们是对的,这个功能也适用于Objective-C。
您不一定需要使用drawRect
,您可以尝试使用- (void)layoutSubviews
,它似乎有效。将代码留在像- (void)layoutSubviews
这样的地方仅仅是为了实时渲染的问题在于它可能性能较差等等(例如,你可以在- (void)awakeFromNib
中做很多事情,但是这种方法可以不能通过实时渲染调用,所以只需确保在- (void)prepareForInterfaceBuilder
中完成所有设置。
答案 2 :(得分:0)
在没有看到所有代码的情况下,很难看出问题的根源是什么,但回答你的问题,是的,你可以使用IBInspectable / IBDesignable而无需实现任何其他特定方法。我已经为一个使用多个图层并且不进行任何绘图的视图(使用嵌套层)做了这个。
有关带圆角的快速测试示例代码段:
@IBDesignable
class MyView : UIView {
@IBInspectable var cornerRadius:CGFloat {
get { return self.layer.cornerRadius }
set { self.layer.cornerRadius = newValue }
}
@IBInspectable var borderWidth:CGFloat {
get { return self.layer.borderWidth }
set { self.layer.borderWidth = newValue }
}
@IBInspectable var borderColor:UIColor {
get { return UIColor(CGColor: self.layer.borderColor) }
set { self.layer.borderColor = newValue.CGColor }
}
}
有关渐变的简单示例,请参阅this post。
有关如何调试实时视图的说明,请参阅大约22分钟的WWDC§411。
到目前为止,我看到的唯一限制是您可以在类扩展中添加可检查的属性,但它们只能在设备上正确呈现。