對(duì)象繼承關(guān)系
UIButton 類本身定義繼承 UIControl ,描述了在 iOS 上所有用戶界面控件的常見(jiàn)基本行為。反過(guò)來(lái), UIControl 類繼承 UIView ,給在屏幕顯示的對(duì)象提供常用功能。UIView 繼承于 UIResponder,允許它響應(yīng)用戶輸 入、手勢(shì)。最后,也是最重要的,UIResponder 繼承 NSObject,圖 1-3 所示。

Documentation and API Reference
UIButton 對(duì)象是一個(gè)視圖,它用于執(zhí)行你的自定義代碼以響應(yīng)用戶交互。
概述
當(dāng)你觸摸點(diǎn)擊按鈕或選擇具有焦點(diǎn)的按鈕時(shí),該按鈕就會(huì)執(zhí)行被附加上的任何操作。 你可以使用文本標(biāo)簽,圖像或兩者同時(shí)使用來(lái)傳達(dá)按鈕的功能。 按鈕的外觀是可配置的,因此你可以使用色調(diào)按鈕或格式化的標(biāo)題來(lái)匹配應(yīng)用程序的設(shè)計(jì)。 你可以通過(guò)編程方式或使用Interface Builder向界面添加按鈕。

當(dāng)添加一個(gè)按鈕到你的界面上時(shí),請(qǐng)執(zhí)行以下步驟:
- 創(chuàng)建按鈕時(shí),設(shè)置按鈕的類型。
- 設(shè)置標(biāo)題或圖片,并根據(jù)內(nèi)容適當(dāng)調(diào)整按鈕的大小。
- 為按鈕設(shè)置一個(gè)或多個(gè)目標(biāo)-動(dòng)作(Target-Action)方法。
- 設(shè)置自動(dòng)布局(Auto Layout)規(guī)則來(lái)控制界面中按鈕的大小和位置。
- 提供輔助功能信息和本地化字符串。
關(guān)于基本視圖行為的更多信息,請(qǐng)參閱:View Programming Guide for iOS.
響應(yīng)按鈕觸摸事件
當(dāng)用戶觸摸點(diǎn)擊按鈕時(shí),按鈕使用 Target-Action 設(shè)計(jì)模式監(jiān)聽(tīng)APP。并不是直接處理觸摸事件,你可以向按鈕分配操作方法,并指定哪些事件觸發(fā)對(duì)你的方法的調(diào)用。 在運(yùn)行時(shí),該按鈕可處理所有傳入的觸摸事件并調(diào)用您的方法作為響應(yīng)。
你使用 addTarget:action:forControlEvents: 方法連接按鈕到動(dòng)作方法上,或者在 Interface Builder 建立連接。動(dòng)作方法的簽名采用清單1中列出的三種形式之一。選擇提供您需要響應(yīng)按鈕輕敲的信息的表單。
Listing 1 Action methods for buttons:
- (IBAction)doSomething;
- (IBAction)doSomething:(id)sender;
- (IBAction)doSomething:(id)sender forEvent:(UIEvent*)event;
配置按鈕外觀
按鈕的類型決定了它的基本外觀和行為,在創(chuàng)建按鈕時(shí),使用buttonWithType: 方法指定按鈕的類型。創(chuàng)建按鈕之后,你無(wú)法再更改它的類型了。最常用的類型是 UIButtonTypeSystem 、UIButtonTypeCustom (默認(rèn)),請(qǐng)?jiān)诤线m時(shí)使用其它類型。
注意
要配置應(yīng)用程序中所有按鈕的外觀,請(qǐng)使用外觀代理對(duì)象。 UIButton 類實(shí)現(xiàn)了
appearance類方法,您可以使用它來(lái)獲取應(yīng)用程序中所有按鈕的外觀代理。
按鈕狀態(tài)
按鈕有五個(gè)狀態(tài)定義其外觀:default(默認(rèn)),highlighted(高亮),focused(聚焦),selected(選中)和disabled(禁用)。 當(dāng)您將一個(gè)按鈕添加到界面時(shí),它最初處于default(默認(rèn))狀態(tài),這意味著該按鈕已啟用(enabled),并且用戶未與其進(jìn)行交互。 當(dāng)用戶與按鈕進(jìn)行交互時(shí),其狀態(tài)將更改為其他值。 例如,當(dāng)用戶點(diǎn)擊帶有標(biāo)題的按鈕時(shí),按鈕將改變到 highlighted(高亮)狀態(tài)。
以編程方式或在Interface Builder中配置按鈕時(shí),可以分別為每個(gè)狀態(tài)指定屬性。 在Interface Builder中,使用“屬性”檢查器中的“狀態(tài)配置”控件選擇適當(dāng)?shù)臓顟B(tài),然后配置其他屬性。 如果不為特定狀態(tài)指定屬性,則 UIButton 類提供合理的默認(rèn)行為。 例如,禁用的按鈕通常變暗,并且在輕拍時(shí)不顯示高亮。 該類的其他屬性,如adjustImageWhenHighlighted和 adjustImageWhenDisabled屬性,可以在特定情況下更改默認(rèn)行為。
內(nèi)容
按鈕的內(nèi)容由你指定的標(biāo)題字符串或圖像組成。你指定的內(nèi)容是用于配置被按鈕所擁有的 UILabel 和 UIImageView 對(duì)象。你可以使用 titleLabel 或 imageView 屬性配置這些對(duì)象,或者直接對(duì)它們賦值。按鈕也有背景顏色,它位于您指定的內(nèi)容后面。很可能同時(shí)指定按鈕的圖片和標(biāo)題,它會(huì)導(dǎo)致下圖的結(jié)果。你可以使用指定的屬性訪問(wèn)按鈕的當(dāng)前內(nèi)容。

