UIButtonConfiguration

前言

隨著iOS的更新汽纤,大的變動似乎沒有员魏,小的變動卻很多孟岛。而且國內(nèi)的開發(fā)者和國外的有一個很大的不同點兼呵,就是國內(nèi)的求穩(wěn)胆剧,國外的求創(chuàng)新垃沦。我接手過的幾個項目特姐,最低支持的還有iOS7的巷查,普遍的都是iOS8歌馍、9握巢。代碼很少會考慮到iOS12,13以上的新特性松却。2022年4月25號暴浦,蘋果強制打包的SDK必須升級到iOS15,之前是警告我都沒在意晓锻,現(xiàn)在成錯誤了歌焦。最開始我還以為可以像添加真機調(diào)試包那樣不用升級XCode就可以,后來發(fā)現(xiàn)我想多了砚哆。必須升級XCode13独撇,升級XCode的過程也是一波三折。XCode13.2.1必須要MacOS Big Sur(MacOS 11),我的電腦是12年的mini纷铣,然后各種求救卵史,發(fā)現(xiàn)可以通過打補丁升級。反正折騰了一天搜立,搞好了之后升級然后發(fā)現(xiàn)項目出現(xiàn)各種各樣的UIbug以躯,什么導(dǎo)航欄透明變白的,UIBarButtonItem的顏色出現(xiàn)問題啊啄踊,TabBar也出現(xiàn)問題忧设。弄好了之后。我就發(fā)現(xiàn)了一個問題社痛。蘋果的代碼風(fēng)格變了见转,如果你寫過Flutter或者用過SwiftUI,你就越發(fā)覺得蘋果的代碼設(shè)計風(fēng)格變了蒜哀,特別是在UIKit里斩箫,頻繁的出現(xiàn)了一個詞Configuartion,像UILabel,UITabbar,UIButton,UINavigationBar等等撵儿。都有與之對應(yīng)的Configuration對象乘客。甚至像基礎(chǔ)類型UIColor,backgroundColor都有與之對應(yīng)的Configuration對象。這樣的設(shè)計風(fēng)格初看有些繁瑣淀歇,但用的多了易核,反而很順手,這種設(shè)計模式就是23種設(shè)計模式中的裝飾模式浪默。

UIButtonConfiguration作用的UI元素

UIButtonConfiguration既然是裝飾模式的一種實踐牡直,那么它必然只會對UI元素做集成,像消息傳遞纳决、手勢碰逸、動作、它是不參與的阔加,顏色文本圖片背景樣式的饵史,它都可以涉及到。

API詳述

弄清楚一個類的成員屬性和方法胜榔,就是寫個案例試一下胳喷。這樣是最快的,比google和百度都好的多夭织。但也僅限于UI類吭露。像一些抽象類,工具類查文檔更適合尊惰。

1. 初始化方法

///主要生成扁平純凈的ButtonConfiguration奴饮,不設(shè)置額外屬性
+ (instancetype)plainButtonConfiguration;

///著色類ButtonConfiguration纬向,主要特點是背景色會半透明化,比如設(shè)置yellowColor的背景色戴卜,而背景的顏色呈現(xiàn)半透明黃色
+ (instancetype)tintedButtonConfiguration;

///半透明灰色背景按鈕逾条,設(shè)置自定義basebackgroundColor會改變背景色,也就是它的優(yōu)先級低一點投剥。
+ (instancetype)grayButtonConfiguration;

///填充類ButtonConfiguration师脂,它的效果和plainButtonConfiguration類似(暫時未發(fā)現(xiàn)不同)
+ (instancetype)filledButtonConfiguration;

///強制無邊框圓角類ButtonConfiguration,它的優(yōu)先級最高江锨,如果你設(shè)置了btn.layer.cornerRadius, 或者config.background也設(shè)置了圓角或者設(shè)置了config.cornerStyle都不會出現(xiàn)圓角吃警。
+ (instancetype)borderlessButtonConfiguration;

///內(nèi)置設(shè)置了一個圓角為5左右的ButtonConfiguration,但優(yōu)先級小于btn.layer.cornerRadius
+ (instancetype)borderedButtonConfiguration;

