【问题标题】:Why are my collectionview cells not animating?为什么我的 collectionview 单元格没有动画?
【发布时间】:2020-12-30 20:30:11
【问题描述】:

我有集合视图单元格,我想同时为所有单元格设置动画。即使我使用UIView.animate,动画也不会发生,并且仿射变换会立即发生。

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    var collectionview: UICollectionView!
    var moveText: Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionview = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
        collectionview.translatesAutoresizingMaskIntoConstraints = false
        collectionview.dataSource = self
        collectionview.delegate = self
        collectionview.backgroundColor = .systemBackground
        collectionview.register(MyCell.self, forCellWithReuseIdentifier: "cell")
        view.addSubview(collectionview)
        
        NSLayoutConstraint.activate([
            collectionview.topAnchor.constraint(equalTo: view.topAnchor),
            collectionview.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            collectionview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            collectionview.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
        cell.moveText = moveText
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return .init(width: collectionview.frame.width, height: 120)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { timer in
            UIView.animate(withDuration: 1, delay: 0) {
                print("Starting animatings")
                self.moveText = !self.moveText
                self.collectionview.reloadData()
            }
        }
    }
    
}

class MyCell: UICollectionViewCell {
    
    let label = UILabel()
    var moveText: Bool = false {
        didSet {
            if moveText == true {
                label.transform = CGAffineTransform(translationX: 50, y: 50)
            } else {
                label.transform = CGAffineTransform(translationX: 0, y: 0)
            }
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        label.text = "mytext"
        label.translatesAutoresizingMaskIntoConstraints = false
        addSubview(label)
        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: leadingAnchor),
            label.topAnchor.constraint(equalTo: topAnchor)
        ])
        backgroundColor = .orange
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

【问题讨论】:

    标签: swift uikit uicollectionviewcell uicollectionviewlayout


    【解决方案1】:

    这是因为您制作了错误的动画。

    // adding weak self so the timer will not retain the view controller
    Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { [weak self] timer in
        self?.moveText.toggle() // you can use toggle() on a `Bool`
        self?.collectionview.reloadData()
    }
    

    相反,您应该尝试用动画设置单个单元格的值

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
        UIView.animate(withDuration: 1, delay: 0) {
            cell.moveText = self.moveText
        }
        return cell
    }
    

    另外,您可以使用.identity,而不是使用CGAffineTransform(translationX: 0, y: 0)

    label.transform = .identity
    

    值得注意的是,每 2 秒重新加载一次集合视图并直接在 cellForItemAt 中制作动画是非常低效的。您应该找到另一种将信息传递给单元格的方法,它们应该为内容设置动画

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      相关资源
      最近更新 更多