Ios 如何在Swift 3中向TableView添加向左滑动手势并返回单元格位置
我有一个TableView,它已经被编码为在使用Ios 如何在Swift 3中向TableView添加向左滑动手势并返回单元格位置,ios,uitableview,swift3,uigesturerecognizer,Ios,Uitableview,Swift3,Uigesturerecognizer,我有一个TableView,它已经被编码为在使用didSelectRowAt方法选择任何单元格时执行操作 现在,我想在表格(或单元格)中添加一个向左滑动的手势,这样我就可以在滑动单元格而不是轻触单元格时执行辅助操作 1) 我希望单元格在滑动时向左移动,但我不希望在单元格移动的位置添加按钮 2) 相反,我希望能够将单元格向左“拖动”到某个点(比如说中途),然后在该点上使用indexPath执行第二个操作(这样我就知道拖动了哪个单元格) 3) 如果用户停止拖动或放开单元格,我希望它返回到起始位置,并
didSelectRowAt
方法选择任何单元格时执行操作
现在,我想在表格(或单元格)中添加一个向左滑动的手势,这样我就可以在滑动单元格而不是轻触单元格时执行辅助操作
1) 我希望单元格在滑动时向左移动,但我不希望在单元格移动的位置添加按钮
2) 相反,我希望能够将单元格向左“拖动”到某个点(比如说中途),然后在该点上使用indexPath执行第二个操作(这样我就知道拖动了哪个单元格)
3) 如果用户停止拖动或放开单元格,我希望它返回到起始位置,并且不执行任何操作
我见过很多这样做的示例,但大多数都在Obj-C中,或者在单元格的同一行中插入按钮
另外,将手势添加到每个单元格是否更好?
将其添加到表中似乎更明智
编辑:下面是我的完整答案,代码是我做了一些研究,并创建了一个简单的示例来说明如何实现这一点-创建一个可以滑动和点击的表格单元格。我在音乐播放器中使用它——轻触手机播放歌曲,轻扫同一手机,切换到不同的视图 我基于以下两个现有示例构建了我的解决方案: 我没有可共享的存储库,所以所有代码都在这里 我使用的是Xcode 8.2.1和Swift 3 步骤1:
- 创建一个新的单视图Swift项目,并打开情节提要
- 将TableView拖到现有的ViewController上,然后将其拖动以适合视图李>
- 将新Swift文件添加到项目中,并将其命名为“TableViewCellSliding.Swift”
- 将下面的代码复制/粘贴到新文件中
// // TableViewCellSliding.swift // import UIKit protocol SlidingCellDelegate { // tell the TableView that a swipe happened func hasPerformedSwipe(touch: CGPoint) func hasPerformedTap(touch: CGPoint) } class SlidingTableViewCell: UITableViewCell { var delegate: SlidingCellDelegate? var originalCenter = CGPoint() var isSwipeSuccessful = false var touch = CGPoint() required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) // add a PAN gesture let pRecognizer = UIPanGestureRecognizer(target: self, action: #selector(SlidingTableViewCell.handlePan(_:))) pRecognizer.delegate = self addGestureRecognizer(pRecognizer) // add a TAP gesture // note that adding the PAN gesture to a cell disables the built-in tap responder (didSelectRowAtIndexPath) // so we can add in our own here if we want both swipe and tap actions let tRecognizer = UITapGestureRecognizer(target: self, action: #selector(SlidingTableViewCell.handleTap(_:))) tRecognizer.delegate = self addGestureRecognizer(tRecognizer) } override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer { let translation = panGestureRecognizer.translation(in: superview!) //look for right-swipe if (fabs(translation.x) > fabs(translation.y)) && (translation.x > 0){ // look for left-swipe //if (fabs(translation.x) > fabs(translation.y)) && (translation.x < 0){ //print("gesture 1") touch = panGestureRecognizer.location(in: superview) return true } //not left or right - must be up or down return false }else if gestureRecognizer is UITapGestureRecognizer { touch = gestureRecognizer.location(in: superview) return true } return false } func handleTap(_ recognizer: UITapGestureRecognizer){ // call function to get indexPath since didSelectRowAtIndexPath will be disabled delegate?.hasPerformedTap(touch: touch) } func handlePan(_ recognizer: UIPanGestureRecognizer) { if recognizer.state == .began { originalCenter = center } if recognizer.state == .changed { checkIfSwiped(recongizer: recognizer) } if recognizer.state == .ended { let originalFrame = CGRect(x: 0, y: frame.origin.y, width: bounds.size.width, height: bounds.size.height) if isSwipeSuccessful{ delegate?.hasPerformedSwipe(touch: touch) //after 'short' swipe animate back to origin quickly moveViewBackIntoPlaceSlowly(originalFrame: originalFrame) } else { //after successful swipe animate back to origin slowly moveViewBackIntoPlace(originalFrame: originalFrame) } } } func checkIfSwiped(recongizer: UIPanGestureRecognizer) { let translation = recongizer.translation(in: self) center = CGPoint(x: originalCenter.x + translation.x, y: originalCenter.y) //this allows only swipe-right isSwipeSuccessful = frame.origin.x > frame.size.width / 2.0 //pan is 1/2 width of the cell //this allows only swipe-left //isSwipeSuccessful = frame.origin.x < -frame.size.width / 3.0 //pan is 1/3 width of the cell } func moveViewBackIntoPlace(originalFrame: CGRect) { UIView.animate(withDuration: 0.2, animations: {self.frame = originalFrame}) } func moveViewBackIntoPlaceSlowly(originalFrame: CGRect) { UIView.animate(withDuration: 1.5, animations: {self.frame = originalFrame}) } }
- 打开情节提要视图并选择表格视图。转到连接检查器(圆圈中的右上角箭头)并从新的参考插座拖动到TableView,然后从弹出菜单中选择“TableView”
- 在TableView仍处于选中状态的情况下,从Outlets>dataSource拖动到情节提要中的TableView。重复从Outlets>delegate开始
- 快跑李>
我不会详细介绍任何代码,因为顶部的两个链接做得很好。这仅仅是关于拥有完整、简单、干净的代码来构建。享受吧。OP所要求的并不是可能的重复about@MichaelFourre这是正确的。然而,我刚刚发现了两个帖子,显示了我在寻找什么,其中一个几乎就是它。概述:准确:你可以写下你的解决方案,然后当你完成后,用一些实现片段给自己一个答案,以防其他人想看到它,我一弄明白就可以了!有一些小问题,因为示例不在Swift 3中
//
// ViewController.swift
//
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SlidingCellDelegate {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.dataSource = self
tableView.delegate = self
tableView.register(SlidingTableViewCell.self, forCellReuseIdentifier: "cell")
tableView.rowHeight = 50;
}
func hasPerformedSwipe(touch: CGPoint) {
if let indexPath = tableView.indexPathForRow(at: touch) {
// Access the image or the cell at this index path
print("got a swipe row:\(indexPath.row)")
}
}
func hasPerformedTap(touch: CGPoint){
if let indexPath = tableView.indexPathForRow(at: touch) {
// Access the image or the cell at this index path
print("got a tap row:\(indexPath.row)")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int)-> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell=tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath) as! SlidingTableViewCell
// Configure cell
cell.selectionStyle = .none
cell.textLabel?.text = "hello \(indexPath.row)"
cell.delegate = self
return cell
}
func tableView(sender: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// do stuff with indexPath.row and indexPath.section
//never make it here because we added a tap gesture but this will
print("selected cell")
}
}