Dynamic UITableView height

后端 未结 11 1566
無奈伤痛
無奈伤痛 2020-12-29 09:47

I would like to set the UITableView to match the height for all the contents in the table view.

This is my storyboard

The problem with this is the t

相关标签:
11条回答
  • 2020-12-29 10:08

    You need to set an IBOutlet to the NSLayoutConstraint that sets the tableView height (first you need create the height constraint with any value, doesn't matter) and then ctrl drag it to your class file

    Then in your viewWillAppear you have to calculate the tableView height and set it. Like this:

    var tableViewHeight:CGFloat = 0;
    for (var i = tableView(self.tableView , numberOfRowsInSection: 0) - 1; i>0; i-=1 ){
        tableViewHeight = height + tableView(self.tableView, heightForRowAtIndexPath: NSIndexPath(forRow: i, inSection: 0) )
    }
    tableViewHeightLayout.constant = tableViewHeight
    

    And that's pretty much it. That will give your scrollView content size and shouldn't raise any warnings.

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

    In that case, don't make your bottom cell static, make it a part of table view and insert this bottom image in last row using table view delegate method - insertRowAtIndexPath

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

    The answers using the subclassing technique are incomplete. You should also override layoutSubviews() like this.

    public class DynamicSizeTableView: UITableView
    {
        override public func layoutSubviews() {
            super.layoutSubviews()
            if bounds.size != intrinsicContentSize {
                invalidateIntrinsicContentSize()
            }
        }
    
        override public var intrinsicContentSize: CGSize {
            return contentSize
        }
    }
    
    0 讨论(0)
  • 2020-12-29 10:12

    You probably have to implement the table view intrinsic content size. Please check this answer to see if it helps.

    I remember having this problem and even created a custom UITableView subclass.

    #import "IntrinsicTableView.h"
    
    @implementation IntrinsicTableView
    
    #pragma mark - UIView
    
    - (CGSize)intrinsicContentSize
    {
        return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
    }
    
    #pragma mark - UITableView
    
    - (void)endUpdates
    {
        [super endUpdates];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)reloadData
    {
        [super reloadData];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
    {
        [super reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
    {
        [super reloadSections:sections withRowAnimation:animation];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
    {
        [super insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
    {
        [super insertSections:sections withRowAnimation:animation];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
    {
        [super deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];
        [self invalidateIntrinsicContentSize];
    }
    
    - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
    {
        [super deleteSections:sections withRowAnimation:animation];
        [self invalidateIntrinsicContentSize];
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-29 10:13
    1. Subclass your UITableView to override the intrinsicContentSize to be its contentSize, like this:

      override var intrinsicContentSize: CGSize {
          return contentSize
      }
      
    2. Then use automatic row heights for your table, so your exampleViewController's viewDidLoad would have:

      tableView.estimatedRowHeight = 44
      

      And the UITableViewDelegate function:

      func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
          return UITableViewAutomaticDimension
      }
      
    3. When you receive data from your API and reload your table, just call:

      tableView.invalidateIntrinsicContentSize()
      

      This will tell your table to resize itself to the same size as its contents (because of the override), and move your bottom image as needed.


    If your storyboard throws an error saying that your UIScrollView has an ambiguous height because there's no height constraint on the UITableView, select your UITableView and give it a placeholder intrinsic size in the Size Inspector.

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