Setting label in UITableView tableFooterView - auto-start

When my table view is empty, I want to add a simple label to the table footer to display the "no content" message. It worked great when I was setting the UILabel and UIView frameworks that I used for footerView, but now I am trying to convert them to use auto-layout and I cannot get it to work.

That's what I'm doing:

// Create the footer    
UIView *tempFooter = [[UIView alloc] init];
UILabel *atext = [[UILabel alloc] init];
tempFooter.translatesAutoresizingMaskIntoConstraints = NO;
atext.translatesAutoresizingMaskIntoConstraints = NO;

atext.numberOfLines = 0;
[atext setText:@"Add Some Text"];
atext.textAlignment = NSTextAlignmentCenter;
atext.font = [UIFont italicSystemFontOfSize:14];
atext.textColor = [UIColor grayColor];
atext.backgroundColor = [UIColor clearColor];
atext.lineBreakMode = NSLineBreakByWordWrapping;

// add label to footer view, and add constraints
[tempFooter addSubview:atext];
NSLayoutConstraint *tvatt1 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeLeft
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext attribute:NSLayoutAttributeLeft
                                                         multiplier:1.0
                                                           constant:10.0];

NSLayoutConstraint *tvatt2 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeRight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext
                                                          attribute:NSLayoutAttributeRight
                                                         multiplier:1.0
                                                           constant:10.0];

NSLayoutConstraint *tvatt3 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeTop
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext
                                                          attribute:NSLayoutAttributeTop
                                                         multiplier:5.0
                                                           constant:0];

NSLayoutConstraint *tvatt4 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeBottom
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1.0
                                                           constant: 0];

[tempFooter addConstraints: @[tvatt1, tvatt2, tvatt3, tvatt4]];


// set the footerview 
self.tview.tableFooterView = tempFooter;

      

When I run this I get a crash:

2014-09-08 19: 57: 16.594 SimpleList [49442: 60b] * Assertion error in - [UITableView layoutSublayersOfLayer:], / SourceCache / UIKit_Sim / UIKit-2935.137 / UIView.m: 8794 2014-09-08 19: 57: 21.073 SimpleList [49442: 60b] * Application terminated due to non-display exception "NSInternalInconsistencyException", reason: "Auto layout is still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews requires calling super

I'm not sure what I am doing wrong. I also tried setting limits self.tview.tableFooterView

on the tempFooter

(fix against all 4 sides), but that doesn't change the crash. I also call:

[self.tview.tableFooterView layoutSubviews];

      

but that doesn't help either.

Any ideas what I am doing wrong?

+3


source to share


5 answers


You shouldn't set translatesAutoresizingMaskIntoConstraints to NO on table views, their cells, or table header and footer views (or your controller's self.view, for that matter). It is okay to use constraints on the views within those views (cell content view or header and footer views). I added a simplified version of your code to viewDidLoad and it worked as expected. Note that you need to provide the footer with height and x position (y position and width are ignored),

    UIView *tempFooter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 50)];
    UILabel *atext = [[UILabel alloc] init];
    atext.translatesAutoresizingMaskIntoConstraints = NO;
    atext.numberOfLines = 0;
    [atext setText:@"Add Some Text"];
    atext.textAlignment = NSTextAlignmentCenter;
    atext.font = [UIFont italicSystemFontOfSize:14];
    atext.textColor = [UIColor grayColor];
    atext.backgroundColor = [UIColor clearColor];
    atext.lineBreakMode = NSLineBreakByWordWrapping;

    [tempFooter addSubview:atext];
    NSDictionary *dict = NSDictionaryOfVariableBindings(atext);
    [tempFooter addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[atext]-10-|" options:0 metrics:nil views:dict]];
    [tempFooter addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[atext]|" options:0 metrics:nil views:dict]];
    self.tableView.tableFooterView = tempFooter;

      



I'm not sure what you were trying to accomplish with your tvatt3 constraint. The multiplier (you have 5) doesn't do anything with the top or left constraint, since the value of those attributes is 0. I used visual constraints, not the method you used, but when I used your code to add constraints, it worked as well.

+10


source


I just came across an article that has a solution that works with Auto Layout: Dynamically Sizing Header or Footer Table Using Auto Layout from Collin Donnell



I tried this and it seems to work well.

+1


source


Interestingly, changing the Autoresizing mask in xib solved my problem.

Constraints don't work:

Does not work

IN:

Working

+1


source


hope this helps you

I'm not sure about this, but it helps me in my project, first add everything to contentView

(all subordinates and constraints)

 [self.contentView addSubview:atext]

      

and then the code comes

NSLayoutConstraint *tvatt1 = [NSLayoutConstraint constraintWithItem:tempFooter
                                                          attribute:NSLayoutAttributeLeft
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:atext attribute:NSLayoutAttributeLeft
                                                         multiplier:1.0
                                                           constant:10.0]; 

      

code for left attribute

 temfooter(must be equal) = 1.0*atext +10.0 

      

those. temfooter must be equal to the modified atext, so you need to make sure your constraints are not wrong.

0


source


I was able to dynamically increase the width and height of the layout table of the layout by implementing @ rdelmar's solution for constraints and adding the following lines below. The same solution applies to the view of the table header.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if let tableFooter = tableView.tableFooterView {
        let maxSize = CGSize(width: self.tableView.bounds.size.width,
                             height: CGFloat.greatestFiniteMagnitude)
        let size = tableFooter.systemLayoutSizeFitting(maxSize)
        let height = size.height
        var headerFrame = tableFooter.frame

        // If we don't have this check, viewDidLayoutSubviews() will get
        // repeatedly, causing the app to hang.
        if height != headerFrame.size.height {
            headerFrame.size.height = height
            tableFooter.frame = headerFrame
            tableView.tableFooterView = tableFooter
        }
    }
}

      

P.S. I prefer the Builder interface for setting constraints enter image description here

0


source







All Articles