2014-09-25 129 views
4

是否有可能創建一個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

回答

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

有關如何調試實時視圖的說明,請參閱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

2

我一直在使用方法- (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

3

可以在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中設置的適當值時,將調用此選擇器。