【问题标题】:Animating the TableView cell using CGAffineTransformScale upon tap and remove the animation upon tableView scroll在点击时使用 CGAffineTransformScale 为 TableView 单元格设置动画,并在 tableView 滚动时删除动画
【发布时间】:2017-12-31 08:29:05
【问题描述】:

如何为点击的 tableView 单元格设置动画,并像使用 CGAffineTransformScale 一样为其设置动画,并在 tableView 滚动时删除动画。如果单元格点击事件我需要调用 didSelect tableView 单元格方法。

CustomTableViewCell 类

import UIKit

class CustomTableViewCell: UITableViewCell {

    @IBOutlet weak var cellDataView: UIView!

    var longTapCallback: ((_ success: Bool) -> Void)?

    override func awakeFromNib() {
        super.awakeFromNib()
        self.setLongTapGuesture()
    }

    func setLongTapGuesture() {
        let guesture = UILongPressGestureRecognizer(target: self, action: #selector(CustomTableViewCell.lognTaponCell))
        self.contentView.addGestureRecognizer(guesture)
    }

    @objc func lognTaponCell(guesture: UILongPressGestureRecognizer) {
        if guesture.state != .ended {
            self.longTapCallback?(true)
        } else {
            self.longTapCallback?(false)
        }
    }
}

ViewController 类

import UIKit

class AnimationTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as? CustomTableViewCell

        cell?.longTapCallback = { (success) in
            if success {
                self.selectedIndexPath = indexPath
                self.startLongTapGuesture(atCell: cell!)

            } else {
                self.stopLongTapGuesture(atCell: cell!)
            }
        }
        return cell!
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Did Select Called")
    }
}

extension AnimationTableViewController {

    func startLongTapGuesture(atCell cell: CustomTableViewCell) {

        UIView.animate(withDuration: 0.0, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 6, options: .beginFromCurrentState, animations: {

        }, completion: { (finished) in
            cell.contentView.transform = CGAffineTransform.init(scaleX: 1.6, y: 1.6)
    })
}

func stopLongTapGuesture(atCell cell: CustomTableViewCell) {

    UIView.animate(withDuration: 0.0, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 6, options: [], animations: {

    }, completion: { (finished) in
        cell.contentView.transform = CGAffineTransform.init(scaleX: 1, y: 1)
    })
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 120.0
}}

模拟器截图:

【问题讨论】:

  • 您的问题到底是什么?您需要弄清楚长按时如何触发 didSelectRowAt ?就这些吗??
  • 我需要像在 AppStore 应用程序中一样为点击的单元格设置动画,当单元格被长按时,它将显示 Tapped-In 动画,直到我们滚动或者如果我们不滚动它将被重定向到相应的页面,这就是我想要实现的。
  • 虽然我不完全确定您在谈论哪个动画,但您可以通过在单元格的 prepareForReuse 方法中调用 self.longTapCallback?(false) 来停止添加的动画,以便动画在单元格被重用之前停止。最后,如果您想以编程方式触发 didSelectRowAt,您始终可以在此处触发stackoverflow.com/questions/18245441/…,如果您的意图是在 tableView 滚动后立即停止动画,您可以使用 UIScrollView 的 scrollViewDidScroll 委托并在所有可见单元格上调用 stopLongTapGuesture
  • 我尝试使用 scrollViewDidScroll 方法来停止动画,但是在这种方法中我将无法访问单元格 (indexPath) 来停止当前应用的动画,我尝试存储选定的单元格索引路径但是它不会工作。
  • 你不需要 :) 当 scrollViewDidScroll 被调用时获取可见范围内的 indexPath ,这将为你提供一个 indexPath 数组,当前可见的迭代它(它会受到限制,所以不要担心 :))使用 indexPath 的单元格,然后在单元格上调用 stopLongTapGuesture :) 虽然我必须添加简单但不是很有效的方法,但肯定会完成你的工作:)

标签: ios swift uitableview


【解决方案1】:

正如我上面提到的,我使用闭包回调来获取 TableViewCell 上的长按手势。

我的场景:

  1. 我需要为单元格设置动画,直到用户点击单元格
  2. 一旦用户停止持有单元格,我需要调用 didSelectRowAtIndexPath 方法。
  3. 如果检测到 TableView 滚动,我将通过迭代 scrollViewDidScroll 方法中的可见单元格来移除应用于单元格对象的动画,如下所示。

    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
       let cellsArray = self.tableView.visibleCells
           for cell in cellsArray {
              UIView.animate(withDuration: 0.0, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 6, options: [], animations: {
    
        }, completion: { (finished) in
            cell.contentView.transform = CGAffineTransform.init(scaleX: 1, y: 1)
        })
    }}
    

我已经修改了 cellForRowAtIndexPath 方法,如下所示:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as? CustomTableViewCell

    cell?.longTapCallback = { (success) in
        if success {

            //Identifies the Long Tap on the Cell.
            self.startLongTapGuesture(atCell: cell!)

        } else {
            //Identifies the Release of Long tap on Cell.
            self.tableView(self.tableView, didSelectRowAt: indexPath)
        }
    }
    return cell!
}

这与 AppStore 应用程序类似。感谢您以Mr.Sandeep Bhandari's 的形式提供有用的想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2015-09-05
    相关资源
    最近更新 更多