Cơ bản về UIGestureRecognizer

UIGestureRecognizer là gì?

Nếu lúc bạn là người mới có tới mức có thể làm ra app Hello world 😃) thì chắc hẳn các bạn cũng đã biết về UIButton, nó có thể bắt được sự kiện khi ta tap vào nó nhưng đôi khi ta cần bắt được các sự kiện với các cử chỉ như kéo, vuốt, quay.... thì một trong những cách đơn giản nhất là dùng UIGestureRecognizer. Nó là một class hỗ trợ khá đầy đủ và dễ sử dụng trong các trường hợp này.

Mình cũng giới thiệu sơ qua luôn là các bài của mình hướng tới đối tượng chỉ biết kiến thức cơ bản về Swift (và mình cũng chỉ biết kiến thức cơ bản về Swift =)) ). Nên mình sẽ cố gắng viết lại rõ ràng sao cho ngay cả khi bạn chưa từng thực sự biết về nó cũng hiểu được - Dĩ nhiên là trước đó bạn phải biết ngôn ngữ Swift :v ).

UIGestureRecognizer dùng để làm gì?

Nếu bạn cần nhận dạng cử chỉ trong app (chạm ngắn, chạm dài, vuốt ngang, vuốt dọc, quay, kéo...) để làm một chức năng nào đó thì việc sử dụng UIGestureRecognizer là một cách đơn giản. Trong hướng dẫn này, bạn sẽ được học cách thêm một hoặc nhiều loại gesture recognizers (nhận dạng cử chỉ) vào trong app của bạn. Vd ở bài này là một app có hình con khỉ và quả chuối, bạn sẽ học cách dùng gesture recognizers để kéo, phóng to, thu nhỏ và quay.

UIPanGestureRecognizer

Trước hết bạn có thể tải demo này về: Download Mở Main.storyboard. Bên trong Object Library, hãy tìm Pan Gesture Recognizer, sau đó kéo nó vào image con khỉ trong view. Điều này sẽ tạo ra pan gesture recognizer, và liên kết nó với hình con khỉ.

Bạn có thể kiểm tra lại chúng đã thật sử liên kết chưa bằng cách click vào hình con khỉ, quan sát Connections Inspector (View Menu > Utilities > Show Connections Inspector), và chắc chắn rằng trong Pan Gesture Recognizer có trong gestureRecognizers Outlet Collection. Lưu ý: Từ lúc bắt đầu demo đã liên kết hình Khỉ với Pinch Gesture RecognizerRotation Gesture Recognizer cho bạn. Nó cũng đã kết nối hình quả chuối với Pan Gesture Recognizer, Pinch Gesture RecognizerRotation Gesture Recognizer cho bạn.

Lưu ý: là ở trên tôi đã ném 3 loại Gesture Recognizer vào hình khỉ và hình chuối vì tôi muốn chỉ khi mình tác động (kéo, vuốt, quay...) lên hình con khỉ hoặc quả chuối thì nó mới hoạt động, còn khi bạn tác động lên view bên ngoài (cái view chứa luôn hình con khỉ với quả chuối) thì nó sẽ không có phản ứng gì (Nếu bạn muốn view ngoài cũng nhận được sự kiện thì chỉ cần kéo các Gesture Recognizer tương ứng vào View là đươc :> ).

Mở ViewController.swift và thêm function dưới vào phía trên viewDidLoad()

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
  let translation = recognizer.translation(in: self.view)
  if let view = recognizer.view {
    view.center = CGPoint(x:view.center.x + translation.x,
                            y:view.center.y + translation.y)
  }
  recognizer.setTranslation(CGPoint.zero, in: self.view)
}

UIPanGestureRecognizer sẽ gọi hàm này khi ta kéo hình ảnh. Bây giờ bạn cần liên kết action này với cái Pan Gesture Recognizer.

Lưu ý là trong hình trên có 2 pan tương ứng với ảnh khỉ và ảnh chuối. Nếu bạn muốn bức ảnh nào di chuyển được khi kéo thì liên kết nó với action handlePan(recognizer:). Ở đây tôi sẽ ví dụ hình khỉ trước. Để kiểm tra lại chúng đã được kết nối chưa bạn có thể chọn Connections Inspector, xem thử Pan Gesture Recognizer có giống hình bên dưới không: Hiện tại: nếu bạn chạy app vẫn sẽ không thấy chúng hoạt động. Nguyên nhân chủ yếu là do mặc định của UIImage khi ta kéo thả vào nó sẽ không bắt các sự kiện chạm vào chúng :v . Mở Attributes Inspector và click vào User Interaction Enabled. Bây giờ hãy chạy thử app, nếu tất cả đều đúng thì bạn có thể kéo chú khỉ di chuyển được rồi đấy 😃). Hãy kéo thử quả chuối (ở trong ví dụ của tôi và nếu bạn làm đúng như tôi lúc ở trên) thì bạn sẽ thấy chúng không thể di chuyển được. Nguyên nhân là như để đề cập ở trước đó, tôi chưa liên kết action handlePan(recognizer:) với hình quả chuối. Bây giờ nếu bạn muốn chúng hoạt động thì chỉ cần làm lại các bước trước đó (liên kết action và mở kích hoạt User Interaction Enabled).

Pinch and Rotation Gestures

Bây giờ chúng ta sẽ làm lại tương tự đới với viẹc phóng to, thu nhỏ và quay hình khỉ, hình chuối.

Trong file ViewController.swift thêm vào hàm sau handlePinch(recognizer:):

if let view = recognizer.view {
  view.transform = view.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
  recognizer.scale = 1
}

và hàm quay, handleRotate(recognizer:):

if let view = recognizer.view {
  view.transform = view.transform.rotated(by: recognizer.rotation)
  recognizer.rotation = 0
}

Nhớ lại các công việc làm làm ở trên là liên kết action và kích hoạt tính năng và chạm (không cần làm bước kích hoạt khi chạm vì ta đã làm ở lúc đầu rồi) Bây giờ bạn mở Main.storyboard và làm các bước sau:

  1. Liên kết action handlePinch(recognizer:) với Pinch của hình khỉ và chuối).
  2. Liên kết action handleRotate(recognizer:) với Rotation của hình khỉ và chuối). Nếu bạn làm đúng, thì màn hình kết nối của bạn sẽ như hình bên dưới:

Build va run app. bạn sẽ thấy chúng hoạt động như thế này: Nếu bạn hoạt động trên mày ảo thì bạn có thể test bằng cách giữ im nút option và kéo bằng 2 ngón tay (Phóng To) và giữ im nút shift và option (Quay). link tham khảo: https://www.raywenderlich.com/162745/uigesturerecognizer-tutorial-getting-started