當(dāng)設(shè)置按鈕的內(nèi)容時(shí),你必須指定每個(gè)狀態(tài)下的標(biāo)題、圖片和外觀屬性。如果你不為某個(gè)特定狀態(tài)自定義內(nèi)容,該按鈕使用與默認(rèn)狀態(tài)相關(guān)聯(lián)的值,并添加任何適當(dāng)?shù)淖远x配置。例如,在按鈕高亮狀態(tài)下,如果沒(méi)有提供自定義圖像,則基于圖像的按鈕將在默認(rèn)圖像的上方繪制高亮。
色調(diào)顏色
你可以通過(guò) tintColor 屬性指定自定義按鈕的色調(diào)。該屬性會(huì)設(shè)置按鈕圖片和文本的顏色。如果你沒(méi)有明確設(shè)置色調(diào),那么按鈕使用它父類的色調(diào)。
邊緣插入量
使用 insets 來(lái)添加或刪除你自定義(或系統(tǒng)的)按鈕內(nèi)容周圍空間,你可以單獨(dú)為按鈕標(biāo)題(titleEdgeInsets)、圖片(imageEdgeInsets)或同時(shí)為標(biāo)題和圖片(contentEdgeInsets)指定 insets 值。應(yīng)用時(shí),insets 影響了按鈕的相應(yīng)內(nèi)容矩形,由Auto Layout引擎用于確定按鈕的位置。
你應(yīng)該沒(méi)有理由去調(diào)整 info,contact 或指示器按鈕的邊緣插入量。
Interface Builder 屬性
表一列出了 Interface Builder 中按鈕配置的核心屬性。
| 屬性 | 描述 |
|---|---|
| Type | 按鈕的類型。該屬性決定了許多其他按鈕屬性的默認(rèn)設(shè)置。該類型屬性無(wú)法在運(yùn)行時(shí)被改變,但是你可以使用 buttonType屬性訪問(wèn)它。 |
| State Config | 狀態(tài)選擇器。 在此控件中選擇一個(gè)值后,按鈕屬性的更改將適用于指定的狀態(tài)。 |
| Title | 按鈕的標(biāo)題。你可以用純字符串或?qū)傩宰址付ò粹o的標(biāo)題 |
| (Title Font and Attributes) | 適用于按鈕標(biāo)題字符串的字體和其他屬性。具體的配置選項(xiàng)取決于你對(duì)按鈕的標(biāo)題使用純字符串還是屬性字符串。對(duì)于純字符串來(lái)說(shuō),你可以設(shè)置字體、文本顏色和陰影顏色。對(duì)于屬性字符串來(lái)說(shuō),你可以指定對(duì)齊方式,文本方向,縮進(jìn),連字號(hào)等許多選項(xiàng)。 |
| Image | 按鈕的前景圖片。通常來(lái)說(shuō),你可以使用模板圖片指定按鈕的前景,但是你可以在XCode 項(xiàng)目中指定任何圖片。 |
| Background | 按鈕的背景圖片。按鈕的背景圖片是展示在它的標(biāo)題和前景圖片后面的。 |
表2列出了影響按鈕外觀的屬性
| 屬性 | 描述 |
|---|---|
| Shadow Offset | 按鈕陰影的偏移和行為。陰影只會(huì)影響標(biāo)題字符串。 當(dāng)按鈕狀態(tài)更改為或高亮狀態(tài)時(shí),啟用“高亮狀態(tài)”選項(xiàng)上的“反轉(zhuǎn)”選項(xiàng)可更改陰影的高亮。 使用編程方式配置偏移量使用按鈕的titleLabel 對(duì)象的 shadowOffset 屬性。配置高亮行為使用 reversesTitleShadowWhenHighlighted 屬性。 |
| Drawing | 按鈕的繪圖行為。 當(dāng)高亮?xí)r顯示觸摸 showsTouchWhenHighlighted 屬性開啟時(shí), 該按鈕向用戶觸摸的按鈕的部分添加白色光澤。 當(dāng)高亮?xí)r調(diào)整圖片 adjustsImageWhenHighlighted 屬性開啟時(shí)。高亮狀態(tài)時(shí),安妮圖片變暗。 當(dāng)禁用時(shí)調(diào)整圖片 adjustsImageWhenDisabled 屬性開啟時(shí), 當(dāng)按鈕被禁用時(shí),圖像變暗。 |
| Line Break | 按鈕文本的打斷顯示選項(xiàng)。 使用此屬性來(lái)定義按鈕的標(biāo)題如何修改以適應(yīng)可用空間。 |
表3列出了按鈕的邊緣插入量屬性。使用邊緣插入按鈕更改按鈕內(nèi)容的矩形。
| 屬性 | 描述 |
|---|---|
| Edge | 邊緣插入配置。 您可以為按鈕的整體內(nèi)容,其標(biāo)題及其圖像指定單獨(dú)的邊緣插入。 |
| Inset | 插入值。 正值縮小相應(yīng)的邊緣,使其更接近按鈕的中心。 負(fù)值展開邊緣,將其從按鈕的中心移開。運(yùn)行時(shí)使用 contentEdgeInsets、titleEdgeInsets 和imageEdgeInsets屬性訪問(wèn)這些值。 |
有關(guān)按鈕的繼承的 Interface Builde r屬性的信息,參閱 UIControl 和 UIView。
國(guó)際化
要使按鈕國(guó)際化,請(qǐng)為按鈕的標(biāo)題文本指定一個(gè)本地化的字符串。 (您也可以根據(jù)需要定位按鈕的圖像。)
使用故事板構(gòu)建界面時(shí),請(qǐng)使用Xcode的基本國(guó)際化功能來(lái)配置項(xiàng)目支持的本地化。 當(dāng)您添加本地化時(shí),Xcode將為該本地化創(chuàng)建一個(gè)字符串文件。 以編程方式配置接口時(shí),請(qǐng)使用系統(tǒng)的內(nèi)置支持來(lái)加載本地化字符串和資源。 有關(guān)國(guó)際化您的界面的更多信息,參閱 Internationalization and Localization Guide。
輔助功能
默認(rèn)情況下可以使用按鈕。 按鈕的默認(rèn)輔助功能特征是按鈕和用戶交互啟用。
當(dāng)在設(shè)備上啟用 VoiceOver 時(shí),可訪問(wèn)性標(biāo)簽,特征和提示將會(huì)發(fā)送給用戶。 按鈕的標(biāo)題覆蓋其無(wú)障礙標(biāo)簽; 即使您為標(biāo)簽設(shè)置了自定義值,VoiceOver會(huì)說(shuō)出標(biāo)題的值。 當(dāng)用戶點(diǎn)擊按鈕一次時(shí),VoiceOver會(huì)顯示此信息。 例如,當(dāng)用戶點(diǎn)擊“相機(jī)”中的“選項(xiàng)”按鈕時(shí),VoiceOver會(huì)說(shuō)出以下內(nèi)容:
- "選項(xiàng).按鈕.顯示其他相機(jī)選項(xiàng)"
有關(guān)使 iOS 控件可訪問(wèn)的更多信息,請(qǐng)參閱 UIControl 中的輔助功能信息。 有關(guān)使您的界面可訪問(wèn)的一般信息,請(qǐng)參閱Accessibility Programming Guide for iOS.
UIButton 的使用
初始化按鈕
+ (instancetype)buttonWithType:(UIButtonType)buttonType;
UIButtonType
這是個(gè)枚舉類型,用于指定按鈕風(fēng)格
| UIButtonType | 描述 |
|---|---|
| UIButtonTypeCustom | 無(wú)按鈕風(fēng)格。 |
| UIButtonTypeSystem | 系統(tǒng)風(fēng)格按鈕,例如導(dǎo)航欄和工具欄中顯示的那些。 |
| UIButtonTypeDetailDisclosure | 詳細(xì)說(shuō)明按鈕。 |
| UIButtonTypeInfoLight | 淺色背景的信息按鈕。 |
| UIButtonTypeInfoDark | 深色背景的信息按鈕 |
| UIButtonTypeContactAdd | 添加按鈕 |
| UIButtonTypeRoundedRect = UIButtonTypeSystem | (失效)圓角矩形樣式按鈕 |
示例:
// UIButtonTypeCustom
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.frame = CGRectMake(150, 50, 50, 50);
button1.backgroundColor = [UIColor turquoiseColor];
[button1 setTitle:@"button1" forState:UIControlStateNormal];
[self.view addSubview:button1];
// UIButtonTypeSystem
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
button2.frame = CGRectMake(150, 120, 50, 50);
[button2 setTitle:@"button2" forState:UIControlStateNormal];
[self.view addSubview:button2];
// UIButtonTypeDetailDisclosure
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
button3.frame = CGRectMake(150, 190, 50, 50);
[self.view addSubview:button3];
// UIButtonTypeInfoLight
UIButton *button4 = [UIButton buttonWithType:UIButtonTypeInfoLight];
button4.frame = CGRectMake(150, 260, 50, 50);
[self.view addSubview:button4];
// UIButtonTypeInfoDark
UIButton *button5 = [UIButton buttonWithType:UIButtonTypeInfoDark];
button5.frame = CGRectMake(150, 330, 50, 50);
[self.view addSubview:button5];
// UIButtonTypeContactAdd
UIButton *button6 = [UIButton buttonWithType:UIButtonTypeContactAdd];
button6.frame = CGRectMake(150, 400, 50, 50);
[self.view addSubview:button6];
// UIButtonTypeRoundedRect = UIButtonTypeSystem
UIButton *button7 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button7.frame = CGRectMake(150, 470, 50, 50);
[button7 setTitle:@"button7" forState:UIControlStateNormal];
[self.view addSubview:button7];
iOS 10.3 下:

