简体   繁体   English

从右向左“滑动” UITableViewCell

[英]UITableViewCell “full” swipe, right-to-left

I have a UITableView with cells already implementing two custom buttons (UITableViewRowAction edit actions) when swiping right-to-left. 我有一个UITableView,当从右向左滑动时,单元格已经实现了两个自定义按钮(UITableViewRowAction编辑动作)。 All works well. 一切正常。

I'd like to trigger one of the buttons' actions when the user swipes "all the way" (also right-to-left), similar to Mail.app. 我想在用户“一路”(也从右到左)滑动时触发按钮的操作之一,类似于Mail.app。

Code is Swift 3, for iOS 9 and 10. 代码是Swift 3,适用于iOS 9和10。

I have what I believe to be sufficient code in place. 我有足够的代码。

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
    return .delete
 }

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    print("commit editingStyle")
}

The commit editingStyle function never fires, as I would expect it to. commit editingStyle函数从不触发,正如我期望的那样。

I removed my editActionsForRowAt method, thinking perhaps I was screwing something up while defining the custom buttons. 我删除了editActionsForRowAt方法,以为我在定义自定义按钮时可能editActionsForRowAt了。 I now see the default "Delete" button, but commit editingStyle still does not fire. 现在,我看到默认的“删除”按钮,但是仍然不会触发commit editingStyle

For what it's worth, this is a UITableView inside a UIViewController (not a UITableViewController), with both .dataSource and .delegate set to the class in question. 值得的是,这是UIViewController(不是UITableViewController)内的UITableView,其中.dataSource和.delegate都设置为相关类。 It is also a NSFetchedResultsControllerDelegate. 它也是NSFetchedResultsControllerDelegate。

Attach a UISwipeGestureRecognizer to the table itself, not to the individual cells. UISwipeGestureRecognizer附加到表本身,而不是单个单元格。 When a swipe is detected, calculate which cell was swiped, and call your swipe action accordingly. 当检测到滑动时,计算要滑动哪个单元格,并相应地调用滑动动作。

Add this : 添加:

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

I came up with a mechanism to do this, which I don't think is too much of a hack - certainly less-so than other solutions I found. 我想出了一种机制来做到这一点,我认为这并不是太多的骇客-当然比我发现的其他解决方案要少。 Comments are welcome. 欢迎发表评论。

My intent is always to use as much standard functionality as possible. 我的意图是始终使用尽可能多的标准功能。 What I'm doing is to track how far a user has swiped the main body of the cell to the left. 我正在做的是跟踪用户向左滑动单元主体的距离。 When some threshold is reached, I tell the UITableView to perform the same action called from editActionsForRowAt for the button in question. 当达到某个阈值时,我告诉UITableView对有问题的按钮执行从editActionsForRowAt调用的相同操作。

I'm using -225 as the threshold for how far to the left the cell has been moved. 我正在使用-225作为单元格向左移动的阈值。 This might not work for all implementations (and I may modify myself with more testing). 这可能不适用于所有实现(并且我可能会通过更多测试来修改自己)。 In my case I have two custom actions, the button for one is somewhat on the wide side. 在我的情况下,我有两个自定义操作,其中一个的按钮有些偏大。

The only thing I really add is an NSTimer, which I add to the main run loop using the .UITrackingRunLoopMode. 我唯一真正添加的是NSTimer,我使用.UITrackingRunLoopMode将其添加到主运行循环中。 This has the benefit of running when (and only when) the user is moving their finger around. 这具有在用户(且仅在)手指移动时运行的好处。 When the timer fires, I check to see where the cell is relative to the host tableView. 当计时器触发时,我检查一下该单元相对于主机tableView的位置。 No added views, no added gesture recognizers. 没有添加视图,没有添加手势识别器。

In the custom UITableViewCell, I added this: 在自定义UITableViewCell中,我添加了以下内容:

var trackTimer:Timer? = nil
weak var tableView:StudentsLessonsViewController? = nil

override func awakeFromNib() {
    super.awakeFromNib()
    setupTimer()
}

override func prepareForReuse() {
    super.prepareForReuse()
    setupTimer()
}

func setupTimer() {
    self.trackTimer = Timer.init(timeInterval: 0.1, target: self, selector: #selector(performActionIfScrolledFarEnough), userInfo: nil, repeats: true)
    if let trackTimer = self.trackTimer {
        RunLoop.main.add(trackTimer, forMode: .UITrackingRunLoopMode)
    }
}

func performActionIfScrolledFarEnough() {
    let globalPoint = self.superview?.convert(self.frame.origin, to: self.tableView?.tableView)
    //print("globalPoint.x: \(String(describing: globalPoint?.x))")
    if let globalPoint = globalPoint {
        if globalPoint.x < CGFloat(-225) {
            //print ("Perform Action NOW!!!")
            trackTimer?.invalidate()
            if let tableView = self.tableView {
                tableView.primaryActionButtonPressed(cell: self)
            }
        }
    }
}

In the UITableView's cellForRowAtIndexPath, I added: 在UITableView的cellForRowAtIndexPath中,我添加了:

cell?.tableView = self

I already had this function in my UITableView, which I was calling when the user taps one of the buttons defined in editActionsForRowAt: 我的UITableView中已经具有此功能,当用户点击editActionsForRowAt中定义的按钮之一时,我正在调用它:

func tableView.primaryActionButtonPressed(cell:UITableViewCell)

In my primaryActionButtonPressed function I remove the cell from the tableView (conceptually like a delete). 在我的primaryActionButtonPressed函数中,我从tableView中删除了单元格(概念上就像删除一样)。 It's possible dissimilar actions might require different implementation details. 不同的操作可能需要不同的实现细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UISplitViewControllerDelegate / UIPopoverDelegate方法在从右向左滑动时未调用 - UISplitViewControllerDelegate/UIPopoverDelegate methods not called on right-to-left swipe UITableView强制从左向左滑动以删除不起作用 - UITableView Force Right-to-Left swipe to delete not work iOS - 禁用 UITableViewCell 的向右或向左滑动 - iOS - disable right or left swipe for UITableViewCell 在UITableViewCell中向左或向右滑动以删除没有删除按钮的单元格? - Swipe left or right anywhere in a UITableViewCell to delete the cell with no delete button? 当我在单元格上从右向左滑动时,UITableviewcell删除按钮会增加 - UITableviewcell delete button apprearing when I swipe right to left on a cell 如何在键盘中更改为从右到左语言 - How to change to Right-to-Left language in keyboard 将UITableView方向更改为从右到左 - Change UITableView direction to Right-to-Left 滑动以删除将UITableViewCell移动到左侧 - Swipe to delete moves the UITableViewCell to the left iOS 9禁用对从右到左语言的支持 - iOS 9 disable support for right-to-left language UILabel无法与NSAttributedString + NSParagraphStyle一起使用,从右向左 - UILabel not working with NSAttributedString + NSParagraphStyle for Right-To-Left
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM