如何在 Swift 中长按时选择表格行
Posted
技术标签:
【中文标题】如何在 Swift 中长按时选择表格行【英文标题】:How To select a table row during a long press in Swift 【发布时间】:2015-06-15 07:13:04 【问题描述】:我有一个表格,它有一个长按手势识别器,它根据选择的表格行运行代码。
我遇到的麻烦是我目前必须点击我想要的行然后长按。
如何让表格选择我长按的行,而无需先点击选择它?
【问题讨论】:
【参考方案1】:Swift 4 和 5
override func viewDidLoad()
super.viewDidLoad()
setupLongPressGesture()
func setupLongPressGesture()
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongPress))
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.delegate = self
self.tblMessage.addGestureRecognizer(longPressGesture)
@objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer)
if gestureRecognizer.state == .began
let touchPoint = gestureRecognizer.location(in: self.tblMessage)
if let indexPath = tblMessage.indexPathForRow(at: touchPoint)
斯威夫特 3
override func viewDidLoad()
super.viewDidLoad()
setupLongPressGesture()
func setupLongPressGesture()
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(YourViewController.handleLongPress(_:)))
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.delegate = self
self.tblMessage.addGestureRecognizer(longPressGesture)
func handleLongPress(_ longPressGestureRecognizer: UILongPressGestureRecognizer)
if longPressGestureRecognizer.state == UIGestureRecognizerState.Began
let touchPoint = longPressGestureRecognizer.locationInView(self.view)
if let indexPath = tableView.indexPathForRowAtPoint(touchPoint)
// your code here, get the row for the indexPath or do whatever you want
目标 - C
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
[self.tableView addGestureRecognizer:longPressRecognizer];
-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
if (pGesture.state == UIGestureRecognizerStateRecognized)
//Do something to tell the user!
if (pGesture.state == UIGestureRecognizerStateEnded)
UITableView* tableView = (UITableView*)self.view;
CGPoint touchPoint = [pGesture locationInView:self.view];
NSIndexPath* row = [tableView indexPathForRowAtPoint:touchPoint];
if (row != nil)
//Handle the long press on row
【讨论】:
在 5 秒内为我工作。 Swift 4 谢谢好友!! 需要修复 Swift 4 的示例。需要删除行 'longPressGesture.delegate = self' 和 .end 替换 .began 我同意@DronPop。我确认 Swift4 不需要“longPressGesture.delegate = self”。另外我也觉得'.began'比较合适。无论如何,这是一个很好的答案,所以我投了赞成票。 我不知道为什么,但我得到indexPathForRowAtPoint
值为零【参考方案2】:
以下代码对我来说很好用:
在 viewDidLoad 中添加长按手势识别器:
// tapRecognizer, placed in viewDidLoad
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPress:")
self.view.addGestureRecognizer(longPressRecognizer)
那么长按调用的方法是这样的:
//Called, when long press occurred
func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer)
if longPressGestureRecognizer.state == UIGestureRecognizerState.Began
let touchPoint = longPressGestureRecognizer.locationInView(self.view)
if let indexPath = tableView.indexPathForRowAtPoint(touchPoint)
// your code here, get the row for the indexPath or do whatever you want
【讨论】:
他已经实现了功能并面临额外的点击问题。 我不确定我是否正确理解了这个问题。我至少可以说的是,我用我的代码长按,我得到了我长按所在行的 indexPath。无需额外点击。let touchPoint = longPressGestureRecognizer.locationInView(self.tableView)
是正确的,而不是 let touchPoint = longPressGestureRecognizer.locationInView(self.view)
。否则,您不会考虑到self.tableView.frame.origin
不能等于CGPointZero
【参考方案3】:
Swift 3 功能:
func handleLongPress(_ longPressGestureRecognizer: UILongPressGestureRecognizer)
if longPressGestureRecognizer.state == UIGestureRecognizerState.Began
let touchPoint = longPressGestureRecognizer.locationInView(self.view)
if let indexPath = tableView.indexPathForRowAtPoint(touchPoint)
// your code here, get the row for the indexPath or do whatever you want
viewDidLoad:
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(YourViewController.handleLongPress(_:)))
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.delegate = self
self.tableView.addGestureRecognizer(longPressGesture)
更多:https://github.com/apple/swift-evolution/blob/e4328889a9643100177aef19f6f428855c5d0cf2/proposals/0046-first-label.md
【讨论】:
如您所说,它不适用于 swift 3.0。它仍然指向 swift 对我来说在 Swift 3 中完美运行。【参考方案4】:Swift 4
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressed(sender:)))
self.view.addGestureRecognizer(longPressRecognizer)
// MARK:动作
@objc func longPressed(sender: UILongPressGestureRecognizer)
if sender.state == UIGestureRecognizerState.began
let touchPoint = sender.location(in: self.tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint)
print("Long pressed row: \(indexPath.row)")
【讨论】:
sender.location(in: self.tableView) // 正确【参考方案5】:适用于 swift 版本 3
func longPress(_ longPressGestureRecognizer: UILongPressGestureRecognizer)
if longPressGestureRecognizer.state == UIGestureRecognizerState.began
let touchPoint = longPressGestureRecognizer.location(in: self.view)
if let indexPath = notificationTabelView.indexPathForRow(at: touchPoint)
print("indexPath=\(indexPath)")
// your code here, get the row for the indexPath or do whatever you want
在您的viewDidLoad
函数中
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(EmployeeNotificationViewController.longPress(_:)))
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.delegate = self as? UIGestureRecognizerDelegate
self.notificationTabelView.addGestureRecognizer(longPressGesture)
【讨论】:
【参考方案6】:为避免这种情况,您可以在cellForRowAtIndexPath
中添加UILongPressGestureRecognizer
而不是didSelectRowAtIndexPath
【讨论】:
【参考方案7】:使用 IBAction 你可以做(对于 CollectionView):
@IBAction func handleLongPress(sender: AnyObject)
if sender.state == UIGestureRecognizerState.Began
let position = sender.locationInView(sender.view)
if let indexPath : NSIndexPath = ((sender.view as! UICollectionView).indexPathForItemAtPoint(position))!
print("You holding cell #\(indexPath.item)!")
记得链接你的长按手势识别器。
【讨论】:
【参考方案8】:let longPressGesture = UILongPressGestureRecognizer(target: self, action: (#selector(YourCustomeTableCell.longTap)))
self.addGestureRecognizer(longPressGesture)
func longTap()
print("Long tap")
【讨论】:
【参考方案9】:斯威夫特 5
像这样在viewDidLoad()
中声明这一行
override func viewDidLoad()
super.viewDidLoad()
//do other stuff here
// long press listener for tableview
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(sender:)))
tableView.addGestureRecognizer(longPress)
handleLongPress()
方法在哪里
@objc private func handleLongPress(sender: UILongPressGestureRecognizer)
if sender.state == .began
let touchPoint = sender.location(in: tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint)
let alert = UIAlertController(title: "Alert", message: "Do you want to delete this item?", preferredStyle: .alert)
let action = UIAlertAction(title: "Yes", style: .default) (action) in
// do your functionality
alert.dismiss(animated: true, completion: nil)
let actionDelete = UIAlertAction(title: "No", style: .default) (action) in
// do your functionality
alert.dismiss(animated: true, completion: nil)
alert.addAction(action)
alert.addAction(actionDelete)
self.present(alert, animated: true, completion: nil)
// your code here, get the row for the indexPath or do whatever you want
【讨论】:
以上是关于如何在 Swift 中长按时选择表格行的主要内容,如果未能解决你的问题,请参考以下文章
如何使用选择器在长按时“永久”突出显示 ListView 行,但在正常按下时短暂显示
如何在swift 3的表格视图中仅更改选定行和未选定行的字体颜色和大小?