設(shè)置按鈕內(nèi)容
// 設(shè)置標(biāo)題,假定為單行。
- (void)setTitle:(NSString *)title forState:(UIControlState)state;
// 設(shè)置標(biāo)題顏色,默認(rèn)為不透明白色。
- (void)setTitleColor:(nullable UIColor *)color forState:(UIControlState)state;
// 設(shè)置標(biāo)題陰影顏色,默認(rèn) 50% 黑色。
- (void)setTitleShadowColor:(nullable UIColor *)color forState:(UIControlState)state;
// 設(shè)置圖片,不同狀態(tài)下的圖片大小應(yīng)該相同
- (void)setImage:(nullable UIImage *)image forState:(UIControlState)state;
// 設(shè)置背景圖片
- (void)setBackgroundImage:(nullable UIImage *)image forState:(UIControlState)state;
// 設(shè)置標(biāo)題
- (void)setAttributedTitle:(nullable NSAttributedString *)title forState:(UIControlState)state;
UIControlState
該類也是一個(gè)枚舉類型,用于設(shè)置按鈕狀態(tài)
typedef NS_OPTIONS(NSUInteger, UIControlState) {
UIControlStateNormal = 0, // 正常狀態(tài)
UIControlStateHighlighted = 1 << 0, // 高亮狀態(tài)
UIControlStateDisabled = 1 << 1, // 禁用狀態(tài)
UIControlStateSelected = 1 << 2, // 選中狀態(tài)
UIControlStateFocused NS_ENUM_AVAILABLE_IOS(9_0) = 1 << 3, // 僅適用于屏幕支持對(duì)焦時(shí)(iOS新加入 應(yīng)該和3D Touch有關(guān))
UIControlStateApplication = 0x00FF0000, // 可用于應(yīng)用程序使用的附加標(biāo)志
UIControlStateReserved = 0xFF000000 // 標(biāo)記保留供內(nèi)部框架使用
};
示例代碼:
// UIControlStateHighlighted
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
button2.frame = CGRectMake(150, 120, 100, 50);
[button2 setTitle:@"高亮狀態(tài)" forState:UIControlStateHighlighted];
[button2 setHighlighted:YES];
[self.view addSubview:button2];
// UIControlStateDisabled
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
button3.frame = CGRectMake(150, 190, 100, 50);
[button3 setTitle:@"禁用狀態(tài)" forState:UIControlStateDisabled];
[button3 setEnabled:NO];
[self.view addSubview:button3];
// UIControlStateSelected
UIButton *button4 = [UIButton buttonWithType:UIButtonTypeSystem];
button4.frame = CGRectMake(150, 260, 100, 50);
[button4 setTitle:@"選中狀態(tài)" forState:UIControlStateSelected];
[button4 setSelected:YES];
[self.view addSubview:button4];
iOS 10.3 下:

