How to animate UITableView header view

前端 未结 7 1422
旧巷少年郎
旧巷少年郎 2020-12-29 09:32

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 go

相关标签:
7条回答
  • 2020-12-29 10:00

    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.

    0 讨论(0)
  • 2020-12-29 10:05

    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.

    0 讨论(0)
  • 2020-12-29 10:06

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

    }

    0 讨论(0)
  • 2020-12-29 10:13

    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
        })
       }
    }
    
    0 讨论(0)
  • 2020-12-29 10:15

    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];  
    
    0 讨论(0)
  • 2020-12-29 10:23

    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
    })
    
    0 讨论(0)
提交回复
热议问题