macOS 開發(fā)-NSButton

Button是一個用戶界面對象,單擊該按鈕即可將操作消息發(fā)送到目標。它的大部分工作都由NSButtonCell處理,當NSButtonCell實例被單擊時,捕獲到鼠標按下事件,實例會將動作消息發(fā)送到其目標。

按鈕類型

cocoa為NSButton實現(xiàn)很多不同類型,按鈕類型決定按鈕的行為,按鈕類型分為三類:

  • 按下按鈕
  • 粘性按鈕
  • 單選按鈕和復選框

我們可以通過setButtonType:方法來設(shè)置按鈕類型:

lazy var button: NSButton = {
    let button = NSButton()
    button.setButtonType(.pushOnPushOff)
    return button
}()

按下按鈕

按下按鈕對于觸發(fā)操作最有用,因為它們不顯示其狀態(tài)。點擊時,它們會更改其外觀;取消點擊時,則會恢復原始外觀。

01.jpg

我們可以通過設(shè)置Button的Type為NSButtonTypeMomentaryPushIn來設(shè)置成按下按鈕:

lazy var button: NSButton = {
    let button = NSButton(title: "button", target: self, action: #selector(click))
    button.setButtonType(.momentaryPushIn)
    button.frame = NSRect(x: 18, y: 100, width: 70, height: 25)
    return button
}()

要控制自己按下按鈕的外觀,可使用NSMomentaryChangeButton。按下鼠標按鈕時,它將顯示替代圖像和標題。釋放鼠標按鈕時,它將顯示正常圖像和標題。如未設(shè)置,則其外觀不會改變:

lazy var button1: NSButton = {
    let button = NSButton()
    button.setButtonType(.momentaryChange)
    button.title = "button"
    button.alternateTitle = "Change"
    button.bezelStyle = .regularSquare
    button.frame = NSRect(x: 18, y: 100, width: 70, height: 25)
    return button
}()

粘性按鈕

粘性按鈕在按下時保留狀態(tài)。點擊一個后,它會保存按下狀態(tài),直到下次點擊恢復。我們可以通過設(shè)置Button的Type為NSPushOnPushOffButton來設(shè)置成按下按鈕:

lazy var onOrOffButton: NSButton = {
    let button = NSButton()
    button.setButtonType(.pushOnPushOff)
    button.title = "button"
    button.frame = NSRect(x: 210, y: 70, width: 70, height: 25)
    button.bezelStyle = .rounded
    return button
}()

我們可以通過state屬性獲取按鈕的狀態(tài),判斷按鈕是否已經(jīng)被選中。對于這個粘性按鈕,對于顯示應(yīng)用程序中某些內(nèi)容的狀態(tài)(例如:Office Word 中是否為粗體的按鈕)很有用。

要控制自己粘性按鈕的外觀,可使用NSToggleButton。點擊一個后,它將顯示替代圖像和標題。直到下次點擊恢復時,它將顯示正常圖像和標題。如未設(shè)置,則其外觀不會改變。用于兩個狀態(tài)(例如,“停止”和“開始”)之間切換有效:

lazy var toggleButton: NSButton = {
    let button = NSButton()
    button.action = #selector(click)
    button.setButtonType(.toggle)
    button.title = "start"
    button.alternateTitle = "stop"
    button.frame = NSRect(x: 290, y: 70, width: 70, height: 25)
    button.bezelStyle = .regularSquare
    return button
}()

單選按鈕和復選框

單選按鈕和復選框主要是區(qū)分某些內(nèi)容的狀態(tài),它們是NSToggleButton系統(tǒng)定義圖標的專用版本。

復選框是可以在多個選項中選擇多項,Button通過設(shè)置類型為NSButtonTypeSwitch,讓它看起來像一個復選框:

02.jpg

實現(xiàn)代碼如下:

lazy var switchBtnView: NSView = {
    let v = NSView(frame: NSRect(x: 70, y: 90, width: 80, height: 200))
    let b1 = NSButton(title: "紅色", target: self, action: #selector(click))
    b1.setButtonType(.switch)
    b1.frame = NSRect(x: 5, y: 100, width: 70, height: 25)
    v.addSubview(b1)

    let b2 = NSButton(title: "綠色", target: self, action: #selector(click))
    b2.setButtonType(.switch)
    b2.frame = NSRect(x: 5, y: 130, width: 70, height: 25)
    v.addSubview(b2)

    let b3 = NSButton(title: "藍色", target: self, action: #selector(click))
    b3.setButtonType(.switch)
    b3.frame = NSRect(x: 5, y: 160, width: 70, height: 25)
    v.addSubview(b3)
    return v
}()

單選按鈕是可以在多個選項中選擇一項,我們可能通過將多個Button類型設(shè)置為NSButtonTypeSwitch,并將它們加在同一個superview,達到多苦單選的效果:

03.jpg

實現(xiàn)代碼如下:

lazy var radioBtnView: NSView = {
    let v = NSView(frame: NSRect(x: 70, y: 90, width: 80, height: 200))
    let b1 = NSButton(title: "紅色", target: self, action: #selector(click))
    b1.setButtonType(.radio)
    b1.frame = NSRect(x: 5, y: 100, width: 70, height: 25)
    v.addSubview(b1)

    let b2 = NSButton(title: "綠色", target: self, action: #selector(click))
    b2.setButtonType(.radio)
    b2.frame = NSRect(x: 5, y: 130, width: 70, height: 25)
    v.addSubview(b2)

    let b3 = NSButton(title: "藍色", target: self, action: #selector(click))
    b3.setButtonType(.radio)
    b3.frame = NSRect(x: 5, y: 160, width: 70, height: 25)
    v.addSubview(b3)
    return v
}()

按鈕的使用

處理點擊事件

我們可以通過action屬性給按鈕設(shè)置處理點擊事件,同時也可以設(shè)置target來指定處理對象:

lazy var toggleButton: NSButton = {
    let button = NSButton()
    button.action = #selector(click)
    button.title = "start"
}()

@objc private func click(_ sender: NSButton) {
    print("click button")
}

設(shè)置邊框的外觀

我們可以通過更改按鈕的形狀和陰影來控制按鈕的邊框。通過設(shè)置isBordered來控制是否顯示 邊框。如若要改邊框的形狀,請使用更改按鈕的邊框類型bezelStyle:。邊框類型有兩個主要類型:

  1. 如果您的按鈕主要由文本標識,請使用NSRoundedBezelStyle。它為文本按鈕使用適當?shù)倪吙驑邮剑@是一個圓角矩形;
  2. 如果您的按鈕主要是鑒定一個圖標,使用NSRegularSquareBezelStyleNSThickSquareBezelStyleNSThickerSquareBezelStyle

設(shè)置按鈕的標題

按鈕可以具有兩個與之關(guān)聯(lián)的標題:正常和交替。如果按鈕類型NSMomentaryPushInButtonNSPushOnPushOffButtonNSMomentaryLightButton,或者NSOnOffButton,是不斷顯示只有正常稱號。如果按鈕類型為NSMomentaryChangeButtonNSToggleButton,則在按鈕狀態(tài)為關(guān)閉(NSOffState)時顯示普通標題,

如果標題只包含純文本,使用setTitle:或setAlternateTitle:設(shè)置標題。如果希望標題包含樣式文本,則使用setAttributedTitle:setAttributedAlternateTitle:設(shè)置標題。

如果要設(shè)置標題的字體,可使用setFont:按鈕標題的字體。

設(shè)置按鈕的圖像

一個按鈕可以具有兩個與之關(guān)聯(lián)的圖像:正常和交替。如果按鈕類是NSMomentaryPushInButtonNSPushOnPushOffButtonNSMomentaryLightButton,或NSOnOffButton,只會顯示正常圖像。如果按鈕類型為NSMomentaryChangeButtonNSToggleButton,則在按鈕狀態(tài)為關(guān)閉(NSOffState)時顯示正常圖像。

注意: 如果按鈕是復選框或單選按鈕,請勿更改其圖像。這些按鈕的圖像是系統(tǒng)定義的,更改它們可能會導致不可預(yù)測的結(jié)果。

如果要設(shè)置按鈕圖像的位置,請使用imagePosition,并使用以下值之一。默認是noImage,具體作用如下:

public enum ImagePosition : UInt {
    case noImage    // 沒有圖片
    case imageOnly  // 只有圖片
    case imageLeft  // 左圖右文
    case imageRight // 左文右圖
    case imageBelow // 上文下圖
    case imageAbove // 上圖下文
    case imageOverlaps // 底層圖,上層文,重疊
    @available(OSX 10.12, *)
    case imageLeading
    @available(OSX 10.12, *)
    case imageTrailing
}

隱藏按鈕

按鍵鈕有兩種隱藏視圖的方法:使它完全透明的,或者僅當鼠標懸停在其上方時才可以顯示其邊框。

  • 若要使按鈕透明,請使用isTransparent。透明按鈕可跟蹤鼠標并發(fā)送其動作,但不會自行繪制。

  • 若要在按鈕處于活動狀態(tài)或鼠標懸停在其上方時才顯示其邊框,請使用showsBorderOnlyWhileMouseInside

默認按鈕

當按鈕設(shè)置為默認按鈕。當用戶按下Return鍵時,默認按鈕會跳動,并調(diào)用其操作消息。若要將按鈕標記為默認按鈕,請將其keyEquivalent設(shè)置為Return ,如下所示:

button.keyEquivalent = "\r"

默認按鈕周圍有一個粗略的輪廓,位于按鈕的邊框之外。界面設(shè)計時應(yīng)考慮到額外的空間。

等效鍵

按鈕可以設(shè)置一個等效的鍵,當用戶按下該鍵時,該按鈕的響應(yīng)與被點擊一樣。需要注意,如果將鍵設(shè)置為等效于Return,則該按鈕將成為默認按鈕。

我們可以通過keyEquivalent來設(shè)置等效鍵。例如,要將其設(shè)置為Return,則可使用:

button.keyEquivalent = "\r"

若要將按鈕的鍵設(shè)置為等效于非打印字符,可以使用由定義的鍵常數(shù),如以下示例所示,該常數(shù)將按鈕的鍵設(shè)置為等效于左箭頭鍵:

var array = [unichar(NSLeftArrowFunctionKey)]
button.keyEquivalent = NSString(characters: array, length: 1) as String

小結(jié)

NSButton相對iOS中的UIButton會更強大,功能也更復雜,在macOS開發(fā)中用得最多的組件之一。在接下來的一節(jié)我們來聊聊NSImageView。完整的源碼請訪問這里:https://github.com/dengyhgit/macOS-Dev-Demo/tree/master/NSButton, 如對你有幫忙,別忘點亮小??。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,690評論 2 370

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