添加、移除點(diǎn)擊事件
- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
- (void)removeTarget:(nullable id)target action:(nullable SEL)action forControlEvents:(UIControlEvents)controlEvents;
使用示例:
[button1 addTarget:self
action:@selector(butClick:)
forControlEvents:UIControlEventTouchUpInside];
// ...
// 調(diào)用的方法,用來(lái)響應(yīng)按鈕的點(diǎn)擊事件
- (void)butClick:(id)button {
// do something
}
UIControlEvents
UIControlEventTouchDown
單點(diǎn)觸摸按下事件:用戶點(diǎn)觸屏幕,或者又有新手指落下的時(shí)候。
UIControlEventTouchDownRepeat
多點(diǎn)觸摸按下事件,點(diǎn)觸計(jì)數(shù)大于1:用戶按下第二、三、或第四根手指的時(shí)候。
UIControlEventTouchDragInside
當(dāng)一次觸摸在控件窗口內(nèi)拖動(dòng)時(shí)。
UIControlEventTouchDragOutside
當(dāng)一次觸摸在控件窗口之外拖動(dòng)時(shí)。
UIControlEventTouchDragEnter
當(dāng)一次觸摸從控件窗口之外拖動(dòng)到內(nèi)部時(shí)。
UIControlEventTouchDragExit
當(dāng)一次觸摸從控件窗口內(nèi)部拖動(dòng)到外部時(shí)。
UIControlEventTouchUpInside
所有在控件之內(nèi)觸摸抬起事,一般用于按鈕。
UIControlEventTouchUpOutside
所有在控件之外觸摸抬起事件(點(diǎn)觸必須開始與控件內(nèi)部才會(huì)發(fā)送通知)。
UIControlEventTouchCancel
所有觸摸取消事件,即一次觸摸因?yàn)榉派狭颂嗍种付蝗∠?,或者被上鎖或者電話呼叫打斷。
UIControlEventTouchChanged
當(dāng)控件的值發(fā)生改變時(shí),發(fā)送通知。用于滑塊、分段控件、以及其他取值的控件。你可以配置滑塊控件何時(shí)發(fā)送通知,在滑塊被放下時(shí)發(fā)送,或者在被拖動(dòng)時(shí)發(fā)送。
UIControlEventEditingDidBegin
當(dāng)文本控件中開始編輯時(shí)發(fā)送通知。
UIControlEventEditingChanged
當(dāng)文本控件中的文本被改變時(shí)發(fā)送通知。
UIControlEventEditingDidEnd
當(dāng)文本控件中編輯結(jié)束時(shí)發(fā)送通知。
UIControlEventEditingDidOnExit
當(dāng)文本控件內(nèi)通過(guò)按下回車鍵(或等價(jià)行為)結(jié)束編輯時(shí),發(fā)送通知。
UIControlEventAlltouchEvents
通知所有觸摸事件。
UIControlEventAllEditingEvents
通知所有關(guān)于文本編輯的事件。
UIControlEventAllEvents
通知所有事件。
userInteractionEnabled 與 enabled 的區(qū)別
self.btn1.enabled = NO;
self.btn1.userInteractionEnabled = NO;
相同點(diǎn)
這兩個(gè)方法都可以將按鈕設(shè)置為禁用狀態(tài),阻止接受用戶觸摸事件及鍵盤響應(yīng)。
不同點(diǎn)
-
enabled = NO會(huì)使按鈕的狀態(tài)變?yōu)?code>UIControlStateDisabled,而userInteractionEnabled = NO不會(huì)。 -
enabled是UIControl的屬性(雖然UIButton是UICotrol的子類,但是這兩個(gè)方法都能用,因?yàn)?code>UICotrol 又是UIView的子類),而userInteractionEnabled是UIView、UIImageView、UILabel的屬性。 - 如果使用時(shí),同時(shí)設(shè)置了這兩個(gè)方法,那么,先設(shè)置的方法奏效。
關(guān)于 tintColor
tintColor 是 iOS7.0 引入的一個(gè) UIView 的屬性,該屬性會(huì)設(shè)置按鈕圖片和文本的顏色。
tintColor 具有 繼承、重寫、傳播 的特點(diǎn)。
繼承:只要一個(gè) UIView 的 subview 沒(méi)有明確指定
tintColor,那么這個(gè) UIView 的tintColor就會(huì)被它的 subview 所繼承!在一個(gè) App 中,最頂層的 view 就是 window,因此,只要修改 window 的tintColor,那么所有 view 的tintColor就都會(huì)跟著改變。(這種說(shuō)法其實(shí)并不嚴(yán)謹(jǐn),請(qǐng)耐心繼續(xù)看下去_)。重寫:如果明確指定了某個(gè) view 的
tintColor, 那么這個(gè) view 就不會(huì)繼承其 superview 的tintColor。而且自此, 這個(gè) view 的 subview 的tintColor會(huì)發(fā)生改變。傳播:一個(gè) view 的
tintColor的改變會(huì)立即向下傳播, 影響其所有的 subview,直至它的一個(gè) subview 明確指定了tintColor為止。
?? 如果創(chuàng)建的是 UIButtonTypeCustom 類型的按鈕,再去設(shè)置 tintColor 屬性是無(wú)效的。

