開發 iOS App 的 Gesture (手勢)功能 — UIKit 版本

開發 iOS App 時,我們可以加入一些手勢操作帶給使用者更好的體驗,比方拖曳,縮放,旋轉,swipe 或長按的手勢。

但要怎麼寫程式辨識手勢呢? 別擔心,Apple 早為我們準備好了,iOS SDK 的 UIKit 提供多種辨識手勢的 Gesture Recognizer,如下圖所示,在 storyboard 的 Library 視窗輸入 gesture,即可看到多種常見手勢的 gesture recognizer。

接下來我們將以在圖片上左滑為例,利用 Swipe Gesture Recognizer 辨識左滑的手勢,

將 Swipe Gesture Recognizer 加到元件上

為了辨識手勢,第一步是將 Gesture Recognizer 加到想辨識手勢的元件上。

在此我們將 Swipe Gesture Recognizer 拖曳到 storyboard 畫面上的 image view。

如下圖所示,此時元件列表裡將長出 Swipe Gesture Recognizer。

從 gesture 元件上按右鍵選單,也可從 Referencing Outlet Collections 看到它連到了 image view 小小夜曲的 gestureRecognizers。

ps: 如果發現 gesture 的 Referencing Outlet Collections 沒有連到任何東西,表示手勢目前沒有作用在任何 view 上。

此時我們可手動將手勢加到 view 上,比方從下圖的 image view 連線到 gesture recognizer,然後點選 Outlet Collections 下的 gestureRecognizers。

將 image view 的 User Interaction Enabled 勾選

有些元件預設是不能操作的,就像 image view & label,他們預設都是只能顯示內容,觸碰時將毫無反應,就像冰山美人一樣。

不過冰山美人也有融化的一天,想讓 image view 觸碰有反應,能辨識到 swipe 手勢也是可以,只要我們要將它的 User Interaction Enabled 勾選。

設定手勢的相關欄位

每種 Gesture Recognizer 偵測不同的手勢,有著不同的設定,比方 swipe 手勢和方向有關,因此我們可指定辨識的方向。

有 Up,Down,Left,Right 四種方向可選擇。在此我們選擇 Left,表示要辨識向左滑動的手勢。

值得注意的,一個 Swipe Gesture Recognizer 只能辦識一個方向,因此若想辨識多個方向,必須使用多個 Swipe Gesture Recognizer。

連結手勢的 IBAction

從 storyboard 的 gesture recognizer 元件可以直接拉 IBAction,設定手勢辨識到時執行的 function。比方我們想要偵測到左滑時顯示下一頁的內容,因此連結 IBAction function showNextPage。

@IBAction func showNextPage(_ sender: Any) {

}

辨識兩種 swipe 方向的方法

方法 1: 加入兩個 Swipe Gesture Recognizer,分別連結不同的 IBAction function。

@IBAction func showNextPage(_ sender: Any) {

}

@IBAction func showPrevPage(_ sender: Any) {

}

方法 2: 加入兩個 Swipe Gesture Recognizer,連結到同一個 IBAction function。

@IBAction func changePage(_ sender: UISwipeGestureRecognizer) {
if sender.direction == .left {

} else if sender.direction == .right {

}
}

如果 gesture recognizer 沒有連結到元件

如下圖所示,如果 gesture recognizer 因為一些原因沒有連結到元件,我們也可以另外拉線連結。

我們可從 image view 拉線到 gesture recognizer。

然後選擇 gestureRecognizers。

從程式加入 gesture recognizer

除了從 storyboard 加入 gesture recognizer,我們也可以從程式加入,範例如下。

class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
@objc func changePage(_ sender: UISwipeGestureRecognizer) {

}

override func viewDidLoad() {
super.viewDidLoad()

let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(changePage(_:)))
swipeGestureRecognizer.direction = .left
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(swipeGestureRecognizer)
}
}

呼叫 function addGestureRecognizer(_:) 加入手勢。值得注意的,設定手勢觸發的 function 時必須使用 #selector( ) 的寫法,因為它跟 Objective-C 有關,因此觸發的 function 前要加上 @objc 。

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com