以编程方式打开UITableView编辑操作按钮 [英] Open UITableView edit action buttons programmatically

查看:107
本文介绍了以编程方式打开UITableView编辑操作按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UIPageViewController ,里面有 UITableViewControllers ,并且在<$之间滑动左手势是冲突的c $ c> UIPageViewController 在视图和 UITableViewCells 手势之间切换以打开编辑操作,因此我需要在显示时执行编辑操作单元格中单击了某个按钮。



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

解决方案

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


  1. 创建名为 PrivateMethodRevealer 允许您访问所需的私有Apple API,即显示和关闭编辑操作的API。



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



    要执行此操作,请使用以下内容替换协议代码,无论你在哪里调用 setShowingDeleteConfirmation(true) _endSwipeToDeleteRowDidDelete(false),用 showRowActions() hideRowActions()。这种方法似乎有一些意想不到的效果,例如 UITableViewCell 在编辑操作可见时没有响应用户交互。

     扩展名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_addMet hod(self,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod))
    method_exchangeImplementations(originalMethod,swizzledMethod)
    }
    }
    }

    扩展名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)
    }
    }
    }


    I have a UIPageViewController that have UITableViewControllers inside it, and the swipe left gestures are conflicted between the UIPageViewController to change between the views and the UITableViewCells gesture to open the edit actions, so I need to show the edit actions when a certain button is clicked in the cell.

    My question is can I show the edit action buttons programmatically instead of showing them on the swipe gesture?

    解决方案

    Apple has a private API that lets you do this, however, be warned that this may get your app rejected from the App Store unless you obfuscate the usage of said API using something like Method Swizzling. Here are the steps to do so:

    1. Create a protocol called PrivateMethodRevealer that lets you access the required private Apple APIs, namely the ones to show and dismiss edit actions. Credits to this answer for providing this method of exposing private APIs. The methods in the protocol are declared as optional, so that in case Apple changes the name of the method, the app will not crash, but rather, it'll just not show the edit actions.

      @objc protocol PrivateMethodRevealer {
          optional func setShowingDeleteConfirmation(arg1: Bool)
          optional func _endSwipeToDeleteRowDidDelete(arg1: Bool)
      }
      

      Note that although the methods refer to delete, this shows all the UITableViewRowActions that are on the cell.

    2. Create a function that handles the showing and hiding of the edit actions in your UITableViewCell subclass (if you have one), or create the method in a UITableViewCell extension. I will name this method showActions for demonstrative purposes.

    3. Add the following body to your function:

      func showActions() {
          (superview?.superview as? AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
          (self as AnyObject).setShowingDeleteConfirmation?(true)
      }
      

      This firstly dismisses any visible cells' editing actions, by calling _endSwipeToDeleteRowDidDelete: on the UITableView (which is the cell's superview's superview), and then shows the cell's own editing actions (by calling setShowingDeleteConfirmation:). Note that we need to dismiss other cells' actions as showing multiple rows with edit actions is extremely buggy.

    4. If you want, you may also create a button in the UIViewController that dismisses any currently editing cells. To do this, just call the following method, where tableView is your reference to the UITableView:

      (tableView as AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
      

    If the swipe gestures between your UIPageViewController and UITableViewCells are conflicting, simply override the tableView:editingStyleForRowAtIndexPath: method to return .None.

    In the end, your code might produce the following result

    EDIT: Here is a quick way to hide the usage of your API using method swizzling. Credits to this website for providing the basic implementation of this method. Be warned that I can't guarantee that it'll work, as it isn't possible to test it live.

    To do this, replace the protocols with the following code, and wherever you call setShowingDeleteConfirmation(true) or _endSwipeToDeleteRowDidDelete(false), replace it with showRowActions() and hideRowActions() instead. This method appears to have some unintended effects however, such as the UITableViewCells not responding to user interaction whilst edit actions are visible.

    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)
            }
        }
    }
    

    这篇关于以编程方式打开UITableView编辑操作按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