【问题标题】:How to animate UITableView header view如何为 UITableView 标题视图设置动画
【发布时间】:2013-05-13 09:19:09
【问题描述】:

我需要为 tableview 标题视图的插入设置动画。我希望表格行在标题视图展开其框架时向下滑动。
到目前为止,我得到的最好结果是使用以下代码:

[self.tableView beginUpdates];  
[self.tableView setTableHeaderView:self.someHeaderView];  
[self.tableView endUpdates];

这个解决方案的问题是标题本身没有动画,它的框架没有展开。

所以我得到的效果是表格行向下滑动(如我所愿)但标题视图立即显示,我希望它用动画扩展它的框架。

有什么想法吗?

谢谢。

【问题讨论】:

标签: iphone ios objective-c uitableview core-animation


【解决方案1】:

标题帧位于CGRectZero 并使用动画设置其框架

[self.tableView beginUpdates];  
[self.tableView setTableHeaderView:self.someHeaderView];  

[UIView animateWithDuration:.5f animations:^{
  CGRect theFrame = someBigger.frame;
  someHeaderView.frame = theFrame;
}];

[self.tableView endUpdates];  

【讨论】:

  • 不起作用,看起来如果您将表格的标题设置为高度为零的视图,那么无论您稍后更改此视图高度,表格的标题都不会改变..
  • 然后尝试增加动画中 TableHeaderView 的高度,而不是 someHeaderView 框架
  • 不需要beginUpdatesendUpdates 调用。
  • 如果你也想移动 tableView 的行和页脚(你几乎肯定会这样做),你可以使用begin/endUpdates 或重新设置tableView.tableViewHeader = tableView.tableViewHeader 来触发它(不仅仅是框架)。
  • 对我来说,它只有在我包含 beginUpdatesendUpdates 调用时才有效。 iOS 9
【解决方案2】:

这是我在 Swift 中的工作,初始帧高度为零,并在动画闭包中将其更新为全高:

// Calculate new frame size for the table header
var newFrame = tableView.tableHeaderView!.frame
newFrame.size.height = 42

// Get the reference to the header view
let tableHeaderView = tableView.tableHeaderView

// Animate the height change
UIView.animate(withDuration: 0.6) {
    tableHeaderView.frame = newFrame
    self.tableView.tableHeaderView = tableHeaderView
})

【讨论】:

  • 这对我有用。为了使标题大小和 tableCell 移动动画同步,我必须使用 0.3 的 animationDuration。在 iOS 9 上。
  • 在动画块中重新分配 tableHeaderView 也对我有用。这应该是公认的答案。
【解决方案3】:

所选答案对我不起作用。必须执行以下操作:

[UIView animateWithDuration: 0.5f
                 animations: ^{
                     CGRect frame = self.tableView.tableHeaderView.frame;
                     frame.size.height = self.headerViewController.preferredHeight;
                     self.tableView.tableHeaderView.frame = frame;
                     self.tableView.tableHeaderView = self.tableView.tableHeaderView;
                   }];

真正特别的部分是,这适用于一个视图,但不适用于同一视图控制器/视图层次结构的子类。

【讨论】:

  • 为什么需要self.tableView.tableHeaderView = self.tableView.tableHeaderView;?没有这条看似多余的线,它就行不通。
  • @OpenUserX03 同意这是多余的,但需要重置框架才能为我工作。
  • @OpenUserX03 我看到了同样的东西,我必须重新设置tableHeaderView 才能让tableView 注意到新的大小。他们可能在didSet 中做了一些事情,因为它是一个类引用,而不是一个结构,所以只是一个指向相同位置的指针。 stackoverflow.com/questions/16518580/…
【解决方案4】:

我找到了在tableHeaderViews 上实现真实动画的明确且正确的方法!

• 首先,如果您在Autolayout 中,请将Margin 系统保留在标题视图中。有了 Xcode 8,它现在成为可能(终于!),只是不要对任何标题子视图设置任何约束。您必须设置正确的边距。

• 然后使用beginUpdatesendUpdates,但将endUpdate 放入动画块中。

