2016-09-05 32 views
11

我期待通過類別方法將新的IBInspectable屬性(計算屬性)添加到UILabel。理想情況下,我希望在設置標籤文本(通過setValue:forKey)後設置此屬性,因爲此IBInspectable屬性可能導致UILabels文本被更新,我們不希望UILabel中的文本稍後替換它。查看文檔時,如果在Interface Builder中配置的屬性的nib/storyboard加載期間總是將用戶定義的屬性設置爲預先定義的屬性,則不會提及。用戶定義的運行時屬性(IBInspectable)是否在預定義屬性之後設置?

自定義屬性是否使用IBInspectable或在用戶定義的運行時屬性保證在標準預定義對象屬性/屬性之後設置的Interface Builder中添加到對象中?

+0

如果您以編程方式設置標籤的文本(如viewDidLoad中),或者您的意思是在IB中設置,您可以更清楚嗎? –

+0

對不起,通過IB – bencallis

回答

0

如果使用IBInspectable計算機變量創建擴展,則在界面構建器中設置這兩個值時,置於Interface Builder中的該自定義字段中的值將覆蓋標籤文本字段中的值,即使它不會預覽在Interface Builder中。

extension UILabel { 

    @IBInspectable var value: String? { 
     get { 
      return text 
     } 

     set { 
      text = newValue 
      setNeedsDisplay() 
     } 
    } 

} 

Interface builder enter image description here

+0

設置感謝您的答案。我已經實現了一個類似的擴展,並在不同版本的iOS上測試過,我注意到了相同的行爲。然而;我希望它被記錄在某處,所以我可以完全安全地在生產代碼中使用它。 – bencallis

2

下面的實驗得出結論,本機文本屬性之前的類別屬性設置,所以該值可以按類別制定者可以安全地覆蓋。

的標籤類別:

// UILabel+Thingy.h 

#import <UIKit/UIKit.h> 

@interface UILabel (Thingy) 

@property (nonatomic, strong) IBInspectable NSString *thingy; 

@end 

// UILabel+UILabel_Thingy.m 

#import "UILabel+Thingy.h" 
#import <objc/runtime.h> 

@implementation UILabel (Thingy) 

- (NSString *)thingy { 
    return objc_getAssociatedObject(self, @selector(thingy)); 
} 

- (void)setThingy:(NSString *)thingy { 
    NSLog(@"setting thingy to '%@', my text is currently '%@'", thingy, self.text); 
    objc_setAssociatedObject(self, @selector(thingy), thingy, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

@end 

在IB中,設置檢查的類別屬性和文本屬性....

enter image description here

在含視圖控制器小儀器:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSLog(@"didLoad text is '%@' and thingy is '%@'", self.label.text, self.label.thingy); 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    NSLog(@"willAppear text is '%@' and thingy is '%@'", self.label.text, self.label.thingy); 
} 

運行它,並且NSLog輸出ind在從nib清醒期間,本機屬性由分類屬性設置器被調用時設置...

... [794:41622]將thingy設置爲'thingy value',我的文本是目前 '文本值'

... [794:41622] didload文字是 '文本值' 和啄爲 '啄值'

... [794:41622] willappear文字是 '文本值'而thingy是'thingy value'

在ca中設置標籤的文本屬性tegory屬性setter將(並且,我測試了它)導致text屬性被覆蓋到thingy屬性,因爲text屬性首先被初始化。

進一步的證據可以在XIB文件時作爲XML呈現可見...

<label opaque="NO" (... all the native properties) text="text value" (...) id="XAM-6h-4fn"> 
    <rect key="frame" x="274" y="147" width="278" height="34"/> 

    (... and so on) 

    <userDefinedRuntimeAttributes> 
     <userDefinedRuntimeAttribute type="string" keyPath="thingy" value="thingy value"/> 
    </userDefinedRuntimeAttributes> 
</label> 

...與視圖被實例化,並且經由預購遍歷初始化,從而其是一致在(子標籤)userDefinedRuntimeAttributes之前設置(父標籤)標籤屬性。

+0

感謝您的回覆。在不同版本的iOS上進行測試期間,我注意到了相同的行爲。然而;我希望它被記錄在某處,所以我可以完全安全地在生產代碼中使用它。 – bencallis

+0

看起來並沒有明確地被覆蓋在哪裏可以看到它在文檔中。但是,證明確定性行爲比文檔更好,對嗎?只要它使用100%的公共API,該行爲就可以視爲對您的應用程序來說是永久性的,就像SDK的任何部分一樣。 – danh

+0

我想在iOS的未來版本中擔心的問題是,在沒有任何明顯的API更改的情況下更改訂單。 – bencallis

相關問題