UIImageView错误旋转使用CGAffineTransform

UIImageView wrong rotation using CGAffineTransform

我有 4 个部分,每个部分有 2 个嵌套行。我通过点击每个部分打开行。

当我点击一个部分时,我希望它的附件(chevron.right,制作为 UIImageView)顺时针旋转 90 度,动画流畅,当我再次点击同一部分时 -向后逆时针旋转 90 度。

我有一个名为 isOpened 的变量(bool,默认情况下为 false),我将其从 false 更改为 true 并在 didSelectRowAt 中每次点击后退。基于此显示所有嵌套单元格:

   override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      if indexPath.row == 0 {
        sections[indexPath.section].isOpened = !sections[indexPath.section].isOpened
        tableView.reloadSections([indexPath.section], with: .none)
      }
   }

我尝试用同样的方法旋转人字形:

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.row == 0 {
        sections[indexPath.section].isOpened = !sections[indexPath.section].isOpened
        tableView.reloadSections([indexPath.section], with: .none)
        
        guard let cell = tableView.cellForRow(at: indexPath) as? MainSortTableViewCell else { return }

        if sections[indexPath.section].isOpened {
            UIView.animate(withDuration: 1.0) {
                cell.chevronImage.transform = CGAffineTransform(rotationAngle: .pi/2)
            }
        } else {
            UIView.animate(withDuration: 1.0) {
                cell.chevronImage.transform = CGAffineTransform(rotationAngle: -.pi/2)
            }
        }
     }

但是使用这种方法我遇到了几个问题:

  1. 虽然第一次点击它会根据需要将人字形动画向下 90 度,但是当我再次点击时 - 它会旋转 initial 人字形(面向右侧),结果如下雪佛龙改为查找 (-pi/2)。如何修复此行为并从其新位置旋转人字形(从其面朝下回到初始右侧)?
  2. 当我在第一次旋转后尝试点击时,动画将永远不会再次触发。过渡是立即的。如何解决?

这是一个包含问题行为的 GIF:CLICK

您误解了 transform 属性 的意思。 transform 表示视图从其 原始 位置(在本例中面向右)的变换,因此将其设置为 CGAffineTransform(rotationAngle: -.pi / 2) 会使视图变换成这样一种从 原始 位置旋转 -.pi / 2 弧度的方式,即面朝上。

要实现所需的旋转,您可以将此-.pi/2旋转与视图的当前变换组合,或者只需将transform设置为.identity(完全没有变换,从原来的位置开始):

cell.chevronImage.transform = .identity
// or
cell.chevronImage.transform = cell.chevronImage.transform.rotated(by: -.pi / 2)

我怀疑您没有在 cellForRowAtIndexPath 中添加这个旋转代码。 请这样做, 只是没有动画。否则,您会 运行 遇到滚动 table 视图 (see also) 后人字形重置等问题。但是,这意味着当您调用 reloadSections 时,它会旋转得太早。解决这个问题最简单的方法是在动画之后移动reloadSections

UIView.animate(withDuration: 1.0) {
    if sections[indexPath.section].isOpened {
        cell.chevronImage.transform = CGAffineTransform(rotationAngle: .pi/2)
    } else {
        cell.chevronImage.transform = .identity
    }
} completion: {_ in
    self.tableView.reloadSections([indexPath.section], with: .none)
}