UIButton

對(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í)不顯示高亮。 該類的其他屬性,如adjustImageWhenHighlightedadjustImageWhenDisabled屬性,可以在特定情況下更改默認(rèn)行為。

內(nèi)容

按鈕的內(nèi)容由你指定的標(biāo)題字符串或圖像組成。你指定的內(nèi)容是用于配置被按鈕所擁有的 UILabelUIImageView 對(duì)象。你可以使用 titleLabelimageView 屬性配置這些對(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、titleEdgeInsetsimageEdgeInsets屬性訪問(wèn)這些值。

有關(guān)按鈕的繼承的 Interface Builde r屬性的信息,參閱 UIControlUIView。

國(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
通知所有事件。

userInteractionEnabledenabled 的區(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ì)。
  • enabledUIControl的屬性(雖然UIButtonUICotrol的子類,但是這兩個(gè)方法都能用,因?yàn)?code>UICotrol 又是 UIView 的子類),而userInteractionEnabledUIView、UIImageViewUILabel的屬性。
  • 如果使用時(shí),同時(shí)設(shè)置了這兩個(gè)方法,那么,先設(shè)置的方法奏效。

關(guān)于 tintColor

tintColoriOS7.0 引入的一個(gè) UIView 的屬性,該屬性會(huì)設(shè)置按鈕圖片和文本的顏色。

tintColor 具有 繼承重寫、傳播 的特點(diǎn)。

  • 繼承:只要一個(gè) UIView 的 subview 沒(méi)有明確指定 tintColor,那么這個(gè) UIViewtintColor 就會(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 為止。

    ——UIView并沒(méi)想的那么簡(jiǎn)單 - 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 圓角:

  1. 工具區(qū)域 → Attribute inspector → View 勾選 Clip To Bounds

  2. 工具區(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控制的是UIButtonimagetitle在豎直方向的對(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ì)齊方式。其值有leftright、centerfill。當(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];
}

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、簡(jiǎn)介 <<UIButton(按鈕) : 既能顯示文字,又能顯示圖片,還能隨時(shí)調(diào)整內(nèi)部圖片和文字的位置,實(shí)現(xiàn)了監(jiān)...
    無(wú)邪8閱讀 5,778評(píng)論 0 2
  • 一個(gè)UIButton的實(shí)例變量, 使一個(gè)按鈕(button)在觸摸屏上生效。一個(gè)按鈕監(jiān)聽(tīng)觸摸事件,當(dāng)被點(diǎn)擊時(shí),給目...
    wushuputi閱讀 1,652評(píng)論 0 1
  • 【譯】為避免撕逼,提前聲明:本文純屬翻譯,僅僅是為了學(xué)習(xí),加上水平有限,見(jiàn)諒! UIButton 控制你自定義代碼...
    singmiya閱讀 1,110評(píng)論 1 0
  • 介紹:UIButton的類是一個(gè)UIControl子類,它實(shí)現(xiàn)了在觸摸屏上的按鈕。觸摸一個(gè)按鈕攔截事件和動(dòng)作消息發(fā)...
    木木小林醬閱讀 649評(píng)論 0 2
  • 正在寫稿的時(shí)候,耳朵近旁有“嗡嗡”之聲,間以“得得”之聲。因?yàn)槲乃颊龝晨欤还芸粗P底下,無(wú)暇抬頭來(lái)探究這是什么聲...
    查無(wú)此名閱讀 221評(píng)論 0 0

友情鏈接更多精彩內(nèi)容