I have a UITableView and custom UITableViewCell. I have added AutoLayout inside the cell and in this cell i have a UILabel that needs to dynamically change its height and then i have a UIView that contains other subviews including this UILabel that needs its height dynamically changed. I get no errors but this is the custom UITableViewCell:
The dynamic text should force the bottom UIView after the dynamic text. But as you can see the dynamic text passes the bottom UIView.
#import "PostTableViewCell.h"
#implementation PostTableViewCell
#synthesize main;
#synthesize top;
#synthesize center;
#synthesize bottom;
#synthesize labelMessage;
#synthesize labelCat;
#synthesize labelUser;
#synthesize labelDate;
#synthesize imageviewThreadImage;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
main = [UIView new];
[self.contentView addSubview:main];
main.translatesAutoresizingMaskIntoConstraints = NO;
//[main sizeToFit];
main.backgroundColor = [UIColor whiteColor];
top = [UIView new];
[main addSubview:top];
top.translatesAutoresizingMaskIntoConstraints = NO;
//[top sizeToFit];
top.backgroundColor = [UIColor whiteColor];
labelUser = [UILabel new];
[top addSubview:labelUser];
labelUser.translatesAutoresizingMaskIntoConstraints = NO;
//[labelUser sizeToFit];
[labelUser setFont:[UIFont systemFontOfSize:14]];
labelUser.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];
labelDate = [UILabel new];
[top addSubview:labelDate];
labelDate.translatesAutoresizingMaskIntoConstraints = NO;
[labelDate sizeToFit];
[labelDate setFont:[UIFont systemFontOfSize:14]];
labelDate.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];
center = [UIView new];
[main addSubview:center];
center.translatesAutoresizingMaskIntoConstraints = NO;
[center sizeToFit];
center.backgroundColor = [UIColor whiteColor];
imageviewThreadImage = [UIImageView new];
[center addSubview:imageviewThreadImage];
imageviewThreadImage.translatesAutoresizingMaskIntoConstraints = NO;
imageviewThreadImage.backgroundColor = [UIColor colorWithRed:(207.0/255.0) green:(215.0/255.0) blue:(248.0/255.0) alpha:1.0];
labelMessage = [UILabel new];
[center addSubview:labelMessage];
labelMessage.translatesAutoresizingMaskIntoConstraints = NO;
[labelMessage sizeToFit];
[labelMessage setFont:[UIFont systemFontOfSize:14]];
labelMessage.preferredMaxLayoutWidth = screenWidth - 10 - 36;
labelMessage.lineBreakMode = NSLineBreakByWordWrapping;
labelMessage.numberOfLines = 0;
labelMessage.textColor = [UIColor lightGrayColor];
bottom = [UIView new];
[main addSubview:bottom];
bottom.translatesAutoresizingMaskIntoConstraints = NO;
[bottom sizeToFit];
labelCat = [UILabel new];
[bottom addSubview:labelCat];
labelCat.translatesAutoresizingMaskIntoConstraints = NO;
[labelCat sizeToFit];
[labelCat setFont:[UIFont systemFontOfSize:12]];
labelCat.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
// need to use to set the preferredMaxLayoutWidth below.
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
// Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
// as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
self.labelMessage.preferredMaxLayoutWidth = CGRectGetWidth(self.labelMessage.frame);
}
- (void)updateConstraints {
[super updateConstraints];
if (self.didSetupConstraints) return;
NSDictionary *viewsDictionary7 = #{#"main":main};
NSArray *constraint_H37 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[main]|"
options:0
metrics:nil
views:viewsDictionary7];
NSArray *constraint_V37 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[main]|"
options:0
metrics:nil
views:viewsDictionary7];
[self.contentView addConstraints:constraint_H37];
[self.contentView addConstraints:constraint_V37];
NSDictionary *viewsDictionary3 = #{#"top":top,#"center":center,#"bottom":bottom,#"labelMessage":labelMessage};
NSArray *constraint_H3 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[top]-5-[center]-5-[bottom]-10-|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H33 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[top]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H333 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[center]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H3335657 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[bottom]|"
options:0
metrics:nil
views:viewsDictionary3];
NSDictionary *viewsDictionary4 = #{#"labelUser":labelUser,#"labelDate":labelDate};
NSArray *constraint_H4 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelUser]|"
options:0
metrics:nil
views:viewsDictionary4];
NSDictionary *viewsDictionary45 = #{#"labelDate":labelDate};
NSArray *constraint_H4555 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelDate]|"
options:0
metrics:nil
views:viewsDictionary45];
NSArray *constraint_H44 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelUser]-20-[labelDate]-5-|"
options:0
metrics:nil
views:viewsDictionary4];
NSDictionary *viewsDictionary48 = #{#"labelMessage":labelMessage,#"imageviewThreadImage":imageviewThreadImage};
NSArray *constraint_H48 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[labelMessage]"
options:0
metrics:nil
views:viewsDictionary48];
NSArray *constraint_H48342 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-8-[imageviewThreadImage(36)]|"
options:0
metrics:nil
views:viewsDictionary48];
NSArray *constraint_H448 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[imageviewThreadImage(36)]-5-[labelMessage]-5-|"
options:0
metrics:nil
views:viewsDictionary48];
NSDictionary *viewsDictionary488 = #{#"labelCat":labelCat};
NSArray *constraint_H488 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[labelCat]|"
options:0
metrics:nil
views:viewsDictionary488];
NSArray *constraint_H4488 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelCat]"
options:0
metrics:nil
views:viewsDictionary488];
[main addConstraints:constraint_H3];
////[main addConstraints:constraint_H33];
[main addConstraints:constraint_H333];
[top addConstraints:constraint_H4];
[top addConstraints:constraint_H44];
[center addConstraints:constraint_H48];
[center addConstraints:constraint_H448];
[top addConstraints:constraint_H4555];
[main addConstraints:constraint_H3335657];
[main addConstraints:constraint_H488];
[main addConstraints:constraint_H48342];
[main addConstraints:constraint_H4488];
self.didSetupConstraints = YES;
}
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
This is the result i get:
Here is your answer redoc01
- (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Get table dat
static NSString *CellIdentifier = #"CustomCell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//Create Cell
NSArray *nib;
nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (UITableViewCell *) [nib objectAtIndex:0];
}
if(indexPath.section == 0) {
UILabel *dateLable = (UILabel *) [cell.contentView viewWithTag:CELL_DATE_LABLE];
dateLable.text = _string3;
[dateLable layoutIfNeeded];
return dateLable.frame.size.height;
}
}
Let me know your feedback..
I solved it by changing the AutoLayout, this is the modified UITableViewCell that makes it work with AutoLayout:
#import "PostTableViewCell.h"
#implementation PostTableViewCell
#synthesize main;
#synthesize top;
#synthesize center;
#synthesize centerLeft;
#synthesize centerRight;
#synthesize bottom;
#synthesize labelMessage;
#synthesize labelCat;
#synthesize labelUser;
#synthesize labelDate;
#synthesize imageviewThreadImage;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
main = [UIView new];
//[self.contentView addSubview:main];
main.translatesAutoresizingMaskIntoConstraints = NO;
[main sizeToFit];
main.backgroundColor = [UIColor whiteColor];
top = [UIView new];
[self.contentView addSubview:top];
top.translatesAutoresizingMaskIntoConstraints = NO;
[top sizeToFit];
top.backgroundColor = [UIColor whiteColor];
labelUser = [UILabel new];
[top addSubview:labelUser];
labelUser.translatesAutoresizingMaskIntoConstraints = NO;
[labelUser sizeToFit];
[labelUser setFont:[UIFont systemFontOfSize:14]];
labelUser.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];
labelDate = [UILabel new];
[top addSubview:labelDate];
labelDate.translatesAutoresizingMaskIntoConstraints = NO;
[labelDate sizeToFit];
[labelDate setFont:[UIFont systemFontOfSize:14]];
labelDate.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];
center = [UIView new];
[self.contentView addSubview:center];
center.translatesAutoresizingMaskIntoConstraints = NO;
[center sizeToFit];
center.backgroundColor = [UIColor whiteColor];
imageviewThreadImage = [UIImageView new];
[center addSubview:imageviewThreadImage];
imageviewThreadImage.translatesAutoresizingMaskIntoConstraints = NO;
imageviewThreadImage.backgroundColor = [UIColor colorWithRed:(207.0/255.0) green:(215.0/255.0) blue:(248.0/255.0) alpha:1.0];
[imageviewThreadImage sizeToFit];
labelMessage = [UILabel new];
[center addSubview:labelMessage];
labelMessage.translatesAutoresizingMaskIntoConstraints = NO;
[labelMessage sizeToFit];
[labelMessage setFont:[UIFont systemFontOfSize:14]];
labelMessage.preferredMaxLayoutWidth = screenWidth - 10 - 36;
labelMessage.lineBreakMode = UILineBreakModeWordWrap;
labelMessage.numberOfLines = 0;
labelMessage.textColor = [UIColor lightGrayColor];
//labelMessage.lineBreakMode = UILineBreakModeWordWrap;
bottom = [UIView new];
[self.contentView addSubview:bottom];
bottom.translatesAutoresizingMaskIntoConstraints = NO;
[bottom sizeToFit];
labelCat = [UILabel new];
[bottom addSubview:labelCat];
labelCat.translatesAutoresizingMaskIntoConstraints = NO;
[labelCat sizeToFit];
[labelCat setFont:[UIFont systemFontOfSize:12]];
labelCat.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
labelCat.lineBreakMode = UILineBreakModeWordWrap;
labelCat.numberOfLines = 0;
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
// need to use to set the preferredMaxLayoutWidth below.
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
// Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
// as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
self.labelMessage.preferredMaxLayoutWidth = CGRectGetWidth(self.labelMessage.frame);
}
- (void)updateConstraints {
[super updateConstraints];
if (self.didSetupConstraints) return;
/**NSDictionary *viewsDictionary7 = #{#"main":main};
NSArray *constraint_H37 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[main]|"
options:0
metrics:nil
views:viewsDictionary7];
NSArray *constraint_V37 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[main]|"
options:0
metrics:nil
views:viewsDictionary7];
[self.contentView addConstraints:constraint_H37];
[self.contentView addConstraints:constraint_V37];**/
NSString *text = labelMessage.text;
NSDictionary *viewsDictionary3 = #{#"top":top,#"center":center,#"bottom":bottom};
NSArray *constraint_H3 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-10-[top]-5-[center(>=50)]-5-[bottom]-10-|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H33 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[top]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H333 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[center]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H3335657 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[bottom]|"
options:0
metrics:nil
views:viewsDictionary3];
NSDictionary *viewsDictionary4 = #{#"labelUser":labelUser,#"labelDate":labelDate};
NSArray *constraint_H4 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelUser]|"
options:0
metrics:nil
views:viewsDictionary4];
NSDictionary *viewsDictionary45 = #{#"labelDate":labelDate};
NSArray *constraint_H4555 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelDate]|"
options:0
metrics:nil
views:viewsDictionary45];
NSArray *constraint_H44 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelUser]-20-[labelDate]-5-|"
options:0
metrics:nil
views:viewsDictionary4];
NSDictionary *viewsDictionary48 = #{#"labelMessage":labelMessage,#"imageviewThreadImage":imageviewThreadImage};
NSArray *constraint_H48 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[labelMessage]|"
options:0
metrics:nil
views:viewsDictionary48];
NSArray *constraint_H48342 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-8-[imageviewThreadImage(36)]"
options:0
metrics:nil
views:viewsDictionary48];
NSArray *constraint_H448345fgdfg = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[imageviewThreadImage(36)]-5-[labelMessage]-5-|"
options:0
metrics:nil
views:viewsDictionary48];
/**NSArray *constraint_H448 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelMessage]-5-|"
options:0
metrics:nil
views:viewsDictionary48];**/
NSDictionary *viewsDictionary488 = #{#"labelCat":labelCat};
NSArray *constraint_H488 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelCat]|"
options:0
metrics:nil
views:viewsDictionary488];
NSArray *constraint_H4488 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelCat]"
options:0
metrics:nil
views:viewsDictionary488];
[self.contentView addConstraints:constraint_H3];
[self.contentView addConstraints:constraint_H33];
[self.contentView addConstraints:constraint_H333];
[self.contentView addConstraints:constraint_H4];
[self.contentView addConstraints:constraint_H44];
[self.contentView addConstraints:constraint_H48];
//[self.contentView addConstraints:constraint_H448];
[self.contentView addConstraints:constraint_H4555];
[self.contentView addConstraints:constraint_H3335657];
[self.contentView addConstraints:constraint_H488];
[self.contentView addConstraints:constraint_H48342];
[self.contentView addConstraints:constraint_H4488];
[self.contentView addConstraints:constraint_H448345fgdfg];
self.didSetupConstraints = YES;
}
- (CGFloat)heightForText:(NSString *)bodyText
{
UIFont *cellFont = [UIFont systemFontOfSize:17];
CGSize constraintSize = CGSizeMake(300, MAXFLOAT);
CGSize labelSize = [bodyText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = labelSize.height + 10;
return height;
}
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
In iOS 8 you can use the delegate function to calculate the cell size as such:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Make sure that you have bottom constraint between the label to the bottom of the contentView and you are done.
Please note it will work only on iOS 8.
Related
There is a view1(UIView) in Custom UITableViewCell in I want new size of view1(UIView) after AutoLayout to draw border
UITableViewCell content is dynamic, hence I usedUITableViewAutomaticDimension for self resizing
I also use below methods but I get Original Size. I can not get new size of view1(UIView) after expanding
[self.tblView1 setNeedsLayout];
[self.tblView1 layoutIfNeeded];
[cell.view1 setNeedsLayout];
[cell.view1 layoutIfNeeded];
CALayer *rightBorder = [CALayer layer];
rightBorder.backgroundColor = [[UIColor redColor] CGColor];
rightBorder.frame = CGRectMake(cell.view1.frame.size.width-1, 0, 1, cell.view1.frame.size.height);
[cell.view1.layer addSublayer:rightBorder];
rightBorder is draw but according to view1's(UIView) original size that is Width = 394 Height = 322 not according to view1's(UIView) new size after layout size that is Width = 394 Height = 422
Try this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView.tag == self.tblEditorialCalendar.tag)
{
UIView *leftBorder = [UIView new];
leftBorder.backgroundColor = [UIColor redColor];
leftBorder.translatesAutoresizingMaskIntoConstraints = NO;
UIView *topBorder = [UIView new];
topBorder.backgroundColor = [UIColor greenColor];
topBorder.translatesAutoresizingMaskIntoConstraints = NO;
UIView *rightBorder = [UIView new];
rightBorder.backgroundColor = [UIColor blueColor];
rightBorder.translatesAutoresizingMaskIntoConstraints = NO;
UIView *bottomBorder = [UIView new];
bottomBorder.backgroundColor = [UIColor yellowColor];
bottomBorder.translatesAutoresizingMaskIntoConstraints = NO;
[cell addSubview:leftBorder];
[cell addSubview:topBorder];
[cell addSubview:rightBorder];
[cell addSubview:bottomBorder];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[leftBorder(3)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(leftBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[leftBorder]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(leftBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-3-[topBorder]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(topBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[topBorder(1)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(topBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[rightBorder(1)]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(rightBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[rightBorder]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(rightBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-3-[bottomBorder]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(bottomBorder)]];
[cell addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[bottomBorder(1)]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(bottomBorder)]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
}
Another way is to use layout anchor (supported from iOS 9 and above) instead of VFL
[leftBorder.widthAnchor constraintEqualToConstant:3].active = YES;
[cell.leadingAnchor constraintEqualToAnchor:leftBorder.leadingAnchor constant:0].active = YES;
[cell.topAnchor constraintEqualToAnchor:leftBorder.topAnchor constant:0].active = YES;
[cell.bottomAnchor constraintEqualToAnchor:leftBorder.bottomAnchor constant:0].active = YES;
[topBorder.heightAnchor constraintEqualToConstant:1].active = YES;
[cell.leadingAnchor constraintEqualToAnchor:topBorder.leadingAnchor constant:3].active = YES;
[cell.topAnchor constraintEqualToAnchor:topBorder.topAnchor constant:0].active = YES;
[cell.trailingAnchor constraintEqualToAnchor:topBorder.trailingAnchor constant:0].active = YES;
[rightBorder.widthAnchor constraintEqualToConstant:1].active = YES;
[cell.trailingAnchor constraintEqualToAnchor:rightBorder.trailingAnchor constant:0].active = YES;
[cell.topAnchor constraintEqualToAnchor:rightBorder.topAnchor constant:0].active = YES;
[cell.bottomAnchor constraintEqualToAnchor:rightBorder.bottomAnchor constant:0].active = YES;
[bottomBorder.heightAnchor constraintEqualToConstant:1].active = YES;
[cell.leadingAnchor constraintEqualToAnchor:bottomBorder.leadingAnchor constant:3].active = YES;
[cell.trailingAnchor constraintEqualToAnchor:bottomBorder.trailingAnchor constant:0].active = YES;
[cell.bottomAnchor constraintEqualToAnchor:bottomBorder.bottomAnchor constant:0].active = YES;
Or you could just take four view (as four borders) in your nib file and place them with proper constraints.
In my project I am using auto-layouts and I am adding one or more labels on my view-controller and for this I would like to use a "for" loop by means of code reducing purpose but using "constraintWithVisualFormate".
I do not understand!
How can I use a for loop?
my code:
emailTextField = [[UILabel alloc] init];
emailTextField.text = #"MD (Medician)";
emailTextField.textColor = [UIColor blackColor];
emailTextField.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview: emailTextField];
nameTextField = [[UILabel alloc] init];
nameTextField.text = #"Experience:12 Years";
nameTextField.textColor = [UIColor blackColor];
nameTextField.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview: nameTextField];
password = [[UILabel alloc] init];
password.text = #"Experience:12 Years";
password.textColor = [UIColor blackColor];
password.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview: password];
//Applying auto-layouts for labels
NSDictionary * views = NSDictionaryOfVariableBindings(emailTextField,nameTextField,password);
NSArray *textFields = #[emailTextField, nameTextField, password];
for (UITextField *textField in textFields) {
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-10-[textField]-10-|"
options:0
metrics:nil
views:viewsDic]];
}
I am struggling near above for loop because I am not understand how can we insert nameTextField,emailTextField...etc labels inside for loop.
Screenshot
Code
emailTextField = [self createLabelWithText: #"MD (Medician)"];
[self.view addSubview: emailTextField];
nameTextField = [self createLabelWithText: #"Experience:12 Years"];
[self.view addSubview: nameTextField];
passwword = [self createLabelWithText: #"Experience:12 Years"];
[self.view addSubview: passwword];
NSDictionary * viewsDic = NSDictionaryOfVariableBindings(emailTextField,nameTextField,passwword);
NSArray * keys = #[#"emailTextField",#"nameTextField",#"passwword"];
for (NSString * key in keys) {
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-10-[%#]-10-|",key]
options:0
metrics:nil
views:viewsDic]];
}
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[emailTextField]-[nameTextField]-[passwword]"
options:0
metrics:nil
views:viewsDic]];
This is the function
-(UILabel *)createLabelWithText:(NSString *)text{
UILabel * label = [[UILabel alloc] init];
label.text = text;
label.textColor = [UIColor blackColor];
label.translatesAutoresizingMaskIntoConstraints = NO;
return label;
}
Im using AutoLayout in my cells but, when the cell has large text inside the cell and the cell expands the cell seems to overlap the cell below. Image shows how this is overlapping the cells:
UITableViewCell:
#import "PostTableViewCell.h"
#implementation PostTableViewCell
#synthesize main;
#synthesize top;
#synthesize center;
#synthesize centerLeft;
#synthesize centerRight;
#synthesize bottom;
#synthesize labelMessage;
#synthesize labelCat;
#synthesize labelSubCat;
#synthesize labelCountry;
#synthesize labelUser;
#synthesize labelDate;
#synthesize imageviewThreadImage;
#synthesize split;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
//CGFloat screenHeight = screenSize.height;
main = [UIView new];
[self.contentView addSubview:main];
main.translatesAutoresizingMaskIntoConstraints = NO;
[main sizeToFit];
main.backgroundColor = [UIColor whiteColor];
top = [UIView new];
[main addSubview:top];
top.translatesAutoresizingMaskIntoConstraints = NO;
[top sizeToFit];
top.backgroundColor = [UIColor whiteColor];
labelUser = [UILabel new];
[top addSubview:labelUser];
labelUser.translatesAutoresizingMaskIntoConstraints = NO;
[labelUser sizeToFit];
[labelUser setFont:[UIFont systemFontOfSize:10]];
labelUser.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];
labelDate = [UILabel new];
[top addSubview:labelDate];
labelDate.translatesAutoresizingMaskIntoConstraints = NO;
[labelDate sizeToFit];
[labelDate setFont:[UIFont systemFontOfSize:10]];
labelDate.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];
center = [UIView new];
[main addSubview:center];
center.translatesAutoresizingMaskIntoConstraints = NO;
[center sizeToFit];
center.backgroundColor = [UIColor whiteColor];
imageviewThreadImage = [UIImageView new];
[center addSubview:imageviewThreadImage];
imageviewThreadImage.translatesAutoresizingMaskIntoConstraints = NO;
imageviewThreadImage.backgroundColor = [UIColor colorWithRed:(207.0/255.0) green:(215.0/255.0) blue:(248.0/255.0) alpha:1.0];
[imageviewThreadImage sizeToFit];
labelMessage = [UILabel new];
[center addSubview:labelMessage];
labelMessage.translatesAutoresizingMaskIntoConstraints = NO;
[labelMessage sizeToFit];
[labelMessage setFont:[UIFont systemFontOfSize:12]];
labelMessage.preferredMaxLayoutWidth = screenWidth - 10 - 36;
labelMessage.lineBreakMode = NSLineBreakByWordWrapping;
labelMessage.numberOfLines = 0;
labelMessage.textColor = [UIColor lightGrayColor];
//labelMessage.backgroundColor = [UIColor colorWithRed:(207.0/255.0) green:(215.0/255.0) blue:(248.0/255.0) alpha:1.0];
//labelMessage.lineBreakMode = UILineBreakModeWordWrap;
bottom = [UIView new];
[main addSubview:bottom];
bottom.translatesAutoresizingMaskIntoConstraints = NO;
[bottom sizeToFit];
labelCat = [UILabel new];
[bottom addSubview:labelCat];
labelCat.translatesAutoresizingMaskIntoConstraints = NO;
[labelCat sizeToFit];
[labelCat setFont:[UIFont systemFontOfSize:10]];
labelCat.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
labelCat.lineBreakMode = NSLineBreakByWordWrapping;
labelCat.numberOfLines = 0;
labelSubCat = [UILabel new];
[bottom addSubview:labelSubCat];
labelSubCat.translatesAutoresizingMaskIntoConstraints = NO;
[labelSubCat sizeToFit];
[labelSubCat setFont:[UIFont systemFontOfSize:10]];
labelSubCat.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
labelCountry = [UILabel new];
[bottom addSubview:labelCountry];
labelCountry.translatesAutoresizingMaskIntoConstraints = NO;
[labelCountry sizeToFit];
[labelCountry setFont:[UIFont systemFontOfSize:10]];
labelCountry.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
split = [UIView new];
[main addSubview:split];
split.translatesAutoresizingMaskIntoConstraints = NO;
[split sizeToFit];
split.backgroundColor = [UIColor grayColor];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
// need to use to set the preferredMaxLayoutWidth below.
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
// Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
// as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
self.labelMessage.preferredMaxLayoutWidth = CGRectGetWidth(self.labelMessage.frame);
}
- (void)updateConstraints {
[super updateConstraints];
if (self.didSetupConstraints) return;
NSDictionary *viewsDictionary7 = #{#"main":main};
NSArray *constraint_H37 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[main]|"
options:0
metrics:nil
views:viewsDictionary7];
NSArray *constraint_V37 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[main]|"
options:0
metrics:nil
views:viewsDictionary7];
[self.contentView addConstraints:constraint_H37];
[self.contentView addConstraints:constraint_V37];
//NSString *text = labelMessage.text;
NSDictionary *viewsDictionary3 = #{#"top":top,#"center":center,#"bottom":bottom,#"split":split};
NSArray *constraint_H3 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-10-[top]-5-[center(>=40)]-5-[bottom]-10-[split(1)]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H33cvcv4545fdd = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[split]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H33 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[top]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H333 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[center]|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H3335657 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[bottom]|"
options:0
metrics:nil
views:viewsDictionary3];
NSDictionary *viewsDictionary4 = #{#"labelUser":labelUser,#"labelDate":labelDate};
NSArray *constraint_H4 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelUser]|"
options:0
metrics:nil
views:viewsDictionary4];
NSDictionary *viewsDictionary45 = #{#"labelDate":labelDate};
NSArray *constraint_H4555 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelDate]|"
options:0
metrics:nil
views:viewsDictionary45];
NSArray *constraint_H44 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelUser]-20-[labelDate]-5-|"
options:0
metrics:nil
views:viewsDictionary4];
NSDictionary *viewsDictionary48 = #{#"labelMessage":labelMessage,#"imageviewThreadImage":imageviewThreadImage};
NSArray *constraint_H48 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[labelMessage]-5-|"
options:0
metrics:nil
views:viewsDictionary48];
NSArray *constraint_H48342 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-8-[imageviewThreadImage(36)]"
options:0
metrics:nil
views:viewsDictionary48];
NSArray *constraint_H448345fgdfg = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[imageviewThreadImage(36)]"
options:0
metrics:nil
views:viewsDictionary48];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
//CGFloat screenHeight = screenSize.height;
NSArray *constraint_H448345fgdfgdfdf454 = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-46-[labelMessage(%f)]-10-|",screenWidth - 51]
options:0
metrics:nil
views:viewsDictionary48];
/**NSArray *constraint_H448 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelMessage]-5-|"
options:0
metrics:nil
views:viewsDictionary48];**/
NSDictionary *viewsDictionary488 = #{#"labelCat":labelCat,#"labelCountry":labelCountry,#"labelSubCat":labelSubCat};
NSArray *constraint_H488 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[labelCat]|"
options:0
metrics:nil
views:viewsDictionary488];
NSArray *constraint_H48898 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[labelCountry]|"
options:0
metrics:nil
views:viewsDictionary488];
NSArray *constraint_H48898fgf54 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[labelSubCat]|"
options:0
metrics:nil
views:viewsDictionary488];
NSArray *constraint_H4488 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelCat]-10-[labelSubCat]-10-[labelCountry]"
options:0
metrics:nil
views:viewsDictionary488];
[self.contentView addConstraints:constraint_H3];
[self.contentView addConstraints:constraint_H33];
[self.contentView addConstraints:constraint_H333];
[self.contentView addConstraints:constraint_H4];
[self.contentView addConstraints:constraint_H44];
[self.contentView addConstraints:constraint_H48];
//[self.contentView addConstraints:constraint_H448];
[self.contentView addConstraints:constraint_H4555];
[self.contentView addConstraints:constraint_H3335657];
[self.contentView addConstraints:constraint_H488];
[self.contentView addConstraints:constraint_H48342];
[self.contentView addConstraints:constraint_H4488];
[self.contentView addConstraints:constraint_H448345fgdfg];
[self.contentView addConstraints:constraint_H48898];
[self.contentView addConstraints:constraint_H48898fgf54];
[self.contentView addConstraints:constraint_H33cvcv4545fdd];
[self.contentView addConstraints:constraint_H448345fgdfgdfdf454];
self.didSetupConstraints = YES;
}
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
How my cells are reused:
CellForRowIndexPath -
if(tableView == tableViewPost){
Post *t = (Post*)[tmpArray2 objectAtIndex:indexPath.row];
static NSString *simpleTableIdentifier = #"SimpleTableItem46";
PostTableViewCell *cell = (PostTableViewCell*)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//cell.layer.shouldRasterize = YES;
//cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
if (cell == nil) {
cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.labelMessage.text = t.message;
cell.labelCat.text = t.cat;
cell.labelSubCat.text = t.subcat;
cell.labelCountry.text = t.country;
cell.labelUser.text = [NSString stringWithFormat:#"%#", t.user];
cell.labelDate.text = [NSString stringWithFormat:#"%#", t.date];
[cell.contentView setNeedsUpdateConstraints];
[cell.contentView updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
return cell;
}
HeightForRowIndexPath -
if(tableView == tableViewPost){
Post *t = (Post*)[tmpArray2 objectAtIndex:indexPath.row];
PostTableViewCell *cell = (PostTableViewCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
[cell.contentView setNeedsUpdateConstraints];
[cell.contentView updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
//CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return height;
}
if you are using iOS 8 or greater you can try
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 70.0
I'm basically trying to achieve this effect: http://youtu.be/VBW2i0P11iI
The tableview is a basic one that's pinned to it's superview with autolayout. The view underneath is added with the classic insertSubview:belowSubview: / addChildViewController combo.
I've tried a couple of approaches. What I have now is:
if (scrollOffset >= -scrollView.contentInset.top) {
self.resultsTableViewContainerTopConstraint.constant = 0;
} else {
self.resultsTableViewContainerTopConstraint.constant = MAX(self.resultsTableViewContainerTopConstraint.constant, self.resultsTableViewContainerTopConstraint.constant - scrollDiff);
}
}
So I'm basically changing the top constraint based on the delta of contentOffset. The problem with this is that the uitableview bounces back so it always gets into the first branch of the if. But even if I solve this problem I feel like I'll just patch it. I'm sure there's a way more elegant way of achieving the effect in the video having the same responsiveness.
Any suggestion will be much appreciated.
Thanks
I'm not sure if this is what you want but I hacked up a quick demo:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate>
#property (nonatomic, strong) UIView *headerView;
#property (nonatomic, strong) UILabel *lblTitle;
#property (nonatomic, strong) UIButton *btnReset;
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, strong) UIScrollView *scrollView;
#property (nonatomic, strong) UITableView *tableView;
#property (nonatomic, strong) NSLayoutConstraint *scrollViewTopConstraint;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//self.view.backgroundColor = [UIColor whiteColor];
[self initViews];
[self initConstraints];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)initViews
{
self.view.backgroundColor = [UIColor colorWithRed:43.0/255.0 green:39.0/255.0 blue:55.0/255.0 alpha:1.0];
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.alwaysBounceVertical = YES;
self.scrollView.delegate = self;
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:43.0/255.0 green:39.0/255.0 blue:55.0/255.0 alpha:1.0];
self.headerView.layer.shadowColor = [UIColor blackColor].CGColor;
self.headerView.layer.shadowOffset = CGSizeMake(0,0);
self.headerView.layer.shadowOpacity = 0.25;
self.headerView.layer.shadowRadius = 4;
self.lblTitle = [[UILabel alloc] init];
self.lblTitle.text = #"HEADER VIEW";
self.lblTitle.textColor = [UIColor whiteColor];
self.lblTitle.textAlignment = NSTextAlignmentCenter;
self.btnReset = [[UIButton alloc] init];
[self.btnReset setTitle:#"Reset" forState:UIControlStateNormal];
self.btnReset.backgroundColor = [UIColor colorWithRed:0.75 green:0.0 blue:0.0 alpha:1.0];
self.btnReset.layer.cornerRadius = 5.0;
[self.btnReset addTarget:self action:#selector(resetView) forControlEvents:UIControlEventTouchUpInside];
self.imageView = [[UIImageView alloc] init];
self.imageView.backgroundColor = [UIColor colorWithRed:43.0/255.0 green:39.0/255.0 blue:55.0/255.0 alpha:1.0];
self.tableView = [[UITableView alloc] init];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.rowHeight = 150.0;
self.tableView.layer.shadowColor = [UIColor blackColor].CGColor;
self.tableView.layer.shadowOffset = CGSizeMake(0,-5);
self.tableView.layer.shadowOpacity = 0.5;
self.tableView.layer.shadowRadius = 20;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.scrollEnabled = NO;
self.tableView.clipsToBounds = NO;
[self.headerView addSubview:self.lblTitle];
[self.headerView addSubview:self.btnReset];
[self.scrollView addSubview:self.tableView];
[self.view addSubview:self.imageView];
[self.view addSubview:self.scrollView];
[self.view addSubview:self.headerView];
}
-(void)initConstraints
{
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
self.lblTitle.translatesAutoresizingMaskIntoConstraints = NO;
self.btnReset.translatesAutoresizingMaskIntoConstraints = NO;
self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
id views = #{
#"scrollView": self.scrollView,
#"headerView": self.headerView,
#"lblTitle": self.lblTitle,
#"btnReset": self.btnReset,
#"imageView": self.imageView,
#"tableView": self.tableView
};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrollView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[scrollView]" options:0 metrics:nil views:views]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
self.scrollViewTopConstraint = [NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
[self.view addConstraint:self.scrollViewTopConstraint];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[headerView(320)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[headerView(50)]" options:0 metrics:nil views:views]];
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[tableView(320)]|" options:0 metrics:nil views:views]];
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-150-[tableView(300)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imageView(320)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageView(320)]" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[lblTitle]|" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[lblTitle]|" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[btnReset(80)]-5-|" options:0 metrics:nil views:views]];
[self.headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-8-[btnReset]-8-|" options:0 metrics:nil views:views]];
}
-(BOOL)prefersStatusBarHidden
{
return YES;
}
#pragma mark - TableView Methods -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
return cell;
}
#pragma mark - ScrollView Delegate -
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//NSLog(#"scrollView offset = %lf", scrollView.contentOffset.y);
if(scrollView.contentOffset.y <= -145)
{
//self.scrollView.scrollEnabled = NO;
self.scrollViewTopConstraint.constant = self.view.bounds.size.height;
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.scrollView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
}
-(void)resetView
{
self.scrollViewTopConstraint.constant = 0;
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.scrollView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
What you get when you open the app:
Then you drag down to the edge, the view snaps open:
Press the red reset button to bring it back up :D
I create a subview with a UIview (acts as header), a UIImage, and 10 UILabels. I'm putting these into a UICollectionView as cells.
When designed completely, it does not scroll smoothly. If i remove all the UILabels, it scrolls smoothly.
I'm assuming it's sluggish cause the UICollectionView loads on demand, so when it needs each new cell, it has to draw it which locks up the main thread.
Is it just a matter that its too much for iOS to handle to create them? If so, is there another way I can put text into it?
what my cell looks like:
Here is DatasetFilterListPanelView, this creates the UIView that I put into the UICollectionViewCell. I did it this way cause I created this before I decided to use UICollectionView.
#implementation DatasetFilterListPanelView
-(id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.translatesAutoresizingMaskIntoConstraints = FALSE;
UIView *contentView = [self createContentView];
[self addSubview:contentView];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[contentView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(contentView)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[contentView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(contentView)]];
}
return self;
}
-(UIView *) createContentView {
UIView *contentView = [[UIView alloc] initWithFrame:self.frame];
// contentView.translatesAutoresizingMaskIntoConstraints = FALSE;
contentView.backgroundColor = [UIColor myDarkGrayColor];
UIView *headerView = [self createHeaderView];
[contentView addSubview:headerView];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[headerView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(headerView)]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[headerView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(headerView)]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"gear12.png"]];
imageView.translatesAutoresizingMaskIntoConstraints = FALSE;
imageView.backgroundColor = [UIColor blueColor];
self.imageView = imageView;
[imageView addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:imageView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
[contentView addSubview:imageView];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[headerView]-[imageView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(headerView, imageView)]];
UILabel *acresLabel = [self createLabelWithTitle:#"Label01:" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:12]];
[contentView addSubview:acresLabel];
UILabel *addedLabel = [self createLabelWithTitle:#"Label02:" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:12]];
[contentView addSubview:addedLabel];
UILabel *typeLabel = [self createLabelWithTitle:#"Label03:" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:12]];
[contentView addSubview:typeLabel];
UILabel *zonesLabel = [self createLabelWithTitle:#"Label04:" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:12]];
[contentView addSubview:zonesLabel];
UILabel *sceneLabel = [self createLabelWithTitle:#"Label05:" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:12]];
[contentView addSubview:sceneLabel];
UILabel *acresValueLabel = [self createLabelWithTitle:#"Data" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE size:12]];
acresValueLabel.textAlignment = NSTextAlignmentLeft;
[contentView addSubview:acresValueLabel];
UILabel *addedValueLabel = [self createLabelWithTitle:#"Data" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE size:12]];
addedValueLabel.textAlignment = NSTextAlignmentLeft;
[contentView addSubview:addedValueLabel];
UILabel *typeValueLabel = [self createLabelWithTitle:#"Name" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE size:12]];
typeValueLabel.textAlignment = NSTextAlignmentLeft;
[contentView addSubview:typeValueLabel];
UILabel *zonesValueLabel = [self createLabelWithTitle:#"Data" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE size:12]];
zonesValueLabel.textAlignment = NSTextAlignmentLeft;
[contentView addSubview:zonesValueLabel];
UILabel *sceneValueLabel = [self createLabelWithTitle:#"Name" andFont:[UIFont fontWithName:HELVETICA_FONT_STYLE size:12]];
sceneValueLabel.textAlignment = NSTextAlignmentLeft;
[contentView addSubview:sceneValueLabel];
NSDictionary *views = NSDictionaryOfVariableBindings(headerView, imageView, acresLabel, acresValueLabel, addedLabel, addedValueLabel, typeLabel, typeValueLabel, zonesLabel, zonesValueLabel, sceneLabel, sceneValueLabel);
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[headerView]-[acresLabel]"
options:0
metrics:nil
views:views]] ;
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[acresLabel]-[addedLabel(==acresLabel)]-[typeLabel(==acresLabel)]-[zonesLabel(==acresLabel)]-[sceneLabel(==acresLabel)]-|"
options:NSLayoutFormatAlignAllRight
metrics:0
views:views]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[acresValueLabel]-[addedValueLabel(==acresLabel)]-[typeValueLabel(==acresLabel)]-[zonesValueLabel(==acresLabel)]-[sceneValueLabel(==acresLabel)]-|"
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:views]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[imageView]-20-[acresLabel]-[acresValueLabel]" options:0 metrics:nil views:views]];
return contentView;
}
-(UIView *)createHeaderView {
UIView *view = [UIView new];
view.translatesAutoresizingMaskIntoConstraints = FALSE;
view.backgroundColor = [UIColor blueColor];
view.clipsToBounds = YES;
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[view(30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]];
UILabel *title = [UILabel new];
title.translatesAutoresizingMaskIntoConstraints = FALSE;
title.text = #"Default text";
title.font = [UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:14];
title.textColor = [UIColor whiteColor];
title.backgroundColor = [UIColor clearColor];
self.headerLabel = title;
[view addSubview:title];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[title]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(title)]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:title attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
self.headerGradient = [UIColor grayGradient];
self.headerGradient.frame = CGRectMake(0, 0, 360, 30);
[view.layer insertSublayer:self.headerGradient atIndex:0];
return view;
}
-(UILabel *)createLabelWithTitle:(NSString *)title andFont:(UIFont *)font; {
UILabel *label = [UILabel new];
label.translatesAutoresizingMaskIntoConstraints = FALSE;
label.text = title;
label.font = font;
label.textAlignment = NSTextAlignmentRight;
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
return label;
}
Here is my UICollectionViewCell file, i just addSubview a DatasetFilterListPanelView to it.
#implementation DatasetViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:[[DatasetFilterListPanelView alloc] initWithFrame:CGRectMake(0, 0, 360, 160)]];
}
return self;
}
When I use the same panels in a UIScrollview, once they are all loaded and positioned, it will scroll smoothly. So it has to be the loading a cell on demand aspect of the UICollectionView.
I followed this UICollectionView Tutorial
EDIT: creating the cell:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
DatasetViewCell *datasetCell = [collectionView dequeueReusableCellWithReuseIdentifier:DatasetCellIdentifier forIndexPath:indexPath];
return datasetCell;
}
EDIT 2: Instrument tracing:
Ok, after much playing around I figured out the culprit: constraints! CodaFI was right. I didn't have that many constraints in the panel so i didn't think it could be the issue.
I created a nib file and removed autolayout and it now scrolls smoothly.
Lesson of the day: Constraints are slow to compute!
Generally the problem is that you don't reuse the cells. Make sure you use dequeueReusableCellWithReuseIdentifier:forIndexPath: to reuse existing cells.