將這張灰色的圖片設(shè)置為按鈕圖片:
// 創(chuàng)建一個(gè)系統(tǒng)類型按鈕
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
button2.frame = CGRectMake(80, 180, 180, 180);
// 設(shè)置按鈕的背景顏色為藍(lán)色
button2.backgroundColor = [UIColor skyBlueColor];
// 設(shè)置按鈕的色調(diào)顏色為綠色
button2.tintColor = [UIColor seafoamColor];
// 設(shè)置按鈕的標(biāo)簽文字
[button2 setTitle:@"Tap it" forState:UIControlStateNormal];
// 設(shè)置按鈕圖片
UIImage *image = [UIImage imageNamed:@"picture_button"];
[button2 setImage:image forState:UIControlStateNormal];
// 綁定按鈕的點(diǎn)擊動(dòng)作
[button2 addTarget:self
action:@selector(butClick:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button2];

運(yùn)行結(jié)果發(fā)現(xiàn)按鈕的圖片、文字都會(huì)變成綠色。
另外:
- 如果我們想指定整個(gè) APP 的 tint color,則可以通過(guò)設(shè)置 window 的 tint color。這樣同一個(gè)window下的所有子視圖都會(huì)繼承此 tint color。
- 如果你是用 storyboard 創(chuàng)建界面的, 那么只要在入口控制器的 File Inspector 中修改一下 Global Tint 即可。
設(shè)置圓角

代碼實(shí)現(xiàn):
button.clipsToBounds = YES; // 如果子視圖的范圍超出了父視圖的邊界,那么超出的部分就會(huì)被裁剪掉
button.layer.cornerRadius = 5; //這里的5是你想設(shè)置的圓角大小,比如是一個(gè)40*40的正方形,那個(gè)設(shè)置成20就是一個(gè)圓,以此類推
StoryBoard / Xib 中設(shè)置 UIButton 圓角:
-
工具區(qū)域 → Attribute inspector → View 勾選 Clip To Bounds
-
工具區(qū)域 → Identity inspector → User Define Runtime Attributes 添加如下:
設(shè)置邊框

代碼實(shí)現(xiàn):
// 創(chuàng)建一個(gè)按鈕
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
button3.frame = CGRectMake(80, 450, 150, 30);
// 設(shè)置按鈕的背景色
button3.backgroundColor = [UIColor icebergColor];
// 設(shè)置按鈕的前景色
button3.tintColor = [UIColor skyBlueColor];
// 設(shè)置按鈕的標(biāo)簽文字
[button3 setTitle:@"Tap it" forState:UIControlStateNormal];
// 給按鈕添加邊框效果
[button3.layer setMasksToBounds:YES];
// 設(shè)置層的圓角半徑
[button3.layer setCornerRadius:5.0];
// 設(shè)置邊框的寬度
[button3.layer setBorderWidth:2.0];
// 設(shè)置邊框的顏色
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef colorRef = CGColorCreate(colorSpace, (CGFloat[]){ 56/255.0, 237/255.0, 56/255.0, 1 });
[button3.layer setBorderColor:colorRef];
[self.view addSubview:button3];
按鈕高亮效果
需求如下:

代碼實(shí)現(xiàn):
UIButton *submitButton = [UIButton buttonWithType:UIButtonTypeCustom];
// 默認(rèn)標(biāo)題
NSDictionary *attributes = @{
NSFontAttributeName:[UIFont systemFontOfSize:18],
NSForegroundColorAttributeName:[UIColor whiteColor] };
NSAttributedString *title =[[NSAttributedString alloc] initWithString:@"提交" attributes:attributes];
[submitButton setAttributedTitle:title forState:UIControlStateNormal];
// 設(shè)置背景顏色
// 使用 YYKit 組件實(shí)現(xiàn)將顏色生成圖片效果
[submitButton setBackgroundImage:[UIImage imageWithColor:HexColor(@"#108EE9")]
forState:UIControlStateNormal];
[submitButton setBackgroundImage:[UIImage imageWithColor:HexColor(@"#1284D6")]
forState:UIControlStateHighlighted];
// 設(shè)置圓角
submitButton.clipsToBounds = YES;
submitButton.layer.cornerRadius = 5;
[submitButton addTarget:self
action:@selector(submitInfoAction:)
forControlEvents:UIControlEventTouchUpInside];
// 將按鈕添加到視圖上
[self.view addSubview:submitButton];
效果展示:

小按鈕高亮鏤空效果
代碼實(shí)現(xiàn):
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
// 默認(rèn)標(biāo)題
NSDictionary *attributes1 = @{
NSFontAttributeName:[UIFont systemFontOfSize:13],
NSForegroundColorAttributeName:HexColor(@"#108EE9")
};
NSAttributedString *normalTitle =[[NSAttributedString alloc] initWithString:@"示例" attributes:attributes1];
[button setAttributedTitle:normalTitle
forState:UIControlStateNormal];
// 高亮標(biāo)題
NSDictionary *attributes2 = @{
NSFontAttributeName:[UIFont systemFontOfSize:13],
NSForegroundColorAttributeName:[UIColor whiteColor]
};
NSAttributedString *highlightedTitle = [[NSAttributedString alloc] initWithString:@"示例" attributes:attributes2];
[button setAttributedTitle:highlightedTitle
forState:UIControlStateHighlighted];
// 高亮背景顏色
[button setBackgroundImage:[UIImage imageWithColor:HexColor(@"#108EE9")]
forState:UIControlStateHighlighted];
[button.layer setCornerRadius:3];
[button.layer setMasksToBounds:YES];
[button.layer setBorderWidth:1];
[button.layer setBorderColor:[HexColor(@"#108EE9") CGColor]];
// Target-Action
[button addTarget:self
action:@selector(buttonClickUpHandler:)
forControlEvents:UIControlEventTouchUpInside];
// 將按鈕添加到視圖上
[self.view addSubview:button];
效果展示:

圖文結(jié)合
通過(guò) setTitle:forState: 和 setImage:forState: 這兩個(gè)方法設(shè)置了 UIButton 的 標(biāo)題和圖片之后,可以通過(guò)以下兩個(gè)屬性訪問(wèn)代表 UIButton 中標(biāo)題和圖片的兩個(gè)子控件:
@property(nullable, nonatomic,readonly,strong) UILabel *titleLabel;
@property(nullable, nonatomic,readonly,strong) UIImageView *imageView;
-
UIControlContentVerticalAlignment
UIControlContentVerticalAlignment控制的是UIButton的image和title在豎直方向的對(duì)齊方式,其值有top、bottom、center、fill。當(dāng)指定為fill時(shí),圖片會(huì)在豎直方向被拉伸填滿UIButton的高度。
// UIButton的image和title在豎直方向的對(duì)齊方式
typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) {
UIControlContentVerticalAlignmentCenter = 0,
UIControlContentVerticalAlignmentTop = 1,
UIControlContentVerticalAlignmentBottom = 2,
UIControlContentVerticalAlignmentFill = 3,
};
| UIControlContentVerticalAlignment | 效果 |
|---|---|
| UIControlContentVerticalAlignmentCenter | ![]() |
| UIControlContentVerticalAlignmentTop | ![]() |
| UIControlContentVerticalAlignmentBottom | ![]() |
| UIControlContentVerticalAlignmentFill | ![]() |
-
UIControlContentHorizontalAlignment
UIControlContentHorizontalAlignment控制的則是水平方向的對(duì)齊方式。其值有left、right、center、fill。當(dāng)指定為fill時(shí),圖片并沒(méi)有在水平方向?qū)?code>UIButton充滿,而是在右側(cè)留出了一定距離,這個(gè)距離應(yīng)該是title的寬度,但是title實(shí)際上也沒(méi)有乖乖的跑到那段空隙去,而是和image重疊了
typedef NS_ENUM(NSInteger, UIControlContentHorizontalAlignment) {
UIControlContentHorizontalAlignmentCenter = 0,
UIControlContentHorizontalAlignmentLeft = 1,
UIControlContentHorizontalAlignmentRight = 2,
UIControlContentHorizontalAlignmentFill = 3,
};
| UIControlContentHorizontalAlignment | 效果 |
|---|---|
| UIControlContentHorizontalAlignmentCenter | ![]() |
| UIControlContentHorizontalAlignmentLeft | ![]() |
| UIControlContentHorizontalAlignmentRight | ![]() |
| UIControlContentHorizontalAlignmentFill | ![]() |
- UIEdgeInsets
使用 insets 來(lái)添加或刪除你自定義(或系統(tǒng)的)按鈕內(nèi)容周圍空間,你可以單獨(dú)為按鈕標(biāo)題(
titleEdgeInsets)、圖片(imageEdgeInsets)或同時(shí)為標(biāo)題和圖片(contentEdgeInsets)指定 insets 值。應(yīng)用時(shí),insets 影響了按鈕的相應(yīng)內(nèi)容矩形,由Auto Layout引擎用于確定按鈕的位置。
@property(nonatomic) UIEdgeInsets contentEdgeInsets;
@property(nonatomic) UIEdgeInsets titleEdgeInsets;
@property(nonatomic) UIEdgeInsets imageEdgeInsets;
默認(rèn)按鈕布局
創(chuàng)建一個(gè)圖片+標(biāo)題的按鈕:
// 創(chuàng)建自定義類型按鈕
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(80, 180, 150, 150);
// 設(shè)置按鈕的背景顏色
button.backgroundColor = [UIColor honeydewColor];
// 設(shè)置按鈕的標(biāo)簽文字
[button setTitle:@"Tap it" forState:UIControlStateNormal];
button.titleLabel.backgroundColor = [UIColor skyBlueColor];
// 設(shè)置按鈕圖片
UIImage *image = [UIImage imageNamed:@"buttonImage"];
[button setImage:image forState:UIControlStateNormal];
[self.view addSubview:button];
默認(rèn)情況下:圖片在左邊而文字在右邊,而且整體水平和垂直居中。

