Có lẽ, sử dụng UILongPressGestureRecognizer là giải pháp phổ biến nhất. Nhưng tôi gặp phải hai rắc rối khó chịu:
- đôi khi trình nhận dạng này hoạt động không chính xác khi chúng tôi di chuyển chạm;
- trình nhận dạng chặn các hành động chạm khác nên chúng tôi không thể sử dụng các lệnh gọi lại đánh dấu của UICollectionView theo cách phù hợp.
Hãy để tôi đề xuất một cách hơi thô bạo một chút, nhưng hoạt động như đề xuất bắt buộc:
Khai báo mô tả gọi lại cho nhấp chuột lâu vào ô của chúng tôi:
typealias OnLongClickListener = (view: OurCellView) -> Void
Mở rộng UICollectionViewCell với các biến (ví dụ: chúng ta có thể đặt tên là OurCellView):
/// To catch long click events.
private var longClickListener: OnLongClickListener?
/// To check if we are holding button pressed long enough.
var longClickTimer: NSTimer?
/// Time duration to trigger long click listener.
private let longClickTriggerDuration = 0.5
Thêm hai phương thức trong lớp ô của chúng tôi:
/**
Sets optional callback to notify about long click.
- Parameter listener: A callback itself.
*/
func setOnLongClickListener(listener: OnLongClickListener) {
self.longClickListener = listener
}
/**
Getting here when long click timer finishs normally.
*/
@objc func longClickPerformed() {
self.longClickListener?(view: self)
}
Và ghi đè các sự kiện cảm ứng tại đây:
/// Intercepts touch began action.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
longClickTimer = NSTimer.scheduledTimerWithTimeInterval(self.longClickTriggerDuration, target: self, selector: #selector(longClickPerformed), userInfo: nil, repeats: false)
super.touchesBegan(touches, withEvent: event)
}
/// Intercepts touch ended action.
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
longClickTimer?.invalidate()
super.touchesEnded(touches, withEvent: event)
}
/// Intercepts touch moved action.
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
longClickTimer?.invalidate()
super.touchesMoved(touches, withEvent: event)
}
/// Intercepts touch cancelled action.
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
longClickTimer?.invalidate()
super.touchesCancelled(touches, withEvent: event)
}
Sau đó, ở đâu đó trong bộ điều khiển chế độ xem bộ sưu tập của chúng tôi khai báo trình nghe gọi lại:
let longClickListener: OnLongClickListener = {view in
print("Long click was performed!")
}
Và cuối cùng trong gọi lại thiết lập cellForItemAtIndexPath cho các ô của chúng tôi:
/// Data population.
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
let castedCell = cell as? OurCellView
castedCell?.setOnLongClickListener(longClickListener)
return cell
}
Bây giờ chúng tôi có thể chặn các hành động nhấp chuột dài trên các ô của chúng tôi.
UICollectionViewCell* cell = [self.collectionView cellForItemAtIndexPath:indexPath];
tham khảo ở đây hy vọng tất cả công đức này một giải thưởng câu trả lời đúng: D