使用LongPressGesture

时间:2018-05-03 22:10:36

标签: ios swift

我试图添加重新排序tableview单元格的LongPressGesture方法。但是当我在模拟器中运行应用程序时,它会在我按下一个单元格进行重新排序后冻结,而我无法弄清楚导致它的原因。

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

更新了这一行:

让longpress = UILongPressGestureRecognizer(动作:#selector(self.longPressGestureRecognized(_:)))

现在收到错误:类型的值' ViewController'没有会员' longPressGestureRecognized' ....这很奇怪,因为下一个代码是func longPressGestureRecognized(gestureRecognizer:UIGestureRecognizer)。

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

let cell = self.tableView.cellForRow(at: Path.initialIndexPath!) as! UITableViewCell 

给出错误:来自&UTSableViewCell的强制演员?'到' 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))

0 个答案:

没有答案