///圓角半透明背景的ButtonConfiguration
+ (instancetype)borderedTintedButtonConfiguration;

///圓角個性化ButtonConfiguration啄育,主要體現(xiàn)在背景色不透明酌心,文字和圖片著色和背景色相反(例如黑色背景,白色文字或者白色背景挑豌,黑色文字等)安券。這一前提在于不主動設(shè)置文字顏色和圖片顏色的前提。一般情況下氓英,如果不設(shè)置文字和圖片顏色侯勉,它們的顏色則為系統(tǒng)默認的系統(tǒng)藍色。
+ (instancetype)borderedProminentButtonConfiguration;

///init和new方法是不允許使用的
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

///這個方法铝阐,根據(jù)說明是復(fù)制指定button的ButtonConfiguration址貌。但有一個疑問,這個是實例方法徘键。我試了一下练对,它并不能復(fù)制指定狀態(tài)的configuration,比如normal狀態(tài)是ConfigA,selected狀態(tài)是configB,但復(fù)制只會復(fù)制normal狀態(tài)的值,這和直接btn.configuration = config貌似沒有什么區(qū)別吹害,可能是我研究不深螟凭,沒有發(fā)現(xiàn)它們的區(qū)別
- (instancetype)updatedConfigurationForButton:(UIButton *)button;

2. 屬性變量

///這個是一個關(guān)于background相關(guān)的config對象,他能處理的內(nèi)容太多了赠制,背景色,圓角挟憔,邊框钟些,陰影,自定義繪圖(貝塞爾曲線繪圖等)绊谭,毛玻璃特效政恍,背景圖片等。只要和背景相關(guān)的UI元素达传,基本都能處理篙耗。
@property (nonatomic, readwrite, strong) UIBackgroundConfiguration *background;

///圓角風(fēng)格枚舉
-1迫筑,固定圓角,0:動態(tài)圓角這兩個值其實差不多宗弯,就是圓角值可以通過btn.layer.cornerRadius和config.background.cornerRadius兩種方式設(shè)置脯燃。1、2蒙保、3這三個值代表內(nèi)置的小辕棚、中、大三個內(nèi)置的圓角邓厕,他的優(yōu)先級比btn.layer.cornerRadius和config.background.cornerRadius 高逝嚎,4是膠囊風(fēng)格,就是圓角切成膠囊狀详恼,優(yōu)先級和1补君、2、3一樣昧互。
@property (nonatomic, readwrite, assign) UIButtonConfigurationCornerStyle cornerStyle;

///內(nèi)置的title字體大小挽铁,優(yōu)先級比attributedTitle低,也就是你不想自己設(shè)置title和Subtitle字體大小時可以用這個枚舉來參考設(shè)置硅堆,一般來講如果自己的UI設(shè)計和審美不怎么樣屿储,或者無所謂時用一用系統(tǒng)推薦的也不錯,畢竟蘋果的審美你沒法說別人不好吧??渐逃。
@property (nonatomic, readwrite, assign) UIButtonConfigurationSize buttonSize;

///看字面意思就是適配mac端的按鈕樣式够掠。
@property (nonatomic, readwrite, assign) UIButtonConfigurationMacIdiomStyle macIdiomStyle;

///文本顏色,title和Subtitle茄菊,根據(jù)文檔疯潭,它的優(yōu)先級比attributedTitleattributedSubtitle以及它倆的變形器都低。它是一個全局設(shè)置變量面殖,當你想按鈕任何狀態(tài)文本顏色不變時竖哩,可以設(shè)置這個值
@property (nonatomic, readwrite, strong, nullable) UIColor *baseForegroundColor;

///背景色,同理它的優(yōu)先級比background低脊僚。
@property (nonatomic, readwrite, strong, nullable) UIColor *baseBackgroundColor;

///圖片
@property (nonatomic, readwrite, strong, nullable) UIImage *image;

