Button簡介
Button是一個使用者介面物件,在單擊時向目標傳送操作訊息。
本文介紹Cocoa提供的各種按鈕的不同之處以及如何使用它們。
Button是如何工作的
Button遵循target-action設計模式,它是一個使用者介面物件,在單擊時向目標傳送操作訊息。關於此設計模式的更多資訊,請檢視 Concepts in Objective-C Programming中的Target-Action
大多數按鈕的工作是由NSButtonCell處理的,一旦NSButtonCell的檢視被點選並捕獲到滑鼠按下的事件後,NSButtonCell的例項傳送它的動作訊息給目標物件,但是隻要滑鼠游標在Button cell內部並保持按下狀態也可以持續傳送動作訊息。Button cell的按壓狀態可以通過多種高亮方式顯示。比如,有邊框的按鈕單元格可以出現在螢幕上,或者在按下按鈕單元格時,影象或標題可以更改為另一種形式。
NSButtonCell物件必須使用NSControl子類的例項,如果你需要一個按鈕,如push按鈕,使用包含單個NSButtonCell
例項的NSButton
物件;如果需要一組相關的按鈕,例如一組開關或radio按鈕,則使用包含幾個NSButtonCell
NSMatrix
物件。
NSButton
和NSMatrix
都提供了一個控制檢視,然而,雖然NSMatrix要求您直接訪問NSButtonCell
物件,但是NSButton
的大多數方法對於NSButtonCell
中相同宣告的方法是“隱藏”的,(也就是說,NSButton方法的執行會自動為你呼叫相應的NSButtonCell方法,無需關心NSButtonCell的存在。)唯一沒有覆蓋的NSButtonCell
方法與用於顯示快捷鍵的字型以及高亮或顯示NSButton狀態的特定方法有關(最後這些通常與NSButton
的setButtonType:
方法一起設定)。
Button的型別
Button的型別決定了它的行為,當按壓時如何高亮顯示以及是否顯示其狀態,button的型別可以歸納為三類:
- 普通按鈕
- 粘性按鈕
- 單選按鈕及複選框
通過setButtonType設定按鈕型別。
普通按鈕
這些按鈕主要用於觸發動作,因為他們不顯示自己的狀態。這類按鈕在滑鼠按下時改變他們的顯示並且在滑鼠擡起時返回他們原始的狀態。
要讓
NSButton
控制按鈕被按下的外觀,使用NSMomentaryPushInButton
(在Xib的按鈕inspector中稱為“Mementary Push”),當滑鼠按下按鈕時,按鈕似乎是按進去的。這裡有一個
NSMomentaryPushInButton
按鈕的例子,帶有NSRoundedBezelStyle
風格的邊框,在正常和按下時的外觀:這是一個帶有
NSThickerSquareBezelStyle
樣式的NSMomentaryPushInButton
按鈕的例子。邊框樣式NSRegularSquareBezelStyle
和NSThickSquareBezelStyle
類似。
為了自己控制按鈕的外觀,使用NSMomentaryChangeButton(在Xib中稱為“Momentary Change”)。當滑鼠按鈕按下時,它將顯示為替換圖片和標題,當滑鼠釋放後,它將顯示為正常的圖片和標題。如果沒有設定替換圖片或者按鈕標題,它的外觀不會有任何變換。
粘性按鈕
此類按鈕顯示他們的狀態,並且在按下後似乎會粘住。點選一次後,它將會保持按下狀態直到下一次點選。
- 要讓
NSButton
控制按鈕被按下的外觀,使用NSPushOnPushOffButton(xib中稱為“Push On/Push Off”)。按鈕被按下後,按鈕似乎是按進去的,再次點選後按鈕彈起。彈出的外觀用於關閉狀態(NSOffState
),而壓入的外觀用於開啟狀態和混合狀態(NSOnState
和NSMixedState
)。這對於顯示應用程式中某些內容的狀態的按鈕(例如,顯示所選文字是否為黑體的按鈕)非常有用。 - 要控制按下按鈕的外觀,請使用
NSToggleButton
(在Interface Builder
的按鈕檢查器中稱為“切換”)。單擊一次後,按鈕會顯示它的替代影象和標題。再次單擊後,按鈕會顯示其正常的影象和標題。如果沒有替代的影象或標題,按鈕的外觀不會改變。正常的影象和標題表示off狀態(NSOffState
),備用的影象和標題表示on狀態和混合狀態(NSOnState和NSMixedState
)。這對於在兩個動作(例如,停止和開始)之間切換的按鈕非常有用。
如果想要一個按鈕顯示所有三種狀態的不同外觀,必須自定義NSButton。
單選按鈕及複選框
這些按鈕顯示應用程式中的狀態,它們是NSToggleButton
的特殊版本,具有系統定義的圖片。
- 要在兩個選項中進行選擇,請使用
NSSwitchButton
按鈕,它看起來像一個複選框。這種型別的按鈕可以在Interface Builder
中作為單獨的選項板使用。
- 要在兩個以上的選項中進行選擇,請使用
NSRadioButton
按鈕矩陣。矩陣和單選按鈕一起工作,以確保每次只打開一個按鈕。這種型別的按鈕可以在Interface Builder
中作為單獨的選項板項使用。
更改這些按鈕使用的影象可能會導致不可預測的結果,如果想要一個具有定製外觀的開關按鈕或單選按鈕,可以定製一個切換按鈕或自定義NSButton
。
雖然複選框和單選按鈕可以顯示所有三種狀態的不同影象,但其他型別的按鈕卻不能。
普通按鈕的使用
普通按鈕執行按鈕名所描述的動作,通常,它是一個圓角矩形,裡面包含了它的名字。例如,這個按鈕可能出現在一個對話方塊中,該對話方塊可以找到文件中的文字。
在Interface Builder
中建立按鈕是最簡單的。您還可以通過程式設計方式建立一個NSButton
例項,其型別為NSMomentaryPushInButton
、NSNoImage
的影象位置和NSRoundedBezelStyle
的邊框。
此類按鈕也可以是一個圖示按鈕,也就是說,這個按鈕主要由其圖示識別,很少或沒有文字。它是長方形的,像這樣:
您可以使用Interface Builder
或程式碼方式建立圖示按鈕。如果使用的是Interface Builder
,從一個普通的按鈕開始。如果您以程式碼方式建立它,那麼建立一個NSButton
例項,然後將其型別設定為NSMomentaryPushInButton
,其影象位置設定為NSImageOnly
,其邊框型別設定為正方形邊框型別。最後,設定影象為您想要的。
注意:文字按鈕上可以有一個小影象,圖示按鈕可以有一個標籤。最重要的問題是什麼最突出。如果是文字,將其視為文字按鈕。如果是影象,將其視為圖示按鈕。
您還可以有一個在兩個狀態之間切換的按鈕,每個狀態都有自己的標題和影象。例如,一個按鈕可以在開始和停止之間切換。您可以和使用Interface Builder
或程式碼建立普通按鈕相同的方式建立一個按鈕,只需將按鈕型別更改為NSToggleButton
。然後給按鈕一個可選標題和影象以及一個常規標題和影象。該按鈕首先顯示常規標題和影象,然後在使用者單擊後顯示替換的標題和影象。
使用複選框
一個複選框展示應用中的設定,複選框的另一個名字叫開關按鈕,用一行文字標識一個複選框。
使用NSButton的state屬性去設定一個複選框的狀態。可能的狀態為NSOnState、NSOffState和NSMixedState。如果按鈕是關閉的,則框是空的,反之,該框裡面有個對號;如果按鈕是混合狀態,則框裡有一個破折號。
標準複選框
Interface Builder
是建立複選框最簡單的方式。你也可以使用程式碼建立,繼承自NSButton
,其型別定義為NSSwitchButton
。
不同於一組單選按鈕,複選框中可以選擇多個選項。這組按鈕顯示所有選中的字元都是粗體,沒有斜體,還有一些是下劃線:
圖示複選框
你也可以有一個複選框,它是一個圖示按鈕;也就是說,這是一個主要由其圖示識別,很少或沒有文字,如果按鈕是關閉的,它似乎是突出的;如果按鈕是開著的,它似乎是按進去的。(圖片按鈕不能顯示混合狀態。)
您可以在Interface Builder
或程式碼中建立圖片複選框,如果您使用的是Interface Builder
,在普通按鈕的基礎上設定;如果以程式碼方式建立,則需要建立NSButton
的例項。然後通過將其型別設定為NSPushOnPushOffButton
、影象位置設定為NSImageOnly
、邊框型別設定為正方形型別來更改它,然後設定影象為你想要的即可。
單選按鈕
單選按鈕顯示應用程式中某些內容的設定,並且是一個組的一部分,其中一次只能有一個按鈕是開啟的,使用一組單選按鈕在幾個相互排斥的選項中進行選擇。
標準單選按鈕
標準的單選按鈕是一個小圓圈,後面跟著一行文字。如果按鈕關閉,圓圈是空的;如果按鈕是開啟的,圓圈被填充;如果按鈕是混合狀態,圓圈有一個破折號。
例如,這組按鈕顯示所有選中的物件都是綠色的:
這個組顯示部分選中的物件是紅色的,部分是綠色的:
一組單選按鈕由一個NSMatrix
物件實現,該物件包含幾個NSButtonCell
例項,並具有NSRadioModeMatrix
的跟蹤模式。每當單擊矩陣的某個按鈕時,矩陣就會關閉先前選擇的按鈕並開啟新單擊的按鈕。
在Interface Builder
中建立一組開關按鈕是最容易的。您還可以通過程式碼的方式建立一個NSMatrix
物件並初始化它(在呼叫initWithFrame:mode:prototype:numberOfRows:numberOfColumns:
),使用原型單元格和NSRadioModeMatrix
的跟蹤模式。對於原型物件,使用NSRadioButton
型別建立一個NSButtonCell
物件。清單1說明了如何進行此操作。
清單1:通過程式碼建立單選按鈕集
- (void)awakeFromNib {
NSButtonCell *prototype = [[NSButtonCell alloc] init];
[prototype setTitle:@"Watermelons"];
[prototype setButtonType:NSRadioButton];
NSRect matrixRect = NSMakeRect(20.0, 20.0, 125.0, 125.0);
NSMatrix *myMatrix = [[NSMatrix alloc] initWithFrame:matrixRect
mode:NSRadioModeMatrix
prototype:(NSCell *)prototype
numberOfRows:3
numberOfColumns:1];
[[[self window] contentView] addSubview:myMatrix];
NSArray *cellArray = [myMatrix cells];
[[cellArray objectAtIndex:0] setTitle:@"Apples"];
[[cellArray objectAtIndex:1] setTitle:@"Oranges"];
[[cellArray objectAtIndex:2] setTitle:@"Pears"];
}
圖示單選按鈕
單選按鈕也可以是一個圖示按鈕;也就是說,這是一個主要由其圖示識別,很少或沒有文字。如果按鈕是關閉狀態的,那麼它似乎是卡在裡面的;如果按鈕是開著的,它似乎是按進去的。(圖示按鈕不能顯示混合狀態。)
您可以在Interface Builder
或程式碼方式中建立一組圖示單選按鈕。如果您使用的是Interface Builder
請從一個普通按鈕開始;如果以程式碼方式建立,則建立一個按鈕矩陣。然後將矩陣的跟蹤模式改為NSRadioModeMatrix
。將按鈕的型別更改為NSPushOnPushOffButton
,它們的影象位置更改為NSImageOnly
,它們的邊框型別更改為正方形邊框型別。最後設定他們的圖片為你想要的。
查詢按鈕矩陣
一組單選按鈕或複選框以程式設計方式是一個NSMatrix
物件,其組成物件是NSButtonCell
物件。矩陣物件是一種特殊的控制元件。每個單元格都可以指定自己的目標物件和操作選擇器。另外,NSMatrix
可能有自己的目標和操作選擇器。(有關矩陣物件的目標操作的更多資訊,請參閱矩陣程式設計指南。)
要找到使用者選擇的單選按鈕或複選框(在使用者單擊時),可以為矩陣中的每個單元格指定目標和不同的操作選擇器,然後實現相應的操作方法。然而,在單選按鈕或複選框矩陣中查詢當前選擇的更有效的方法是為NSMatrix
物件本身實現目標操作,並且在操作方法中確定現在選擇了哪個單元(或單元)。這個的NSMatrix
方法是selectedCell
和selectedCells
。
清單1展示了一個action方法的實現,該方法響應單選按鈕矩陣中的選擇。
清單1 查詢所選的radio-button單元格的矩陣物件
- (IBAction)findSelectedButton:(id)sender { // sender是一個矩陣物件
NSButtonCell *selCell = [sender selectedCell];
NSLog(@"Selected cell is %d", [selCell tag]);
}
這個程式碼片段說明了在處理矩陣中的單元格選擇時可以應用的另一種技術。可以為矩陣中的每個單元格分配數字標記來識別它,然後在處理選擇時查詢這些標記值。
設定按鈕邊框的外觀
可以通過改變按鈕的形狀和陰影來控制它的邊框。注意,如果isborder
返回NO
,則邊界不會出現。使用setborder:
改變它的值。
要更改邊框的形狀,請使用setBezelStyle:
改變按鈕的邊框型別。有兩大類邊框型別。
- 如果您的按鈕主要通過文字標識,那麼使用
NSRoundedBezelStyle
。它為文字按鈕使用適當的邊框樣式,它是一個圓角矩形,如下所示:
- 如果您的按鈕主要由圖示標識,那麼使用
NSRegularSquareBezelStyle
,NSThickSquareBezelStyle
或NSThickerSquareBezelStyle
。這些型別使用帶有邊框的矩形按鈕。小樣式具有2畫素的邊框;中等樣式有3畫素的邊框;大樣式有4畫素的邊框。三種類型如下所示:
設定按鈕標題
一個按鈕可以有兩個與之相關的標題:普通標題和交替標題。如果按鈕型別是NSMomentaryPushInButton
、NSPushOnPushOff
按鈕、NSMomentaryLightButton
或NSOnOffButton
,則只顯示正常的標題。如果按鈕型別是NSMomentaryChangeButton
或NSToggleButton
,則當按鈕的狀態為off (NSOffState
)時將顯示正常標題,當按鈕的狀態為on
或mixed
(NSOnState
)時將顯示備用標題。或NSMixedState
)。如果你想要一個按鈕顯示所有三種狀態的不同標題,你必須子類化NSButton
。
如果希望標題包含純文字,請使用setTitle:
設定普通標題和setAlternateTitle:
設定備用標題。如果希望標題包含樣式文字(例如,斜體或粗體),請使用setAttributedTitle:
和setAttributedAlternateTitle:
。
要設定標題相對於按鈕影象的定位方式,使用setImagePosition:
,在設定按鈕影象中描述。如果沒有圖片,標題將在按鈕內水平和垂直居中。如果標題位於影象的上方、下方或重疊部分,則標題將在按鈕內水平居中。要隱藏標題,使用setImagePosition:
帶有NSImageOnly
的引數。
要設定標題的字型,傳送setFont:
到按鈕的按鈕單元格。
如果想讓按鈕在滑鼠移動到標籤上時顯示其標題,需要使用Tool Tips
。
設定按鈕圖示
一個按鈕可以有兩個與之相關聯的影象:普通影象和交替影象。如果按鈕型別是NSMomentaryPushInButton
、NSPushOnPushOff
按鈕、NSMomentaryLightButton
或NSOnOffButton
,則只顯示正常的影象。如果按鈕型別為NSMomentaryChangeButton
或NSToggleButton
,則正常影象在按鈕狀態為off
時顯示(NSOffState
),而備用影象在按鈕狀態為on
或mixed
(NSOnState
)時顯示。或NSMixedState
)。如果你想要一個按鈕顯示所有三種狀態的不同影象,你必須子類化NSButton
。(儘管開關按鈕和單選按鈕可以顯示所有三種狀態的不同影象,但這個功能沒有公共介面。)
要設定正常的影象,使用setImage:
。要設定備用映像,使用setAlternateImage:
。
注意:如果按鈕是複選框或單選按鈕,不要改變其影象。這些按鈕的影象是系統定義的,更改它們可能導致不可預知的結果。如果您想要一個具有定製外觀的開關按鈕或單選按鈕,可以定製一個切換按鈕(型別為NSToggleButton的按鈕)或NSButton子類。
要為按鈕的影象設定位置,使用setImagePosition:
,下面的值之一。預設是NSNoImage
NSNoImage | NSImageOnly | NSImageOverlaps |
NSImageLeft | NSImageRight | |
NSImageBelow | NSImageAbove |
隱藏按鈕
有兩種方法可以從檢視中隱藏按鈕:它可以是完全透明的,也可以只在滑鼠經過它時才顯示它的邊框。
- 要使按鈕透明,使用
setTransparent:
。一個透明的按鈕跟蹤滑鼠併發送它的動作,但不繪製自己。這對於將螢幕上的區域敏感化非常有用,這樣當該區域收到滑鼠單擊時,操作就會發送到目標。 - 要讓一個按鈕顯示其邊框,只有當它處於活動狀態並且滑鼠在它上面時,才可以使用
setshowsborderonly
目地:。其餘的按鈕的元件總是繪製。下面是一些按鈕的例子,這些按鈕只在滑鼠移動到它們上面時才顯示它們的邊框:
設定按鈕為預設樣式
如果按鈕具有NSRoundedBezelStyle
邊框型別,您可以將其標記為預設按鈕。預設按鈕是選中樣式的,當用戶按下Return
時呼叫其操作訊息。它看起來像這樣:
若要將按鈕標記為預設值,用 setKeyEquivalent:
方法將其快捷鍵設定為Return
。
[myButton setKeyEquivalent:@"\r"];
可以在Interface Builder
中設定快捷鍵,預設按鈕有一個在它周圍繪製的粗輪廓,在按鈕的邊界之外,介面設計應該考慮到額外的空間。
設定按鈕快捷鍵
一個按鈕可以有一個等效的鍵,這樣當用戶按下那個鍵時,按鈕就會響應,就好像它已經被點選過一樣。
注意,如果將按鈕的快捷鍵設定為Return
,該按鈕將成為預設按鈕。
通常在Interface Builder
中設定一個按鈕的快捷鍵。為此,選擇按鈕並開啟檢查器的attributes
窗格。顯示按鈕的屬性,單擊鍵Equiv
欄位,並鍵入要與按鈕相關聯的鍵或鍵組合。(按“清除”鍵可以刪除等效鍵。)
要在程式中設定快捷鍵,可以使用setKeyEquivalent:
並傳入相應的字元即可。例如,設定Return
為該按鈕的快捷鍵:
[myButton setKeyEquivalent:@"\r"];
要將按鈕的鍵值設定為非列印字元,可以使用NSResponder
定義的鍵常量,如下例所示,它將按鈕的鍵值設定為左箭頭鍵。
unichar arrowKey = NSLeftArrowFunctionKey;
[button setKeyEquivalent:[NSString stringWithCharacters:&arrowKey length:1]];
子類化NSButton
如果建立了一個NSButton
的子類來執行它自己的初始化,覆蓋指定的初始化器(NSView
的initWithFrame:
方法)。如果想在NSButton
的子類中使用自定義NSButtonCell
子類,必須重寫cellClass:
方法。