Long Press (press-and-hold): Phát hiện ngón tay chạm màn hình kéo dài một khoảng thời gian. Dùng cho: context menu, drag & drop, trigger action phụ.
Apple Docs: Handling Long-Press Gestures
Ví dụ: Hiển thị Alert khi nhấn giữ button 2 giây
Bước 1: Tạo dự án
Xcode → Single View App → Tên: "LongPressGesture".
Bước 2: Storyboard
Thêm Button → Tạo @IBOutlet weak var btnLongOutlet: UIButton!
Bước 3: Code ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var btnLongOutlet: UIButton!
private var longPressGesture: UILongPressGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
setupLongPressGesture()
}
func setupLongPressGesture() {
longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
longPressGesture.minimumPressDuration = 2.0 // 2 giây
longPressGesture.allowableMovement = 10 // Cho phép di chuyển 10pt vẫn tính là long press
btnLongOutlet.addGestureRecognizer(longPressGesture)
}
@objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
// Quan trọng: Kiểm tra state để chỉ trigger 1 lần
guard gesture.state == .began else { return }
let alert = UIAlertController(title: "Long Press",
message: "Long Press Gesture Detected",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
}

Các State của UILongPressGestureRecognizer
| State | Ý nghĩa | Khi nào xảy ra |
|---|---|---|
.possible |
Chưa xác định | Ban đầu |
.began |
Vừa đạt ngưỡng thời gian | Trigger action chính ở đây |
.changed |
Đang giữ, có di chuyển nhẹ | Drag tracking |
.ended |
Nhả ngón tay | Cleanup, kết thúc drag |
.cancelled |
Hủy (system interrupt, call coming...) | Reset state |
.failed |
Không đạt ngưỡng | Tap quá nhanh |
Cấu hình quan trọng
let gesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
gesture.minimumPressDuration = 0.5 // Mặc định 0.5s, có thể tăng (2s cho deliberate action)
gesture.allowableMovement = 10 // Mặc định 10pt, tăng nếu muốn cho di chuyển nhiều hơn
gesture.numberOfTouchesRequired = 1 // Số ngón tay (default 1)
gesture.numberOfTapsRequired = 0 // Số tap trước khi hold (default 0)
Thêm Long Press cho bất kỳ View nào (Programmatically)
extension UIView {
func addLongPressGesture(target: Any, action: Selector, duration: TimeInterval = 0.5) {
let gesture = UILongPressGestureRecognizer(target: target, action: action)
gesture.minimumPressDuration = duration
gesture.allowableMovement = 10
self.addGestureRecognizer(gesture)
self.isUserInteractionEnabled = true // Bắt buộc!
}
}
// Usage
myView.addLongPressGesture(target: self, action: #selector(handleLongPress), duration: 1.0)
Long Press trên TableView/CollectionView (Cell)
// Trong cellForRowAt
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(cellLongPressed(_:)))
cell.addGestureRecognizer(longPress)
// Handler
@objc func cellLongPressed(_ gesture: UILongPressGestureRecognizer) {
guard gesture.state == .began,
let cell = gesture.view as? UITableViewCell,
let indexPath = tableView.indexPath(for: cell) else { return }
// Haptic feedback
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
// Show context menu hoặc action sheet
showContextMenu(for: indexPath)
}
iOS 13+: UIContextMenuInteraction (Thay thế Long Press cho context menu)
let interaction = UIContextMenuInteraction(delegate: self)
view.addInteraction(interaction)
// Delegate
func contextMenuInteraction(_ interaction: UIContextMenuInteraction,
configurationForMenuAtLocation location: CGPoint)
-> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
let edit = UIAction(title: "Sửa", image: UIImage(systemName: "pencil")) { _ in }
let delete = UIAction(title: "Xóa", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in }
return UIMenu(title: "", children: [edit, delete])
}
}
Lưu ý
- Luôn check
gesture.state == .beganđể tránh trigger nhiều lần - Thêm
isUserInteractionEnabled = truecho view nếu chưa có - Long press delay mặc định 0.5s - tăng lên 1-2s cho action nguy hiểm (xóa, logout)
- Kết hợp
UIImpactFeedbackGeneratorcho haptic feedback tốt hơn UX