///圖片顏色變形器相叁,他是一個輸入顏色,再輸出顏色的回調(diào)辽幌,目前不清楚設(shè)置成回調(diào)的好處增淹,反正你在回調(diào)里直接返回你想要設(shè)置的顏色即可
@property (nonatomic, readwrite, copy, nullable) UIConfigurationColorTransformer imageColorTransformer;

///內(nèi)置的系統(tǒng)矢量圖圖標config對象,你可以設(shè)置指定風(fēng)格,大小乌企,顏色的矢量圖圖標作為按鈕的image
@property (nonatomic, readwrite, copy, nullable) UIImageSymbolConfiguration *preferredSymbolConfigurationForImage;

///是否顯示加載轉(zhuǎn)圈的HUD圖標(菊花指示器)虑润,HUD的位置和image是一致的,且hud和image不能同時存在
@property (nonatomic, readwrite, assign) BOOL showsActivityIndicator;

///加載HUD指示器的顏色變形器
@property (nonatomic, readwrite, copy, nullable) UIConfigurationColorTransformer activityIndicatorColorTransformer;

///主標題的文本加酵,富文本及變形器
@property (nonatomic, readwrite, copy, nullable) NSString *title; @property (nonatomic, readwrite, copy, nullable) NSAttributedString *attributedTitle; @property (nonatomic, readwrite, copy, nullable) UIConfigurationTextAttributesTransformer titleTextAttributesTransformer;

///副標題的文本拳喻,富文本及變形器
@property (nonatomic, readwrite, copy, nullable) NSString *subtitle; @property (nonatomic, readwrite, copy, nullable) NSAttributedString *attributedSubtitle; @property (nonatomic, readwrite, copy, nullable) UIConfigurationTextAttributesTransformer subtitleTextAttributesTransformer;

///內(nèi)容四邊距
@property (nonatomic, readwrite, assign) NSDirectionalEdgeInsets contentInsets;

///恢復(fù)默認邊距
- (void)setDefaultContentInsets;

///圖標放置方位哭当,這是一個非常好用的屬性,在這之前冗澈,如果你想制作右圖左文钦勘,上圖下文的圖標,你得設(shè)置imageInset和titleInset渗柿,關(guān)鍵還要計算文本的size和圖標的size个盆。如果你的按鈕通過AutoLayout布局,那么這將計算更加困難朵栖,你必須將UIButton子類化颊亮,在-layoutSubviews方法中調(diào)整,不然無法獲取titleLabel和imageView的正確尺寸≡山Γ現(xiàn)在有了這個屬性再配合imagePadding一切變得那么美好了终惑,親愛的(grd)蘋果的工程師,為什么不早點拿出來懊派取雹有?有一點需要說明,這是個option枚舉臼寄,意思是可以多選霸奕,但實際應(yīng)用,并不能達到效果吉拳,比如你想圖標在右上角,你將值設(shè)置為NSDirectionalRectEdgeTop|NSDirectionalRectEdgeTrailing實際上按鈕還是Y軸居中质帅,右邊顯示,沒有啥效果留攒,目前不明啥原因煤惩,我猜測可能需要配合UIButton的對齊屬性使用才有效果。
@property (nonatomic, readwrite, assign) NSDirectionalRectEdge imagePlacement;

///圖標距文本的距離
@property (nonatomic, readwrite, assign) CGFloat imagePadding;

///標題與子標題的間距炼邀,可以為負值
@property (nonatomic, readwrite, assign) CGFloat titlePadding;

///按鈕文本對齊風(fēng)格
@property (nonatomic, readwrite, assign) UIButtonConfigurationTitleAlignment titleAlignment;

///選中狀態(tài)時是否更新buttonConfigration魄揉,實際用不到,下面會體現(xiàn)
@property (nonatomic, readwrite, assign) BOOL automaticallyUpdateForSelection;

///下面是UIButton的屬性拭宁,這個也是核心洛退,根據(jù)按鈕不同的狀態(tài)切換不同的buttonConfiguration,值得注意的是每個分支結(jié)尾必須重新賦值,示例如下

