How to animate UITableView header view

南笙酒味 提交于 2019-12-18 12:28:13

问题


I need to animate the insertion of a tableview header view. I want that the table rows to slide down while the header view expands its frame.
So far the best result I got is by using the following code:

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

The problem with this solution is that the header itself doesn't get animated, its frame doesn't expand.

So the effect I'm getting is that the table rows slide down (as I want) but the header view is immediately shown, and I want it to expand it's frame with animation.

Any ideas?

Thanks.


回答1:


have the header frame at CGRectZero and set its frame using animation

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

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

[self.tableView endUpdates];  



回答2:


Here's what I got to work in Swift, with an initial frame height of zero and updating it to its full height in the animations closure:

// 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
})



回答3:


The selected answer didn't work for me. Had to do the following:

[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;
                   }];

The really peculiar part is that this works in one view but not in a subclass of the same view controller / view hierarchy.




回答4:


I found the definitive and proper way to achieve a real animation on tableHeaderViews!

• First, if you're in Autolayout, keep the Margin system inside your header view. With Xcode 8 its now possible (at last!), just do not set any constraint to any of the header subviews. You'll have to set the correct margins thought.

• Then use beginUpdates and endUpdates, but put endUpdate into the animation block.

// [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];
}];

Note: I only tried in iOS10, i'll post an update when my iOS9 simulator will be downloaded.

EDIT

Unfortunately, it doesn't work in iOS9 as well as iOS10: the header itself does not change its height, but header subviews seem to move as if the header bounds changed.




回答5:


SWIFT 4 SOLUTION w/ Different Header

If you want this kind of animation, that is the solution that I have used: (even though in my case I had also to play a bit with the opacity of the objects, since I was loading another completely different header)

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()
    }
}

So, basically, it's all about changing the frame inside the .animate closure. The beging/end updates is needed in order to move and update the other elements of the tableView.




回答6:


Here is a Swift 5 UITableView extension for changing the headerView or changing its height, animated using 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:


Use below code this works

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
    })
   }
}


来源:https://stackoverflow.com/questions/16518580/how-to-animate-uitableview-header-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!