在 Web 應用中,我們常常會看到畫面的右下角會提供一個按鈕,點下去後會展開更多的按鈕,用來提供一些功能(例如分享到 Facebook/Line/Weibo)
這次要在 iOS 中實現這個功能。
藍色的按鈕負責顯示/隱藏其餘的四個按鈕。
為了讓這個折疊式按鈕可以被 reuse ,這裡建立一個繼承於 UIView 的 SKExpandableView.
排版的時候我們從上到下依次放入按鈕,功能按鈕通過一個 Array 來保管,藍色按鈕命名為 baseButton
並且給每個按鈕加入 touchUpInside
事件
private func setupButtons() {
for i in 0..<imageNames.count {
let name = imageNames[i]
let button = UIButton(frame: CGRect(x: 0, y: 44 * i , width: 44, height: 44))
button.setImage(UIImage(named:name), for: .normal)
button.tag = i + 1
button.addTarget(self, action: #selector(buttonTapHandler(button:)), for: .touchUpInside)
addSubview(button)
buttons.append(button)
}
baseButton.frame = CGRect(x: 0, y: 44 * 4, width: 44, height: 44)
baseButton.setImage(UIImage(named:"icon-base"), for: .normal)
baseButton.addTarget(self, action: #selector(buttonTapHandler(button:)), for: .touchUpInside)
baseButton.tag = 0
addSubview(baseButton)
}
負責處理每個按鈕 touchUpInside 事件的方法:
@objc private func buttonTapHandler(button:UIButton) {
DispatchQueue.main.async {
switch(button.tag){
case 0: self.switchMenu()
case 1: self.delegate?.didTapExpandable(button: .book)
case 2: self.delegate?.didTapExpandable(button: .box)
case 3: self.delegate?.didTapExpandable(button: .camera)
case 4: self.delegate?.didTapExpandable(button: .card)
default: break
}
}
}
當 baseButton 被點下的時候,就會執行 switchMenu 方法,將功能性的按鈕通過動畫來隱藏或顯示。
private func switchExpandableStackView() {
UIView.animate(withDuration: 0.3, animations: {
_ = self.buttons.map{
($0.alpha == 0) ? ($0.alpha = 1) : ($0.alpha = 0)
}
})
}
通過建立 Delegate 來讓調用者能夠得知哪一個功能性的按鈕觸發了 touchUpInside 事件
enum SKExpandableButtonType {
case card
case camera
case box
case book
}
protocol SKExpandableViewDelegate {
func didTapExpandable(button:SKExpandableButtonType)
}
在 HomeViewController 中加入 SKExpandableView 並設定 delegate 方法
private func setupView() {
let screenSize = UIScreen.main.bounds
let menu = SKExpandableView(frame: CGRect(x: screenSize.width - 50, y: screenSize.height - 400, width: 44, height: 220))
menu.delegate = self
view.addSubview(menu)
}
實作 delegate 方法
extension HomeViewController: SKExpandableViewDelegate {
func didTapExpandable(button:SKExpandableButtonType) {
switch button {
case .card: showMessage("did tap card")
case .camera: showMessage("did tap camera")
case .box: showMessage("did tap box")
case .book: showMessage("did tap book")
}
}
}
當 SKExpandableView 中的功能性按鈕觸發 touchUpInside 事件的時候跳出提示
private func showMessage(_ message:String) {
let alertController = UIAlertController(title: "Message", message: message, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(action)
present(alertController, animated: true, completion: nil)
}
請教一下
各篇文章中的手機畫面(video as .gif)
是用什麼工具/方式製作的?
如果你是用 mac 的話,可以試試看 LICEcap 這個工具
我是用 mac
個人習慣不需要用到返回值會用foreach
_ = self.buttons.map{
($0.alpha == 0) ? ($0.alpha = 1) : ($0.alpha = 0)
}
2018唯一支持陳董
粉絲大人說得好