btn.configurationUpdateHandler = ^(UIButton *b) {
        if (b.state == UIControlStateHighlighted) {
            btnConfig.showsActivityIndicator = YES;
            btnConfig.attributedTitle = [[NSAttributedString alloc] initWithString:@"Highlighted Title" attributes:@{NSForegroundColorAttributeName:[UIColor systemRedColor]}];
            btnConfig.attributedSubtitle = [[NSAttributedString alloc] initWithString:@"Highlighted Subtitle" attributes:@{NSForegroundColorAttributeName:[UIColor systemRedColor]}];
            btnConfig.image = [UIImage systemImageNamed:@"square.and.arrow.up.fill"];
            btnConfig.imageColorTransformer = ^UIColor * _Nonnull(UIColor * _Nonnull color) {
                return [UIColor systemPurpleColor];
            };
            ///這個賦值操作必須寫杰标,不然不生效
            b.configuration = btnConfig;
        }else {
            btnConfig.showsActivityIndicator = NO;
            btnConfig.attributedTitle = [[NSAttributedString alloc] initWithString:@"Normal Title" attributes:@{NSForegroundColorAttributeName:[UIColor systemRedColor]}];
            btnConfig.attributedSubtitle = [[NSAttributedString alloc] initWithString:@"Normal Subtitle" attributes:@{NSForegroundColorAttributeName:[UIColor systemRedColor]}];
            btnConfig.image = [UIImage systemImageNamed:@"square.and.arrow.up"];
            btnConfig.imageColorTransformer = ^UIColor * _Nonnull(UIColor * _Nonnull color) {
                return [UIColor systemOrangeColor];
            };
            ///這個賦值操作必須寫兵怯,不然不生效
            b.configuration = btnConfig;
        }
    };

還有一個要注意的點

///這行代碼生效
btnConfig.baseForegroundColor = [UIColor systemGreenColor];
 btn.configuration = btnConfig;
///這行代碼不生效
btnConfig.baseForegroundColor = [UIColor systemRedColor];

總結(jié)

UIButtonConfiguration的優(yōu)點在我看來有以下幾點

  1. 使用裝飾模式,讓責任區(qū)分更加明確在旱。
  2. 更多內(nèi)置樣式摇零,在某些場景使用更方便推掸。
  3. API擴展性更強大了桶蝎,這可能是最重要的一點了驻仅。給按鈕加自定義背景視圖,比如毛玻璃登渣,多彩漸變等噪服。給按鈕添加加載指示器。調(diào)整按鈕的圖文布局等胜茧,在以前的環(huán)境的下粘优,要添加大量代碼。而現(xiàn)在變得更加簡單了呻顽。

唯一的缺點是版本要求太高雹顺,無法兼容低版本。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末廊遍,一起剝皮案震驚了整個濱河市嬉愧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喉前,老刑警劉巖没酣,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異卵迂,居然都是意外死亡裕便,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門见咒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偿衰,“玉大人,你說我怎么就攤上這事论颅“タ眩” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵恃疯,是天一觀的道長漏设。 經(jīng)常有香客問我,道長今妄,這世上最難降的妖魔是什么郑口? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮盾鳞,結(jié)果婚禮上犬性,老公的妹妹穿的比我還像新娘。我一直安慰自己腾仅,他們只是感情好乒裆,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著推励,像睡著了一般鹤耍。 火紅的嫁衣襯著肌膚如雪肉迫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天稿黄,我揣著相機與錄音喊衫,去河邊找鬼。 笑死杆怕,一個胖子當著我的面吹牛族购,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播陵珍,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼寝杖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了互纯?” 一聲冷哼從身側(cè)響起朝墩,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伟姐,沒想到半個月后收苏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡愤兵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年鹿霸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秆乳。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡懦鼠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屹堰,到底是詐尸還是另有隱情肛冶,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布扯键,位于F島的核電站睦袖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荣刑。R本人自食惡果不足惜馅笙,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厉亏。 院中可真熱鬧董习,春花似錦、人聲如沸爱只。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至窝趣,卻和暖如春蔗喂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背高帖。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畦粮,地道東北人散址。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像宣赔,于是被迫代替她去往敵國和親预麸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容