2

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];
    }];
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
z22
  • 10,013
  • 17
  • 70
  • 126
  • Attach the constraint to an NSLayoutConstraint outlet in Interface Builder. – i_am_jorf Dec 10 '15 at 05:20
  • 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 Dec 10 '15 at 05:21
  • @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 Dec 10 '15 at 05:25
  • @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 Dec 10 '15 at 05:28
  • @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 Dec 10 '15 at 06:02
  • @z22 - No, you only use `registerClass...` if you're going to use NIBs or programmatically created cells. When using cell prototypes, you should _not_ call `registerClass...`. Just specify base class in storyboard and that's all you need. I have revised my answer below to show you the Objective-C rendition of this. – Rob Dec 10 '15 at 06:32

2 Answers2

1

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.)

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks mate, helped a lot! – z22 Dec 10 '15 at 06:38
  • This solved my query somewhat but the constraint change is not reflected in the view. Can you please help me out with this? Please check my edited question. – z22 Dec 10 '15 at 06:41
  • I need to hide/show a control below the label. I followed http://stackoverflow.com/questions/28301595/hiding-a-uiview-using-autolayout-constraints link and hence have kept such priorities of the constraint. – z22 Dec 10 '15 at 06:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97478/discussion-between-rob-and-z22). – Rob Dec 10 '15 at 07:06
0

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

Community
  • 1
  • 1
Rahul Mathur
  • 872
  • 1
  • 7
  • 20