直播Xcode的接口生成器UIView子类(IB_DESIGNABLE)无的drawRect:

问题描述:

是否有可能创建一个UIView子类,在Xcode使得现场(通过增加IB_DESIGNABLE属性作为解释here),但不具有自定义drawRect:方法?直播Xcode的接口生成器UIView子类(IB_DESIGNABLE)无的drawRect:

我们有一个使用一些CAShapeLayer S的被添加到self.layer绘制自定义UIView子类(因此,没有必要重写drawRect:)。这个类在App上工作正常,但不会在Xcode上呈现。

如果我们复制drawRect:中的代码,它可以工作,但我们希望让图形在图层上自动发生。

可以这样做吗?


我也想这样做

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextMoveToPoint(currentContext, self.myLayer1.frame.origin.x, self.myLayer1.frame.origin.y); 
    [self.myLayer1 renderInContext:currentContext]; 
    CGContextMoveToPoint(currentContext, self.myLayer1.frame.origin.x, self.myLayer1.frame.origin.y); 
    [self.myLayer2 renderInContext:currentContext];  
} 

这似乎在设备上而不是在Xcode的IB工作。

+0

确保初始化(即设置'CAShapeLayers')代码也从'initWithFrame:'调用。 IB呼吁进行预览。 – rintaro 2014-09-25 15:28:06

+0

是的,我也从那里打电话给它。没有运气。你怎么知道IB使用'initWithFrame:'?在IB预览时有没有调试视图的代码? – 2014-09-25 15:34:44

+1

'Editor'>'从Xcode菜单中调试选定的视图。 – rintaro 2014-09-25 15:40:30

没有看到你所有的代码,很难看到问题的根源,但回答你的问题,是的,你可以使用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

有关如何调试实时视图的说明,请参阅WWDC§411约22分钟标记。

我目前看到的唯一限制是您可以在类扩展中添加可检查的属性,但它们只能在设备上正确呈现。

+0

感谢您的回答,但是[本课程](https://gist.github.com/rsanchezsaez/ac620ce58bd6097207d8)我们做了如果你设法使它在Xcode 6上显示,请告诉我怎么做,看看我们尝试过的两个'drawRect'解决方案实现,但是没有用, – 2014-10-08 09:47:34

+0

这是一个Swift唯一的特性 - 据我所知。以我发布的链接作为基线,并从那里分支 – 2014-10-09 16:10:49

+0

'IB_DESIGNABLE'自定义视图不是Swift唯一的功能。[docs](https://developer.apple.com/library/ios/recipes/xcode_help -IB_objects_media/chapters/CreatingaLiveViewofaCustomObject.html)清楚地表明它可以与Objective-C一起工作,如果只是,这不适用于自定义子CALayers的事实是* Objective-C only * bug。 ](http://bugreport.apple.com)给Apple。 – 2014-10-09 16:34:29

我一直在使用方法- (void)prepareForInterfaceBuilder为了告诉IB生活渲染视图。

在这里看到:Creating a Live View of a Custom Object

而且,你们是对的,这个功能也可用于Objective-C的。

你不一定需要使用drawRect,你可以尝试使用- (void)layoutSubviews,它似乎工作。仅仅为了实时渲染而将代码留在像- (void)layoutSubviews这样的地方的问题在于它可能性能较差等(例如,您可以在- (void)awakeFromNib中做很多事情,但该方法不会从实时渲染中调用,所以只要确保你做你的设立在- (void)prepareForInterfaceBuilder为好。

+0

这无助于呈现当前视图的子层的自定义CALayers。 – 2014-10-27 12:28:36

可以在IB预览UIView子类(与IB_DESIGNABLE宏)即使drawRect:没有覆盖
我加你code在XCode 6.1并将OEProgressIndicator添加到xib文件中。然后我通过在commonProgressIndicatorInit选择器中设置一个断点来调试它(使用菜单Editor/Debug Selected View)。

这就是为什么你没有看到在预览任何与你当前的代码commonProgressIndicatorInit被调用(从initWithFrame:(CGRect)frame构造函数),该frame等于CGRectZerox:0 y:0 width:0 height:0),使你的心变实际上等于(0, 0),半径是-1
在设备上,根据类的使用方式,可以直接调用适当的框架,这就是为什么它可以在设备上工作,但不在IB中。

为了解决这个问题,我将实现layoutSubviews选择(从UIView覆盖它)正常组织的子层。当frame将从CGRectZero更改为在Interface Builder中设置的适当值时,将调用此选择器。