分享

iOS 的選單(menu)按鈕

 wintelsui 2023-02-18 发布于北京

iOS 的選單(menu)按鈕 — Pull Down Button & Pop Up Button

從 iOS 14 開始,我們可以更方便地製作選單按鈕,呈現類似下拉式選單的效果。

接下來我們將介紹兩種選單(menu)按鈕的實現方法。

  • Pull Down Button

點選按紐後將顯示選單,列出使用者可選擇的選項。

  • Pop Up Button

按鈕的標題顯示選單裡被選到的選項,被選到的選項將打勾(單選)。

點選後顯示選單的 Pull Down Button

將 UIButton 的 showsMenuAsPrimaryAction 設為 true,利用 UIMenu 製作選單,每個選項由 UIAction 產生。由於 UIButton 在 iOS 14 才有 property showsMenuAsPrimaryAction & menu,因此以下程式只支援 iOS 14 以上的版本。

class ViewController: UIViewController {   override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

let button = UIButton(type: .system)
button.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
button.setTitle("Edit", for: .normal)
view.addSubview(button)
button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
UIAction(title: "Select Messages", handler: { action in
print("Select Messages")
}),
UIAction(title: "Edit Pins", handler: { action in
print("Edit Pins")
}),
UIAction(title: "Edit Name and Photo", handler: { action in
print("Edit Name and Photo")
})
])
}}

點選 button 後將顯示選單,點選某個選項或是空白處都可關閉選單。

menu 出現的位置跟順序

依據 button 在畫面上的位置,menu 出現的位置跟順序也會有所不同。

  • 當 button 比較靠上面,點選 button 時選單將出現在 button 下方,選項的順序則跟 UIAction array 的順序一致。
  • 當 button 比較靠下面,點選 button 時選單將出現在 button 上方,選項的順序則跟 UIAction array 的順序相反。

包含圖片跟文字的 menu

menu 的選單除了文字,也可以透過 UIAction 的 image 參數加入圖片。

  • 顯示 SF Symbol 的圖片。
button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
UIAction(title: "Select Messages", image: UIImage(systemName: "checkmark.circle"), handler: { action in
print("Select Messages")
}),
UIAction(title: "Edit Pins", image: UIImage(systemName: "pin"), handler: { action in
print("Edit Pins")
}),
UIAction(title: "Edit Name and Photo", image: UIImage(systemName: "person.crop.circle"), handler: { action in
print("Edit Name and Photo")
})
])
  • 顯示 Assets 的彩色圖片。

asset 的圖片將自動縮小,不需要另外調整。

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
UIAction(title: "Select Messages", image: UIImage(named: "peter"), handler: { action in
print("Select Messages")
}),
UIAction(title: "Edit Pins", image: UIImage(systemName: "pin"), handler: { action in
print("Edit Pins")
}),
UIAction(title: "Edit Name and Photo", image: UIImage(systemName: "person.crop.circle"), handler: { action in
print("Edit Name and Photo")
})
])

menu 裡有 menu

如果選項很多,我們也可以在 menu 裡再加入另一層 menu。以下例子裡參數 children array 的前兩個是 UIAction,第三個是第二層的 menu。

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
UIAction(title: "Select Messages", image: UIImage(systemName: "checkmark.circle"), handler: { action in
print("Select Messages")
}),
UIAction(title: "Edit Pins", image: UIImage(systemName: "pin"), handler: { action in
print("Edit Pins")
}),
UIMenu(title: "Sort By", image: UIImage(systemName: "arrow.up.arrow.down"), children: [
UIAction(title: "Manual", handler: { action in
print("Manual")
}),
UIAction(title: "Due Date", handler: { action in
print("Due Date")
})
])
])

點選 Sort By 後將顯示第二層的 menu。

將 menu 裡選到的選項打勾

產生 UIAction 時,參數 state 傳入 .on 可讓選項打勾。若是想實現只有一個選項能打勾的單選效果,在 iOS 15 跟 14 有不同的做法。

  • iOS 15

產生 UIMenu 時在參數 options 傳入 .singleSelection,它會自己記得目前被選到的項目,然後將選到的項目打勾。

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(options: .singleSelection, children: [
UIAction(title: "Manual", state: .on, handler: { action in
print("Manual")
}),
UIAction(title: "Due Date", handler: { action in
print("Due Date")
})
])
  • iOS 14