這是一個(gè) UIButton 范疇(Category) 類,用于處理圖文結(jié)合
- UIButton+ImageTitleStyle.h 文件
#import <UIKit/UIKit.h>
@interface UIButton (ImageTitleStyle)
//上下居中,圖片在上,文字在下
- (void)verticalCenterImageAndTitle:(CGFloat)spacing;
- (void)verticalCenterImageAndTitle; //默認(rèn)6.0
//左右居中,文字在左,圖片在右
- (void)horizontalCenterTitleAndImage:(CGFloat)spacing;
- (void)horizontalCenterTitleAndImage; //默認(rèn)6.0
//左右居中,圖片在左,文字在右
- (void)horizontalCenterImageAndTitle:(CGFloat)spacing;
- (void)horizontalCenterImageAndTitle; //默認(rèn)6.0
//文字居中,圖片在左邊
- (void)horizontalCenterTitleAndImageLeft:(CGFloat)spacing;
- (void)horizontalCenterTitleAndImageLeft; //默認(rèn)6.0
//文字居中,圖片在右邊
- (void)horizontalCenterTitleAndImageRight:(CGFloat)spacing;
- (void)horizontalCenterTitleAndImageRight; //默認(rèn)6.0
@end
- UIButton+ImageTitleStyle.m 文件
#import "UIButton+ImageTitleStyle.h"
@implementation UIButton (ImageTitleStyle)
#pragma mark - 上下居中,圖片在上,文字在下
- (void)verticalCenterImageAndTitle:(CGFloat)spacing
{
// get the size of the elements here for readability
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// lower the text and push it left to center it
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height + spacing/2), 0.0);
// the text width might have changed (in case it was shortened before due to
// lack of space and isn't anymore now), so we get the frame size again
titleSize = self.titleLabel.frame.size;
// raise the image and push it right to center it
self.imageEdgeInsets = UIEdgeInsetsMake(- (titleSize.height + spacing/2), 0.0, 0.0, - titleSize.width);
}
- (void)verticalCenterImageAndTitle
{
const int DEFAULT_SPACING = 6.0f;
[self verticalCenterImageAndTitle:DEFAULT_SPACING];
}
#pragma mark - 左右居中,文字在左,圖片在右
- (void)horizontalCenterTitleAndImage:(CGFloat)spacing
{
// get the size of the elements here for readability
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// lower the text and push it left to center it
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, 0.0, imageSize.width + spacing/2);
// the text width might have changed (in case it was shortened before due to
// lack of space and isn't anymore now), so we get the frame size again
titleSize = self.titleLabel.frame.size;
// raise the image and push it right to center it
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, titleSize.width + spacing/2, 0.0, - titleSize.width);
}
- (void)horizontalCenterTitleAndImage
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterTitleAndImage:DEFAULT_SPACING];
}
#pragma mark - 左右居中,圖片在左,文字在右
- (void)horizontalCenterImageAndTitle:(CGFloat)spacing;
{
// get the size of the elements here for readability
// CGSize imageSize = self.imageView.frame.size;
// CGSize titleSize = self.titleLabel.frame.size;
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, - spacing/2);
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, - spacing/2, 0.0, 0.0);
}
- (void)horizontalCenterImageAndTitle;
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterImageAndTitle:DEFAULT_SPACING];
}
#pragma mark - 文字居中,圖片在左邊
- (void)horizontalCenterTitleAndImageLeft:(CGFloat)spacing
{
// get the size of the elements here for readability
// CGSize imageSize = self.imageView.frame.size;
// CGSize titleSize = self.titleLabel.frame.size;
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, - spacing, 0.0, 0.0);
}
- (void)horizontalCenterTitleAndImageLeft
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterTitleAndImageLeft:DEFAULT_SPACING];
}
#pragma mark - 文字居中,圖片在右邊
- (void)horizontalCenterTitleAndImageRight:(CGFloat)spacing
{
// get the size of the elements here for readability
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// lower the text and push it left to center it
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, 0.0, 0.0);
// the text width might have changed (in case it was shortened before due to
// lack of space and isn't anymore now), so we get the frame size again
titleSize = self.titleLabel.frame.size;
// raise the image and push it right to center it
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, titleSize.width + imageSize.width + spacing, 0.0, - titleSize.width);
}
- (void)horizontalCenterTitleAndImageRight
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterTitleAndImageRight:DEFAULT_SPACING];
}
1. 上下居中,圖片在上,文字在下
[button verticalCenterImageAndTitle:10.0f];

