Contents
Chào bạn, chúng ta lại tiếp tục với seri học iOS cơ bản. Bài này sẽ hướng dẫn thêm cách lấy sự kiện người dùng.
Ở bài trước thì ta đã tìm hiểu về IBAction, nhưng nó sử dụng được với một vài UI Control cơ bản. Hôm nay, ta sẽ tìm hiểu tiếp về Touch Event và dùng được cho tất cả các loại UIView.
Touch Event
- Chỉ là tên gọi chung có các loại sự kiện cảm ứng mà người dùng tác động vào giao diện của ứng dụng
- IBAction chỉ là 1 trường hợp riêng của nó.
- Thuộc class UIResponder
- Cả UIWindow & UIView đều kế thừa nó
- Tất cả các view hay sub-class của UIView đều có tụi nó
- Các functions sử dụng
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)
- Trong đó:
- touchesBegan : bắt đầu chạm vào
- touchesMove : di chuyển điểm chạm
- touchesEnded : kết thúc bằng cách đưa ngón tay lên khỏi màn hình
- touchesCancel : khi di chuyển điểm chạm ra ngoài vùng hiển thị của view
Sử dụng
- Mở file ViewController lên vào gõ chữ
touches
, bạn sẽ thấy hiện ra suggestion 4 function trên
- Tiến hành
override
các function đó. - Bạn hãy thử log bằng các print trong 4 function trên để xem chúng phản ứng lại với tương tác của người dùng như thế nào.
Lấy toạ độ của điểm chạm
- Tiếp tục với đoạn code sau
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { let currentPoint = touch.location(in: view) // do something with your currentPoint print("touch point(\(currentPoint.x), \(currentPoint.y))") } }
- Giải thích
- Sẽ có nhiều điểm chạm cảm ứng –> lấy điểm đầu tiên
- Tìm toạ độ của nó trong đối tượng
view
nào- Ở trên chính là view của ViewController hay chính là màn hình hiện tại
- Vì sự kiện cảm ứng sẽ được truyền theo từng cấp
- View trên cùng trước
- Rồi xuống dần các View ở dưới
- Theo dõi đoạn code tiếp theo
class ViewController: UIViewController { @IBOutlet weak var redView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { let currentPointOfView = touch.location(in: view) print("View point(\(currentPointOfView.x), \(currentPointOfView.y))") let currentPointOfRedView = touch.location(in: redView) print("RedView point(\(currentPointOfRedView.x), \(currentPointOfRedView.y))") } } }
- Giải thích
- Vẫn là điểm chạm đầu tiên
- Location được lấy ở 2 view
- View của ViewController
- RedView là view con của View
- Đối với mỗi đối tượng view thì sẽ cho 1 giá trị khác nhau
Phân biệt các đối tượng View
Vấn đề tiếp theo, là chúng ta có nhiều đối tượng view trong 1 view của ViewController. Tất cả chúng đều có 4 function trên. Làm sao để phân biết được từng đối tượng với nhau?
- Tiếp tục phân tích đoạn code sau
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { if touch.view == redView { print("inside RedView") } else { print("outside RedView") } } }
- Sử dụng thuộc tính
view
của đối tượng touch - Sau đó so sánh với các
outlet
hay các đối tượng view khác
- Nâng cấp 1 xí cho nhiều view
- Trong đoạn code dưới thì phân biệt 2 đối tượng view xanh và đỏ
import UIKit class ViewController: UIViewController { @IBOutlet weak var redView: UIView! @IBOutlet weak var blueView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { if touch.view == redView { print("inside RedView") } else if touch.view == blueView { print("inside BlueView") } else { print("outside RedView") } } } }
Di chuyển một đối tượng view
- Sử dụng function
touchesMove
khi chạm và kéo rê trên màn hình - Ví dụ
- Chạm vào trái banh
- Di chuyển trái banh
import UIKit class BalllViewController: UIViewController { @IBOutlet weak var ball: UIImageView! override func viewDidLoad() { super.viewDidLoad() } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { if touch.view == ball { let location = touch.location(in: view) ball.center = location } } } }
-
- Khi di chuyển điểm cảm ứng trên màn hình thì đồng thời ta xét lại vị trí
center
của trái banh. Như vậy, trái banh luôn di chuyển theo tay của chúng ta.
- Khi di chuyển điểm cảm ứng trên màn hình thì đồng thời ta xét lại vị trí
Vẽ một đường thẳng đơn giản
- Một ứng dụng nữa với
touchesMove
mà bạn có thể làm được. - Xem đoạn code sau
import UIKit class LineViewController: UIViewController { var path = UIBezierPath() var firstLocation = CGPoint.zero var shapeLayer = CAShapeLayer() override func viewDidLoad() { super.viewDidLoad() setupView() } func setupView(){ view.layer.addSublayer(shapeLayer) self.shapeLayer.lineWidth = 2 self.shapeLayer.strokeColor = UIColor.blue.cgColor } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let location = touches.first?.location(in: view){ firstLocation = location } } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let location = touches.first?.location(in: view) { path.removeAllPoints() path.move(to: firstLocation) path.addLine(to: location) shapeLayer.path = path.cgPath } } }
- Giải thích
- Tạo ra 1 CAShapeLayer & 1 Path
- touchesBegan : lưu lại giá trị của điểm chạm lúc bắt đầu
- touchesMove : khi có một điểm chạm mới trong lúc di chuyển thì add 1 line vào Path –> add Path vào layer
Tạm kết
- Bắt được sự kiện cảm ứng của người dùng trên tất cả loại view
- Lấy được các điểm chạm trên từng view khác nhau
- Phân biệt được các view khi chạm vào
- Chạm và di chuyển 1 đối tượng view
- Vẽ một đường thẳng đơn giản.
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Actor
Advanced Swift
api
AppDistribution
autolayout
basic ios tutorial
blog
bundle
ci/cd
closure
collectionview
combine
concurrency
crashlytics
darkmode
dart
dart basic
dart tour
Declarative
delegate
deploy
design pattern
fabric
fastlane
firebase
flavor
flutter
GCD
gestures
gradients
iOS
MVVM
optional
protocol
rxswift
safearea
Swift
Swift 5.5
SwiftData
SwiftUI
SwiftUI Notes
tableview
testing
TravisCI
unittest
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
You may also like:
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)