我們必須自己記錄被選到的項目,然後在 UIAction 裡設定要打勾的選項。

利用分隔線將 menu 分組

當選項很多時,我們可以利用 separator 將 menu 分組,讓使用者知道某些選項是相關的項目。分組的方法是在 menu 裡加入 menu,然後讓第一層的 menu 選項跟第二層的 menu 選項同時顯示並用分隔線隔開,如此即可呈現下圖的 menu 分組效果。

以下程式產生第二層 menu 時參數 options 傳入 .displayInline,它將讓第一層的 menu 選項跟第二層的 menu 選項同時顯示並用分隔線隔開。

button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [
UIAction(title: "Select", handler: { action in
print("Select")
}),
UIAction(title: "New Folder", handler: { action in
print("New Folder")
}),
UIAction(title: "Scan Documents", handler: { action in
print("Scan Documents")
}),
UIAction(title: "Connect to Server", handler: { action in
print("Connect to Server")
}),
UIMenu(options: .displayInline, children: [
UIAction(title: "Icons", handler: { action in
print("Icons")
}),
UIAction(title: "List", handler: { action in
print("List")
})
])
])

Pop Up Button

除了點選後會顯示選單,Pop Up Button 多了以下功能:

  • 按鈕的標題將顯示選單裡被選到的選項。
  • 只能單選,被選到的選項將打勾。
  • 自動記得目前被選到的項目。

以下分別介紹 iOS 15 跟 14 的做法。

  • iOS 15

除了設定 button 的 showsMenuAsPrimaryAction & menu,還要將 changesSelectionAsPrimaryAction 設為 true。changesSelectionAsPrimaryAction 是 iOS 15 才有的 property,因此只支援 15 以上的版本。

class ViewController: UIViewController {   override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

let button = UIButton(type: .system)
button.frame = CGRect(x: 100, y: 100, width: 200, height: 100)
view.addSubview(button)
button.showsMenuAsPrimaryAction = true
button.changesSelectionAsPrimaryAction = true
button.menu = UIMenu(children: [
UIAction(title: "統一7-ELEVEn獅隊", state: .on, handler: { action in
print("統一7-ELEVEn獅隊")
}),
UIAction(title: "中信兄弟隊", handler: { action in
print("中信兄弟隊")
}),
UIAction(title: "樂天桃猿隊", handler: { action in
print("樂天桃猿隊")
}),
UIAction(title: "富邦悍將隊", handler: { action in
print("富邦悍將隊")
}),
UIAction(title: "味全龍隊", handler: { action in
print("味全龍隊")
})
])
}
}

如下圖所示,按鈕的標題隨著我們點選的選項更新。

  • iOS 14

我們必須自己寫程式實現 Pop Up Button 的功能,在點選選項時更新按鈕的標題。

將 menu 加到 UIBarButtonItem

剛剛的例子我們都是將 menu 加到 UIButton 上,其實它也可以加到 UIBarButtonItem。

  • Pull Down Button
class ViewController: UIViewController {   override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let menu = UIMenu(children: [
UIAction(title: "Select Messages", handler: { action in
print("Select Messages")
}),
UIAction(title: "Edit Pins", handler: { action in
print("Edit Pins")
}),
UIAction(title: "Edit Name and Photo", handler: { action in
print("Edit Name and Photo")
})
])
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", menu: menu)
}
}

記得要搭配 navigation controller,navigationItem 設定的 rightBarButtonItem 才會顯示。

  • Pop Up Button
class ViewController: UIViewController {   override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let menu = UIMenu(children: [
UIAction(title: "統一7-ELEVEn獅隊", state: .on, handler: { action in
print("統一7-ELEVEn獅隊")
}),
UIAction(title: "中信兄弟隊", handler: { action in
print("中信兄弟隊")
}),
UIAction(title: "樂天桃猿隊", handler: { action in
print("樂天桃猿隊")
}),
UIAction(title: "富邦悍將隊", handler: { action in
print("富邦悍將隊")
}),
UIAction(title: "味全龍隊", handler: { action in
print("味全龍隊")
})
])
let barButtonItem = UIBarButtonItem(menu: menu)
barButtonItem.changesSelectionAsPrimaryAction = true

navigationItem.rightBarButtonItem = barButtonItem
}
}

參考連結

Human Interface Guidelines 的 button 介紹。

Apple 官方範例 UIKit Catalog: Creating and Customizing Views and Controls

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多