以编程方式打开UITableView编辑操作按钮

Fir*_*ras 28 uitableview ios swift

我有一个UIPageViewController具有UITableViewControllers里面,并向左滑动手势之间冲突UIPageViewController的意见和之间改变UITableViewCells姿势,打开编辑的动作,所以我需要显示的编辑操作时,单击该单元中的某个按钮.

我的问题是,我可以以编程方式显示编辑操作按钮,而不是在滑动手势上显示它们吗?

kab*_*rai 10

Apple有一个私有API可以让你这样做,但是,请注意,这可能会让你的应用程序被App Store拒绝,除非你使用Method Swizzling之类的东西模糊了所述API的使用.以下是执行此操作的步骤:

  1. 创建一个名为的协议PrivateMethodRevealer,允许您访问所需的私有Apple API,即显示和关闭编辑操作的API.相信这个答案提供了这种公开私有API的方法.协议中的方法被声明为optional,因此,如果Apple更改方法的名称,应用程序将不会崩溃,而是,它不会显示编辑操作.

    @objc protocol PrivateMethodRevealer {
        optional func setShowingDeleteConfirmation(arg1: Bool)
        optional func _endSwipeToDeleteRowDidDelete(arg1: Bool)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,虽然方法参考delete,但它显示UITableViewRowAction了单元格上的所有s.

  2. 创建一个函数来处理UITableViewCell子类中编辑操作的显示和隐藏(如果有的话),或者在a中创建方法UITableViewCell extension.我将此方法命名showActions为演示目的.

  3. 将以下正文添加到您的函数:

    func showActions() {
        (superview?.superview as? AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
        (self as AnyObject).setShowingDeleteConfirmation?(true)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这首先驳斥任何可见的细胞的编辑操作,通过调用_endSwipeToDeleteRowDidDelete:UITableView(这是细胞的上海华盈的上海华),然后显示了细胞自身的编辑操作(通过调用setShowingDeleteConfirmation:).请注意,我们需要关闭其他单元格的操作,因为使用编辑操作显示多行非常错误.

  4. 如果需要,您还可以在其中创建一个按钮,以UIViewController取消当前正在编辑的任何单元格.要做到这一点,只需调用以下方法,tableView您在哪里引用UITableView:

    (tableView as AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
    
    Run Code Online (Sandbox Code Playgroud)

如果您UIPageViewController和您之间的滑动手势存在UITableViewCell冲突,只需覆盖tableView:editingStyleForRowAtIndexPath:要返回的方法即可.None.

最后,您的代码可能会产生以下结果 演示视频

编辑:这是一种使用方法调配隐藏API使用情况的快捷方法.致本网站提供此方法的基本实现.请注意,我无法保证它能够正常工作,因为无法对其进行现场测试.

要做到这一点,用下面的代码替换协议,并且无论你打电话setShowingDeleteConfirmation(true)或者_endSwipeToDeleteRowDidDelete(false),取而代之的是showRowActions()hideRowActions()不是.但是,此方法似乎有一些意想不到的效果,例如UITableViewCell在编辑操作可见时s不响应用户交互.

extension UITableViewCell {
    func showRowActions(arg1: Bool = true) {}

    public override static func initialize() {
        struct Static {
            static var token: dispatch_once_t = 0
        }

        guard self === UITableViewCell.self else {return}

        dispatch_once(&Static.token) {
            let hiddenString = String(":noitamrifnoCeteleDgniwohStes".characters.reverse())
            let originalSelector = NSSelectorFromString(hiddenString)
            let swizzledSelector = #selector(showRowActions(_:))
            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
            class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

extension UITableView {
    func hideRowActions(arg1: Bool = false) {}

    public override static func initialize() {
        struct Static {
            static var token: dispatch_once_t = 0
        }

        guard self === UITableView.self else {return}

        dispatch_once(&Static.token) {
            let hiddenString = String(":eteleDdiDwoReteleDoTepiwSdne_".characters.reverse())
            let originalSelector = NSSelectorFromString(hiddenString)
            let swizzledSelector = #selector(hideRowActions(_:))
            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
            class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)