Ios 使用LongPress手势重新订购后应用程序冻结

Ios 使用LongPress手势重新订购后应用程序冻结,ios,swift,Ios,Swift,我正在尝试添加longpress手势方法来重新排列tableview单元格。但当我在模拟器中运行应用程序时,在我按下单元格重新排序后,它会冻结,我无法找出是什么导致它 以下是我的ViewController的相关部分 导入UIKit 类ViewController:UITableViewController{ var stories = [URL]() var storyEnglishTitles:[String:String] = [ "A":"AEnglish", "B":

我正在尝试添加longpress手势方法来重新排列tableview单元格。但当我在模拟器中运行应用程序时,在我按下单元格重新排序后,它会冻结,我无法找出是什么导致它

以下是我的ViewController的相关部分

导入UIKit

类ViewController:UITableViewController{

var stories = [URL]()

var storyEnglishTitles:[String:String] = [
    "A":"AEnglish",
    "B":"BEnglish",
    "C":"CEnglish",
]

override func viewDidLoad() {
    super.viewDidLoad()

    title = "Stories, translated"

    stories = Bundle.main.urls(forResourcesWithExtension: "txt", subdirectory: nil)!

    let longpress = UILongPressGestureRecognizer(target: self, action: Selector(("longPressGestureRecognized:")))
    tableView.addGestureRecognizer(longpress)
}

func longPressGestureRecognized(gestureRecognizer: UIGestureRecognizer) {

    let longpress = gestureRecognizer as! UILongPressGestureRecognizer
    let state = longpress.state
    let locationInView = longpress.location(in: self.tableView)
    var indexPath = self.tableView.indexPathForRow(at: locationInView)

    switch state {
    case .began:
        if indexPath != nil {
            Path.initialIndexPath = indexPath
            let cell = self.tableView.cellForRow(at: indexPath!) as! UITableViewCell
            My.cellSnapShot = snapshopOfCell(inputView: cell)
            var center = cell.center
            My.cellSnapShot?.center = center
            My.cellSnapShot?.alpha = 0.0
            self.tableView.addSubview(My.cellSnapShot!)

            UIView.animate(withDuration: 0.25, animations: {
                center.y = locationInView.y
                My.cellSnapShot?.center = center
                My.cellSnapShot?.transform = CGAffineTransform(scaleX: 1.05, y: 1.05)
                My.cellSnapShot?.alpha = 0.98
                cell.alpha = 0.0
            }, completion: { (finished) -> Void in
                if finished {
                    cell.isHidden = true
                }
            })
        }

    case .changed:
        var center = My.cellSnapShot?.center
        center?.y = locationInView.y
        My.cellSnapShot?.center = center!
        if ((indexPath != nil) && (indexPath != Path.initialIndexPath)) {

            self.stories.swapAt((indexPath?.row)!, (Path.initialIndexPath?.row)!)
            self.tableView.moveRow(at: Path.initialIndexPath!, to: indexPath!)
            Path.initialIndexPath = indexPath
        }

    default:
        let cell = self.tableView.cellForRow(at: Path.initialIndexPath!) as! UITableViewCell
        cell.isHidden = false
        cell.alpha = 0.0
        UIView.animate(withDuration: 0.25, animations: {
            My.cellSnapShot?.center = cell.center
            My.cellSnapShot?.transform = .identity
            My.cellSnapShot?.alpha = 0.0
            cell.alpha = 1.0
        }, completion: { (finished) -> Void in
            if finished {
                Path.initialIndexPath = nil
                My.cellSnapShot?.removeFromSuperview()
                My.cellSnapShot = nil
            }
        })
    }
}

func snapshopOfCell(inputView: UIView) -> UIView {

    UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
    inputView.layer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    let cellSnapshot : UIView = UIImageView(image: image)
    cellSnapshot.layer.masksToBounds = false
    cellSnapshot.layer.cornerRadius = 0.0
    cellSnapshot.layer.shadowOffset = CGSize(width: -5.0, height: 0.0)
    cellSnapshot.layer.shadowRadius = 5.0
    cellSnapshot.layer.shadowOpacity = 0.4
    return cellSnapshot
}

struct My {
    static var cellSnapShot: UIView? = nil
}

struct Path {
    static var initialIndexPath: IndexPath? = nil
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return stories.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "StoryCell", for: indexPath) as UITableViewCell
    let storyForeignTitle = stories[indexPath.row].deletingPathExtension().lastPathComponent
    cell.textLabel?.text = storyForeignTitle
    let subtitleEnglishTitles = storyEnglishTitles[hymnGurmukhiTitle]
    cell.detailTextLabel?.text = subtitleEnglishTitles
    return cell 

}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: false)

    if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController {
        vc.selectedStory = stories[indexPath.row]
        navigationController?.pushViewController(vc, animated: true)
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
以下是来自我的控制台的错误消息:

2018-05-04 15:40:54.047849-0700 FolkStore[1891:628678]-[FolkStore.ViewController LongPressGestureRecognited:]:未识别的选择器发送到实例0x10390c190 2018-05-04 15:40:54.048686-0700 FolkStore[1891:628678]*由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[FolkStore.ViewController LongPressGestureReceignized:]:未识别的选择器发送到实例0x10390c190' *第一次抛出调用堆栈: (0x181d82d8c 0x180f3c5ec 0x181d90098 0x18be36de4 0x181d885c8 0x181c6e41c 0x18bb32750 0x18c09f2a4 0x18bc94e6c 0x18bb317a8 0x18c090ac4 0x181d2a910 0x181d28238 0x181d28884 0x181c48da8 0x183c2b020 0x18bc2978c 0x102accc54 0x1816d9fc0) libc++abi.dylib:以NSException类型的未捕获异常终止

更新此行:

let longpress = UILongPressGestureRecognizer(target: self, action: Selector(("longPressGestureRecognized:")))
让longpress=UILongPressGestureRecognitizer(操作:#选择器(self.LongPressGestureRecognited(:))

现在获取错误:“ViewController”类型的值没有成员“LongPressGestureRecognited”……这很奇怪,因为下一个代码是func LongPressGestureRecognited(GestureRecognitizer:UIGestureRecognitizer)

我还得到了另外两个可能相关的条件错误。func LongPressGestureRecognited方法中的这两行给出了相同的错误。这些行:

let cell = self.tableView.cellForRow(at: Path.initialIndexPath!) as! UITableViewCell 
给出错误:从“UITableViewCell”强制强制转换为“UITableViewCell”仅打开选项;您的意思是使用“!”吗

解决方案:这是一个Swift 3到Swift 4的问题,我想为我添加解决方案,以防其他人正在寻找答案

首先将@objc添加到方法中:

@objc func longPressGestureRecognized(gestureRecognizer: UIGestureRecognizer) {}
第二次更新此行:

let longpress = UILongPressGestureRecognizer(target: self, action: Selector(("longPressGestureRecognized:")))
以使其与Swift 4兼容:

let longpress = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPressGestureRecognized))

它会给你任何错误消息吗?在错误消息方面,我还是个傻瓜。我设置了断点来诊断这个问题。我在AppDelegate at类AppDelegate:UIResponder,UIApplicationLegate中得到了“线程1:breakpoint 1.1”{是的,我去过那里。我说的是出现在你控制台中的一条消息。我刚刚在上面的帖子中添加了我在控制台中遇到的两个错误。我的长按选择器有问题吗?请尝试在
func longpressgestureerecognized
之前添加
@objc