2. 左右居中,文字在左,圖片在右
[button horizontalCenterTitleAndImage:10.0f];

3. 左右居中,圖片在左,文字在右
[button horizontalCenterImageAndTitle:10.0f];

4.5.
【文字居中,圖片在左邊】和【文字居中,圖片在右邊】這兩個(gè)方法顯示時(shí)還有點(diǎn)問(wèn)題。
不知道是不是設(shè)置了 Button 的 frame 使其有了固定大小的原因,先放著。
通過(guò)布局子視圖方法:
當(dāng) UIButton 是固定大小時(shí),使用上面的方法無(wú)法設(shè)置按鈕中的圖片相對(duì)于整個(gè)按鈕的大小。
- 圖片在上、文字在下
- (void) layoutSubviews {
[super layoutSubviews];
// 修改button內(nèi)image和label的位置
self.imageView.y = self.height * 0.15;
self.imageView.width = self.width * 0.5;
self.imageView.height = self.imageView.width;
self.imageView.centerX = self.width * 0.5;
self.titleLabel.x = 0;
self.titleLabel.y = self.imageView.bottom;
self.titleLabel.width = self.width;
self.titleLabel.height = self.height - self.imageView.bottom;
}
顯示/隱藏密碼按鈕
- (UIButton *)showPasswordButton {
if (!_showPasswordButton) {
_showPasswordButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_showPasswordButton setImage:[UIImage imageNamed:@"login_pwd_hide"]
forState:UIControlStateNormal];
[_showPasswordButton setImage:[UIImage imageNamed:@"login_pwd_show"]
forState:UIControlStateSelected];
[_showPasswordButton setSelected:NO];
[_showPasswordButton addTarget:self
action:@selector(showPasswordButtonDidClicked:)
forControlEvents:UIControlEventTouchUpInside];
}
return _showPasswordButton;
}
- (void)showPasswordButtonDidClicked:(id)sender {
self.passwordTextField.secureTextEntry = !self.passwordTextField.secureTextEntry;
[self.showPasswordButton setSelected:!self.passwordTextField.secureTextEntry];
}









