2016-07-21 25 views
4

根據NSHipster,「讓自定義UI類符合UIAppearance不僅是一種最佳實踐,而且它還表現出一定程度的謹慎加入其實施。」通過UIAppearance在Swift中定製的UIView子類中設置文本屬性

因此,我想在一個UIView子這樣的設置文本屬性,這是後來用於創建NSAttributedString,到屬性var titleTextAttributes: [String : AnyObject]?

func applyAppearance() { 

    UINavigationBar.appearance().translucent = true 
    UINavigationBar.appearance().tintColor = UIColor(named: .NavBarTextColor) 
    UINavigationBar.appearance().barTintColor = UIColor(named: .NavBarBlue) 
    UINavigationBar.appearance().titleTextAttributes = [ 
     NSForegroundColorAttributeName: UIColor(named: .NavBarTextColor), 
     NSFontAttributeName: UIFont.navBarTitleFont()! 
    ] 

    ActionBarView.appearance().backgroundColor = UIColor(white: 1, alpha: 0.15) 
    ActionBarView.appearance().titleTextAttributes = [ 
     NSKernAttributeName: 1.29, 
     NSFontAttributeName: UIFont.buttonFont()!, 
     NSForegroundColorAttributeName: UIColor.whiteColor(), 
    ] 
} 

這是一個從我AppDelegate剪斷。

現在,試圖設置ActionBarView.appearance().titleTextAttributes = [ ... ]的時候,我發現了以下運行時錯誤:

​​

值得一提的是,沒有任何問題設置上UINavigationBar作品的屬性。

UINavigationBar的頭文件揭示了這一點:

/* You may specify the font, text color, and shadow properties for the title in the text attributes dictionary, using the keys found in NSAttributedString.h. 
*/ 
@available(iOS 5.0, *) 
public var titleTextAttributes: [String : AnyObject]? 

這正好是一個屬性相同的定義在我ActionBarView類:

class ActionBarView: UIView { 

    var titleTextAttributes: [String : AnyObject]? 

    // ... 
} 

所以我的問題是:有沒有我可以通過UIAppearance代理在我自己的UIView子類中使用文本屬性字典來實現屬性的任何操作? 由於在Swift中使用UI_APPEARANCE_SELECTOR是不可能的?爲什麼它爲UIKit類如UINavigationBar開箱即用?有沒有涉及到某種黑魔法?

+0

似乎將我的屬性'titleTextAttributes'標記爲'dynamic'並將其作爲存儲的另一個支持解決此問題:http://stackoverflow.com/a/28734970/1161723 –

+0

嗯,我想你告訴我!對於那個很抱歉。所以這個功能必須通過某種混合(比如KVO,它也需要'動態')。 – matt

回答

1

基於this answer,標誌着物業titleTextAttributes作爲dynamic,並用另一個作爲存儲備份解決了這個問題:

class ActionBarView: UIView { 

    /// UIAppearance compatible property 
    dynamic var titleTextAttributes: [String : AnyObject]? { // UI_APPEARANCE_SELECTOR 
     get { return self._titleTextAttributes } 
     set { self._titleTextAttributes = newValue } 
    } 

    private var _titleTextAttributes: [String : AnyObject]? 

    // ... use `self.titleTextAttributes` in the implementation 
} 
3

對於外觀屬性只是添加動態關鍵字:

class ActionBarView: UIView { 

    dynamic var titleTextAttributes: [String : AnyObject] = [:] 

    // use ActionBarView.appearance().titleTextAttributes 
} 

和外觀屬性存取方法必須爲form:

func propertyForAxis1(axis1: IntegerType, axis2: IntegerType, axisN: IntegerType) -> PropertyType 
func setProperty(property: PropertyType, forAxis1 axis1: IntegerType, axis2: IntegerType) 
+0

可以實現對'dynamic'不敏感的樣式,並且可以處理嵌套對象的屬性(如'view.layer.cornerRadius')。如果您有興趣,請查看[StyleSheet](https://github.com/werediver/StyleSheet)。 – werediver

相關問題