【问题标题】:UIView.animation of transformation property doesn't work on UITableViewCell转换属性的 UIView.animation 在 UITableViewCell 上不起作用
【发布时间】:2021-07-05 01:58:07
【问题描述】:

我创建了一个带有视图控制器的项目,该项目设置为初始项目。还有另一个视图控制器,它是 UITableViewController 的子类,它呈现 UITableViewCell 的子类,它有一个图像视图的出口。

初始视图控制器上的按钮显示表格视图控制器,该控制器在“willDisplayCell”方法中设置单元格图像出口的转换属性的动画。当 tableview 显示为卡片时它不起作用(modalPresentationStyle == .automatic),它在 modalPresentationStyle == .fullScreen 时起作用

这是一个 UIKit 错误吗?我的配置是 Xcode 12.4 (iOS 14.4)

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "cel") as? CustomCell {
        fatalError()
    }

    UIView.animate(withDuration: 0.2, delay: 0, options: [.repeat, .autoreverse]) {
        cell.customImage.transform = .init(scaleX: 1.2, y: 1.2)
    }
}

class CustomCell {
    @IBOutlet private(set) var customImage: UIImageView!
}

【问题讨论】:

    标签: ios uitableview uikit uiviewanimation


    【解决方案1】:

    不要在此处将另一个单元格出列 - 您已经在方法签名中获得了该单元格。出队是为了当你想从重用池中获取一个单元格对象以返回tableView(_: cellForRow at:)

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        UIView.animate(withDuration: 0.2, delay: 0, options: [.repeat, .autoreverse]) {
            (cell as? CustomCell)?.customImage.transform = .init(scaleX: 1.2, y: 1.2)
        }
    }
    

    【讨论】:

    • 是的,你是对的,但这不是问题的根源,不这样做也不是解决方案
    【解决方案2】:

    首先,不要dequeue 一个新单元格——该函数已经为您提供了对带有这部分签名的单元格的引用:

    willDisplay cell: UITableViewCell
    

    但是,您遇到了一些怪癖。我不确定,但似乎当使用.automatic 作为演示风格时,UIView.animate(...) 调用正在作用于presenting 控制器,而不是 呈现的 控制器。可能是因为 UIKit 在不同的时间点生成表格。

    让您的动画工作的一种方法是确保调用发生在视图层次结构完全完成之后。

    试试这样:

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let c = cell as? CustomCell {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
                UIView.animate(withDuration: 0.2, delay: 0, options: [.repeat, .autoreverse]) {
                    c.customImage.transform = .init(scaleX: 1.2, y: 1.2)
                }
            })
        }
    }
    

    快速测试表明,如果表格视图有效:

    • 是根视图控制器,或者
    • 被推送到导航堆栈,或
    • 显示为.automatic,或
    • 显示为.fullScreen

    编辑 - 更多讨论...

    使用.automatic.fullScreen 进行演示是有区别的。

    特别是使用.automatic,当您在呈现控制器中关闭呈现的视图控制器viewDidAppear()时,不会被调用.

    因此,整体视图/控制器层次结构并不是我们所期望的,并且(显然)影响了我们在这里尝试做的事情。

    值得注意的是...如果我们不延迟UIView.animate(...) 调用,每个单元格中的customImage 会显示转换为1.2 比例

    所以,看起来正在发生的事情是……当 UIKit 配置、渲染和显示模态视图控制器时,这行代码被执行:

    c.customImage.transform = .init(scaleX: 1.2, y: 1.2)
    

    然后[.repeat, .autoreverse] 动画将图像视图从1.2 缩放到1.2 并再次缩放(而不是从1.01.2)...所以我们看不到任何视觉变化.

    【讨论】:

    • "...表格在不同的时间点。"你能发展出这部分答案吗?
    • @BlazejSLEBODA - 请参阅我的回答中的 Edit
    猜你喜欢
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 2020-10-16
    • 2021-11-03
    • 2016-02-13
    • 2014-11-25
    • 2019-03-31
    • 2018-08-22
    相关资源
    最近更新 更多