ios - CollectionViewCell 内向上移动标签动画

标签 ios swift animation uicollectionview

我水平滚动 CollectionView 单元格数量未知,它占据了除导航栏之外的整个屏幕。还有 CollectionViewCell,它占用整个 CollectionView。另外,在这个单元格内,我将 UIView 居中,其中包含一些标签和一个按钮。这就是我的用户界面的样子:click

每当用户单击此 UIView 内的按钮时,标签就会向上移动一点,并且所有其他标签也变得可见。如果此模式已激活,按钮将以相反的方式工作:

class WordCell: UICollectionViewCell {

    var isActive = false
@IBOutlet weak var word: UILabel!
    @IBOutlet weak var translation: UILabel!
    @IBOutlet weak var exOne: UILabel!
    @IBOutlet weak var exTwo: UILabel!

// ...

@IBAction func move(_ sender: UIButton) {
        if !isActive {
        UIView.animate(withDuration: 0.25, animations: {
            self.word.frame.origin.y -= self.bounds.height / 7
        }, completion: nil)
            UIView.animate(withDuration: 0.3, animations: {
                self.translation.alpha = 1
                self.exOne.alpha = 1
                self.exTwo.alpha = 1
            })
            isActive = true
        } else {
            UIView.animate(withDuration: 0.25, animations: {
                self.word.frame.origin.y += self.bounds.height / 7
            }, completion: nil)
            UIView.animate(withDuration: 0.3, animations: {
                self.translation.alpha = 0
                self.exOne.alpha = 0
                self.exTwo.alpha = 0
            })
        isActive = false
        }
    }
}

之后我的用户界面如下所示:click

我的 CollectionView 代码:

    // CollectiomView Delegate stuff, in the code above I just retrieve data from FireBase
extension RepeatController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return words.count
        }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "wordCell", for: indexPath) as! WordCell
        if words[0].lPairs == "re" {
            cell.word.text = words[indexPath.row].translation
            cell.translation.text = words[indexPath.row].word

        } else {
            cell.word.text = words[indexPath.row].word
            cell.translation.text = words[indexPath.row].translation
        }
        cell.exOne.text = words[indexPath.row].exOne
        cell.exTwo.text = words[indexPath.row].exTwo
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let bounds = collectionView.bounds
        return CGSize(width: bounds.width, height: bounds.height)
    }

}

问题:

仅当我单击按钮两次(向上移动标签,然后将其返回到相同位置并隐藏所有其他标签)时,该系统才起作用。否则,在 2-3 个单元格之后,所有其他标签都会变得可见,并且主标签位于顶部,就像我在每个单元格的按钮上键入(但我没有)一样。问题是什么?

最佳答案

由于更改是在 UI 中,所以首先我认为您应该首先将动画代码放入 DispatchQueue.main.async block

然后,由于您使用的是可重用的 Collection View 单元格,因此您在动画代码中更改的值对于重用的单元格保持不变,因此为了在 Collection View 重用这些值之前为这些值提供一些初始值,我们重写 prepareForReuse() 方法并在其中给出初始值。

使用文档 here 中的想法

When a view is dequeued for use, this method is called before the corresponding dequeue method returns the view to your code. Subclasses can override this method and use it to reset properties to their default values and generally make the view ready to use again

在代码中你可以这样做:

 @IBAction func move(_ sender: UIButton) {
            if !isActive {
                 DispatchQueue.main.async {
                          UIView.animate(withDuration: 0.25, animations: {
                          self.word.frame.origin.y -= self.bounds.height / 7
                          }, completion: nil)
                               UIView.animate(withDuration: 0.3, animations: {
                               self.translation.alpha = 1
                               self.exOne.alpha = 1
                               self.exTwo.alpha = 1
                          })

                  }
                          isActive = true
            } else {
                 DispatchQueue.main.async {
                         UIView.animate(withDuration: 0.25, animations: {
                         self.word.frame.origin.y += self.bounds.height / 7
                         }, completion: nil)
                         UIView.animate(withDuration: 0.3, animations: {
                               self.translation.alpha = 0
                               self.exOne.alpha = 0
                               self.exTwo.alpha = 0
                         })

                }
                isActive = false
            }
        }
    }

override func prepareForReuse() {

     super.prepareForReuse()

     self.word.frame.origin.y = self.wordTop.constant, //where wordTop is a top constraint for the word 
     isActive = false
     self.translation.alpha = 0
     self.exOne.alpha = 0
     self.exTwo.alpha = 0



}

关于ios - CollectionViewCell 内向上移动标签动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45589411/

相关文章:

iphone - 适用于 iOS 的 Xcode 项目自动化

ios - 如何使用带 PHFetchOptions 的 NSPredicate 按媒体子类型进行过滤

objective-c - 使用@package.何时以及如何使用它?

python - 如何在 wxpython 中使用 Matplotlib.animation?

c# - UIElement 的值更改后执行方法

ios - 为什么xcodebuild在使用xcworkspace构建时需要设置指定方案?

ios - 将 SCNNode 固定到位,无需 ARPlaneAnchor

ios - 将节点添加到子节点时不会调用 layoutSpecThatFits

swift - 如何在仍然接收点击事件的同时使 OS X 应用程序无法聚焦?

jquery - Css3 中的云动画循环