// [self.tableView setTableHeaderView:headerView]; // not needed if already there
[self.tableView beginUpdates]; 
CGRect headerFrame = self.tableView.tableHeaderView.bounds;
headerFrame.size.height = PLAccountHeaderErrorHeight;

[UIView animateWithDuration:0.2 animations:^{
    self.tableView.tableHeaderView.bounds = headerFrame;

    [self.tableView endUpdates];
}];

注意:我只在iOS10中尝试过,我会在下载iOS9模拟器时发布更新。

编辑

不幸的是,它在 iOS9 和 iOS10 中都不起作用:标题本身不会改变它的高度,但标题子视图似乎会移动,就好像标题边界发生了变化一样。

【讨论】:

    【解决方案5】:

    带有不同标题的 SWIFT 4 解决方案

    如果你想要这种动画,那就是我使用的解决方案:(尽管在我的情况下,我还必须对对象的不透明度进行一些调整,因为我正在加载另一个完全不同的标题)

    fileprivate func transitionExample() {
    
        let oldHeight = tableView.tableHeaderView?.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height ?? 0
    
        let newHeader = YourCustomHeaderView()
        newHeader.hideElements() // If you want to play with opacity.
    
        let smallHeaderFrame = CGRect(x: 0, y: 0, width: newHeader.frame.width, height: oldHeight)
        let fullHeaderFrame = newHeader.frame
    
        newHeader.frame = smallHeaderFrame
    
        UIView.animate(withDuration: 0.4) { [weak self] in
            self?.tableView.beginUpdates()
            newHeader.showElements() // Only if have hided the elements before.
            self?.tableView.tableHeaderView = newHeader
            self?.tableView.tableHeaderView?.frame = fullHeaderFrame
            self?.tableView.endUpdates()
        }
    }
    

    所以,基本上,这都是关于更改 .animate 闭包内的框架。为了移动和更新 tableView 的其他元素,需要开始/结束更新。

    【讨论】:

      【解决方案6】:

      这是一个 Swift 5 UITableView 扩展,用于更改 headerView 或更改其高度,使用 AutoLayout 动画

      extension UITableView {
      
      func animateTableHeader(view: UIView? = nil, frame: CGRect? = nil) {
          self.tableHeaderView?.setNeedsUpdateConstraints()
          UIView.animate(withDuration: 0.2, animations: {() -> Void in
              let hView = view ?? self.tableHeaderView
              if frame != nil {
                  hView?.frame = frame!
              }
              self.tableHeaderView = hView
              self.tableHeaderView?.layoutIfNeeded()
          }, completion: nil)
      }
      

      }

      【讨论】:

        【解决方案7】:

        对我来说,在没有任何明确的动画块或操作帧的情况下使用自动布局时它是动画的。

        // `tableHeaderViewHeight` is a reference to the height constraint of `tableHeaderView`
        tableHeaderViewHeight?.constant = .leastNormalMagnitude
        
        tableView.beginUpdates()
        tableView.tableHeaderView = tableHeaderView
        tableHeaderView.layoutIfNeeded()
        tableView.endUpdates()
        

        【讨论】:

          【解决方案8】:

          使用下面的代码就可以了

          extension UITableView {
          
           func hideTableHeaderView() -> Void {
              self.beginUpdates()
              UIView.animate(withDuration: 0.2, animations: {
                  self.tableHeaderView = nil
              })
              self.endUpdates()
          }
          
          func showTableHeaderView(header: UIView) -> Void {
              let headerView = header
              self.beginUpdates()
              let headerFrame = headerView.frame
              headerView.frame = CGRect()
              self.tableHeaderView = headerView
              UIView.animate(withDuration: 0.2, animations: {
                  self.tableHeaderView?.frame = headerFrame
                  self.tableHeaderView?.alpha = 0
                  self.endUpdates()
              }, completion: { (ok) in
                  self.tableHeaderView?.alpha = 1
              })
             }
          }
          

          【讨论】:

            猜你喜欢
            • 2011-11-12
            • 2015-09-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多