How to resize a tableHeaderView of a UITableView?

后端 未结 19 2209
死守一世寂寞
死守一世寂寞 2020-11-29 16:14

I\'m having trouble resizing a tableHeaderView. It simple doesn\'t work.

1) Create a UITableView and UIView (100 x 320 px);

2) Set the UIView as tableHeaderV

相关标签:
19条回答
  • 2020-11-29 16:59

    If custom headerView is designed using autolayout and headerView needs to be updated after web-fetch or similar lazy task. then in iOS-Swift I did this and got my headerView updated using bellow code:

    //to reload your cell data
    self.tableView.reloadData()
    dispatch_async(dispatch_get_main_queue(),{
    // this is needed to update a specific tableview's headerview layout on main queue otherwise it's won't update perfectly cause reloaddata() is called
      self.tableView.beginUpdates()
      self.tableView.endUpdates()
    } 
    
    0 讨论(0)
  • 2020-11-29 17:00

    On iOS 9.x, doing this on viewDidLoad works just fine:

    var frame = headerView.frame
    frame.size.height = 11  // New size
    headerView.frame = frame
    

    headerView is declared as @IBOutlet var headerView: UIView! and connected on the storyboard, where it is placed at the top of the tableView, to function as the tableHeaderView.

    0 讨论(0)
  • 2020-11-29 17:01

    If you want to conditionally animate the changes you can do the following:

    - (void) showHeader:(BOOL)show animated:(BOOL)animated{
    
        CGRect closedFrame = CGRectMake(0, 0, self.view.frame.size.width, 0);
        CGRect newFrame = show?self.initialFrame:closedFrame;
    
        if(animated){
            // The UIView animation block handles the animation of our header view
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.3];
            [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    
            // beginUpdates and endUpdates trigger the animation of our cells
            [self.tableView beginUpdates];
        }
    
        self.headerView.frame = newFrame;
        [self.tableView setTableHeaderView:self.headerView];
    
        if(animated){
            [self.tableView endUpdates];
            [UIView commitAnimations];
        }
    }
    

    Please note that the animation is two-folded:

    1. The animation of the cells below the tableHeaderView. This is done using beginUpdates and endUpdates
    2. The animation of the actual header view. This is done using a UIView animation block.

    In order to synchronize those two animations the animationCurve has to be set to UIViewAnimationCurveEaseInOut and the duration to 0.3, which seems to be what the UITableView uses for it's animation.

    Update

    I created an Xcode project on gihub, which does this. Check out the project ResizeTableHeaderViewAnimated in besi/ios-quickies

    screenshot

    0 讨论(0)
  • 2020-11-29 17:02

    Obviously, by now Apple should have implemented UITableViewAutomaticDimension for tableHeaderView & tableFooterView...

    The following seems to work for me using layout contraint(s):

    CGSize   s  = [ self  systemLayoutSizeFittingSize : UILayoutFittingCompressedSize ];
    CGRect   f  = [ self  frame ];
    
    f.size   = s;
    
    [ self  setFrame : f ];
    
    0 讨论(0)
  • 2020-11-29 17:03

    I have implemented animated height change of the table's header to expand to overall screen when tapped. However, the code can help in other cases:

    // Swift
    @IBAction func tapped(sender: UITapGestureRecognizer) {
    
        self.tableView.beginUpdates()       // Required to update cells. 
    
        // Collapse table header to original height
        if isHeaderExpandedToFullScreen {   
    
            UIView.animateWithDuration(0.5, animations: { () -> Void in
                self.scrollView.frame.size.height = 110   // original height in my case is 110
            })
    
        }
        // Expand table header to overall screen            
        else {      
            let screenSize = self.view.frame           // "screen" size
    
            UIView.animateWithDuration(0.5, animations: { () -> Void in
                self.scrollView.frame.size.height = screenSize.height
            })
        }
    
        self.tableView.endUpdates()  // Required to update cells. 
    
        isHeaderExpandedToFullScreen= !isHeaderExpandedToFullScreen  // Toggle
    }
    
    0 讨论(0)
  • 2020-11-29 17:05

    This is only for when you use auto-layout and set translatesAutoresizingMaskIntoConstraints = false to a custom header view.

    The best and the simplest way is to override intrinsicContentSize. Internally UITableView uses intrinsicContentSize to decide its header/footer size. Once you have override intrinsicContentSize in your custom view, What you need to do is as below

    1. configure the custom header/footer view's layout(subviews)
    2. invoke invalidateIntrinsicContentSize()
    3. invoke tableView.setNeedsLayout() and tableView.layoutIfNeeded()

    Then the UITableView's header/footer will be updated as you want. No need to set the view nil or reset.

    One thing really interesting for the UITableView.tableHeaderView or .tableFooterView is that UIStackView loose its ability to manage its arrangedSubviews. If you want to use UIStackView as a tableHeaderView or tableFooterView, you have to embed the stackView in a UIView and override UIView's intrinsicContentSize.

    0 讨论(0)
提交回复
热议问题