12
votes

I feel like this is going to be a simple answer revolving around AutoResizingMasks, but I can't seem to wrap my head around this topic.

I've got an iPad app that shows 2 UITableViews side-by-side. When I rotate from Portrait to Landscape and back, the cells in the UITableView resize perfectly, on-the-fly, while the rotation is occurring. I'm using UITableViewCellStyleSubtitle UITableViewCells (not subclassed for now), and I've set the UITableView up in IB to anchor to the top, left and bottom edges (for the left UITableView) and to have a flexible width.

I'm supplying my own UIView object for

- (UIView *)tableView:(UITableView *)tableView 
     viewForHeaderInSection:(NSInteger)section

Here's what I've got so far (called as a class method from another class):

+ (UIView *)headerForTableView:(UITableView *)tv
{
    // The view to return 
    UIView *headerView = [[UIView alloc] 
        initWithFrame:CGRectMake(0, 0, [tv frame].size.width, someHeight)];

    [headerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | 
                                    UIViewAutoresizingFlexibleLeftMargin | 
                                    UIViewAutoresizingFlexibleRightMargin];

    // Other layout logic... doesn't seem to be the culprit

    // Return the HeaderView
    return headerView;
}

So, in either orientation, everything loads up just like I want. After rotation, if I manually call reloadData or wait until my app triggers it, or scroll the UITableView, the headerViews will resize and show themselves properly. What I can't figure out is how to get the AutoResizeMask property set properly so that the header will resize just like the cells.

4
It's not clear to me from your question: is the issue that the headers' widths aren't changing with the table, that you expect their heights to change, or that the changes that happen aren't being animated with the table's rotation?Sixten Otto
I haven't viewed this in a long while, but one thing immediately jumped out at me upon review. I'm guessing that my problem was related to having flexible width AND flexible right and left margins. Who knows how to predict the horizontal resize behavior under such a scenario? I would bet that setting the AutoResizingMask to just flexible width would have been the answer. Again, though, as I said below, I've moved to a completely different solution.mbm29414

4 Answers

15
votes

Not a very good fix. But works :

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [mTableView reloadData];
}
5
votes

I faced the same issue recently. The trick was to use a custom view as the headerView of the table. Overriding layoutSubviews allowed me to control the layout at will. Below is an example.

#import "TableSectionHeader.h"

@implementation TableSectionHeader

- (id)initWithFrame:(CGRect)frame title:(NSString *)title
{
    self = [super initWithFrame:frame];
    if (self) {

        self.backgroundColor = [UIColor clearColor];

        // Initialization code
        headerLabel = [[UILabel alloc] initWithFrame:frame];
        headerLabel.text = title;

        headerLabel.textColor = [UIColor blackColor];
        headerLabel.font = [UIFont boldSystemFontOfSize:17];
        headerLabel.backgroundColor = [UIColor clearColor];

        [self addSubview:headerLabel];
    }
    return self;
}

-(void)dealloc {

    [headerLabel release];

    [super dealloc];
}

-(void)layoutSubviews {

    [super layoutSubviews];

    NSInteger xOffset = ((55.0f / 768.0f) * self.bounds.size.width);

    if (xOffset > 55.0f) {
        xOffset = 55.0f;
    }

    headerLabel.frame = CGRectMake(xOffset, 15, self.bounds.size.width - xOffset * 2, 20);
}

+(UIView *) tableSectionHeaderWithText:(NSString *) text bounds:(CGRect)bounds {
    TableSectionHeader *header = [[[TableSectionHeader alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, 40) title:text] autorelease];
    return header;
}

+(CGFloat) tableSectionHeaderHeight {
    return 40.0;
}
@end
0
votes

I'd love to get a real answer to this, but for now, I've just re-worked my UITableView so that my "headers" are just cells inside the table. Resizing has no issues that way.

0
votes

I have created UIView subclass where I've used visual constraints to stick the subview to the sides of the screen. And rotation is all fine.

class MLFlexibleView: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)

    self.addSubview(self.segmentedControl)
    self.setUpConstraints()
}

func setUpConstraints() {
    let views = ["view" : self.segmentedControl]

    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-7-[view]-7-|", options: [], metrics: nil, views: views))
    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-15-[view]-15-|", options: [], metrics: nil, views: views))
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

let segmentedControl:UISegmentedControl = {
    let segmentedControl = UISegmentedControl(items: ["Searches".localized, "Adverts".localized])
    segmentedControl.selectedSegmentIndex = 0
    segmentedControl.tintColor = UIColor.white
    segmentedControl.translatesAutoresizingMaskIntoConstraints = false
    return segmentedControl
}()

}