2
votes

I have multiple prototype cells in a UITableView. Now in one of these cells, I have a UILabel with top, 'bottom', leading and trailing constraints. I wish to modify the bottom constraint programmatically. How do I assess this constraint in my code?

I have given identifier to this constraint in xib, but when I do lbl.constraints, I just get the array of following constraints:

 po lbl.constraints
<__NSArrayI 0x7f987fb81a60>(
<NSContentSizeLayoutConstraint:0x7f987faca450 H:[UILabel:0x7f98815f4660'Schedule Showing'(117)] Hug:251 CompressionResistance:750>,
<NSContentSizeLayoutConstraint:0x7f987faca4b0 V:[UILabel:0x7f98815f4660'Schedule Showing'(16.5)] Hug:251 CompressionResistance:750>
)

Why is this not showing trailing, leading, bottom and top constraints? Where am I getting wrong? How do I solve this?

Edit(Constraint change not reflected)

-(IBAction)btnShowCtrl_click:(id)sender{
    FormTableViewCell *cell = (FormTableViewCell *)[_tblView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:[[dictData valueForKey:@"FeatureList"] count]+4]];

    if(cell.nlcTextField.priority == 999){
        cell.nlcLabel .priority = 999;
        cell.nlcTextField.priority = 500;
    } else {
        cell.nlcLabel .priority = 500;
        cell.nlcTextField.priority = 999;
    }

    [UIView animateWithDuration:.5 animations:^{
//        self.orangeView.alpha = 0;
        [_tblView beginUpdates];
        [_tblView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:[[dictData valueForKey:@"FeatureList"] count]+4]] withRowAnimation:UITableViewRowAnimationNone];
        [_tblView endUpdates];
        [cell layoutIfNeeded];
    }];
}
2
Attach the constraint to an NSLayoutConstraint outlet in Interface Builder.i_am_jorf
The constraints are at the superview. But rather than programmatically iterating through the constraints, it's far easier to create @IBOutlet for the constraint and use that for modification purposes.Rob
@Rob - I have prototype cells without the implementation files. I am just using the cell and its views by tags. Hence @IBOutlet cannot be created in the .h file of the ViewController.z22
@z22 but if you create a subclass of uitableviewcell and specify that as the base class for your prototype cell, you don't need to implement any methods, but then can enjoy seamless outlets (avoiding the use of tags, which Apple advises against, anyway). It makes your code much more legible, is super easy, and you can enjoy outlets for not only the controls, but the constraints, too.Rob
@Rob alright so now I have created subclass of UITableviewCell and used registerclass.. in viewDidLoad. And in cellForRowAtIndexpath I have used- strIdentifier = @"FormTableViewCell"; FormTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strIdentifier forIndexPath:indexPath];, the app is crashing, where am I getting wrong. Am not much familiar with using registerClass with multiple prototype cells.z22

2 Answers

1
votes

I'd suggest creating a UITableViewCell subclass for your cell. For example, if you have just a label and you want an outlet for the bottom constraint, it might look like:

//  CustomCell.h

#import <UIKit/UIKit.h>

@interface CustomCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *customLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;

@end

and

//  CustomCell.m

#import "CustomCell.h"

@implementation CustomCell

// intentionally blank

@end

Then, specify that as the base class for the prototype:

enter image description here

Then you can hook up not only the outlet to the label, but also the bottom constraint:

enter image description here

Then in your cellForRowAtIndexPath, you can not only avoid using tag references (just use the customLabel outlet you hooked up), but you can also reference the bottom constraint:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell" forIndexPath:indexPath];

    cell.customLabel.text = @"Foo";
    cell.bottomConstraint.constant = 100;

    return cell;
}

By the way, if you're modifying that bottom constraint, you probably want to tell the table view that it should automatically resize the cell based upon the constraints, for example in viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.estimatedRowHeight = 44;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}

For more information, see WWDC 2014 video What's New in Table and Collection Views.

(For Swift rendition, see the revision history of this question.)

0
votes

You need to bind the IBOutlet for bottom constraint if the UILabel . How to do that follow this link : AutoLayout with hidden UIViews?