Content size issue for UITableView in UIscrollView

2019-02-03 18:56发布

问题:

I actually create a UIScrollView with a UITableView inside it with interface builder. I set the content size of my UIScrollView with:

scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);

and I set my file's owner view to the UIScrollView

I created an IBOutlet UITableView and I set it in the interface builder.

When the view is loaded. it displays the correct content size for my UIScrollView. But it doesn't display the correct content size for my UITableView. Besides when I change the content size of my UIScrollView, it changes the content size of my UITableView as if both content size were related.

Anyone knows how can I keep the content size of my table view that I set in the interface builder?

回答1:

A UITableView is a UIScrollView. There are very few times when it would be useful to embed a UITableView inside a UIScrollView.

Assuming you really do want this, you'll need to do the following somewhere. Probably in your UIViewController in methods like viewDidAppear: or somewhere you after you populate the table view.

// Set the size of your table to be the size of it's contents 
// (since the outer scroll view will handle the scrolling).
CGRect tableFrame = tableView.frame;
tableFrame.size.height = tableView.contentSize.height;
tableFrame.size.width = tableView.contentSize.width; // if you would allow horiz scrolling
tableView.frame = tableFrame;

// Set the content size of your scroll view to be the content size of your 
// table view + whatever else you have in the scroll view.
// For the purposes of this example, I'm assuming the table view is in there alone.
scrollView.contentSize = tableView.contentSize;


回答2:

Example to dynamically manage the TableView Height along with ScrollView, works in Swift:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Custom Cell
        let cell:TblPortCell = self.tableList.dequeueReusableCellWithIdentifier("cell") as! TblPortCell

        //tableList is the OutLet for the table
        tableList.sizeToFit()
        // Set the size of the table to be the size of it's contents
        // (since the outer scroll view will handle the scrolling).
        let height = tableList.frame.size.height
        let pos = tableList.frame.origin.y
        let sizeOfContent = height + pos + 130
        //scrollView is the Outlet for the Scroll view
        scrollView.contentSize.height = sizeOfContent
        scrollView.sizeToFit()

        cell.selectionStyle = UITableViewCellSelectionStyle.None
        return cell
    }

References to:

  • Setting the ContentSize for ScrollView based in TableView ContentSize.
  • You must use sizeToFit before using contentSize.


回答3:

If you're still having problems, try this without the need for a scrollView.

After playing around with DBD's example for awhile, I found that the frame and contentSize don't seem to be able to be set together like:

self.tableView.contentSize = CGSizeMake(320, scrollHeight);
self.tableView.frame = CGRectMake(self.tableView.frame.origin.x,44,self.tableView.contentSize.width,self.tableView.contentSize.height);

The attempt was to set a max height of the frame but keep the ability to scroll though all of the content if there were a large number of cells. This hack seems to work well and can be modified with more conditions if needed:

int cellCount = [YOURARRAY count];
CGFloat scrollHeight = cellCount*44+44;//for a cell with height of 44 and adding 44 if you have a toolbar at the bottom

self.tableView.contentSize = CGSizeMake(320, scrollHeight);//you can change the width and or let the .xib control the autoresizing

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && cellCount < 14)
{
    //here's were you can add more conditions if you're in landscape or portrait, but this handles 14 cells with a heightForHeaderInSection of 46 in landscape
    self.tableView.frame = CGRectMake(self.tableView.frame.origin.x,44,self.tableView.contentSize.width,scrollHeight);
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && cellCount < 7)
{
     //same as above but it's for the iPhone in portrait
     self.tableView.frame = CGRectMake(self.tableView.frame.origin.x,44,self.tableView.contentSize.width,scrollHeight);
}

This works for sure. You might need to adjust the autoresizingMask inside your .xib or in your code, but this hack is the only solution I found that takes care of all the different variables in my case.



回答4:

Call below method multiple times. Each time you call there will be more cells.

CGRect tableFrame = tableView.frame;
tableFrame.size.height = tableView.contentSize.height;
tableView.frame = tableFrame;

scrollView.contentSize = tableView.contentSize;