Issue with cell reuse in UITableView - ios

I have a UITableView that displays information but mostly the bit I am stuck on is showing star ratings. I have managed to create a custom UITableViewCell that contains the logic to display how man star rating each cell has. So if there is a rating of 3 it will display 3 yellow stars and 2 blank stars so altogether theres a total rating of 5. When the UITableView is displayed I can see that the star rating for the first 4 cells is correct:
Display of only TEN cells.
Rating in order of cell (what comes back from the Database):
5
3
3
1
0
0
0
0
0
0
but whats happening is that when I scroll the cells I get these ratings, seems to repeat the first for cell rating:
Rating in order of cell when scrolled (UI Scrolling):
5
3
3
1
5
3
3
1
5
3
Why is this happening?
I will give you code and edit if needed.
EDIT
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == tableViewTopThreads){
static NSString *simpleTableIdentifier = #"SimpleTableItem";
ThreadTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//cell.layer.shouldRasterize = YES;
//cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
if (cell == nil) {
cell = [[ThreadTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
Thread *t = (Thread*)[tmpArray4 objectAtIndex:indexPath.row];
cell.labelTitle.text = t.title;
cell.labelCat.text = t.cat;
cell.labelUser.text = [NSString stringWithFormat:#"%# %#", t.firstname, t.lastname];
cell.labelDate.text = [NSString stringWithFormat:#"%#", t.date];
cell.labelCountry.text = t.country;
cell.labelSubCat.text = t.subcat;
cell.rating = t.rating;
[cell.contentView setNeedsUpdateConstraints];
[cell.contentView updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
return cell;
}
}
Custom Cell:
#import "ThreadTableViewCell.h"
#implementation ThreadTableViewCell
#synthesize main;
#synthesize top;
#synthesize center;
#synthesize bottom;
#synthesize rate;
#synthesize rating;
#synthesize labelTitle;
#synthesize labelCat;
#synthesize labelSubCat;
#synthesize labelUser;
#synthesize labelDate;
#synthesize labelCountry;
#synthesize imageviewThreadImage;
#synthesize imageviewRating1;
#synthesize imageviewRating2;
#synthesize imageviewRating3;
#synthesize imageviewRating4;
#synthesize imageviewRating5;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//self.contentView.backgroundColor = [UIColor lightGrayColor];
[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];
labelTitle = [UILabel new];
[center addSubview:labelTitle];
labelTitle.translatesAutoresizingMaskIntoConstraints = NO;
[labelTitle sizeToFit];
labelTitle.lineBreakMode = NSLineBreakByWordWrapping;
[labelTitle setFont:[UIFont systemFontOfSize:14]];
labelTitle.textColor = [UIColor lightGrayColor];
labelTitle.numberOfLines = 0;
//labelTitle.preferredMaxLayoutWidth = screenWidth - 10 - 36;
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];
labelSubCat = [UILabel new];
[bottom addSubview:labelSubCat];
labelSubCat.translatesAutoresizingMaskIntoConstraints = NO;
[labelSubCat sizeToFit];
[labelSubCat setFont:[UIFont systemFontOfSize:12]];
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:12]];
labelCountry.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
rate = [UIView new];
[bottom addSubview:rate];
rate.translatesAutoresizingMaskIntoConstraints = NO;
[rate sizeToFit];
imageviewRating1 = [UIImageView new];
[rate addSubview:imageviewRating1];
imageviewRating1.translatesAutoresizingMaskIntoConstraints = NO;
[imageviewRating1 sizeToFit];
imageviewRating2 = [UIImageView new];
[rate addSubview:imageviewRating2];
imageviewRating2.translatesAutoresizingMaskIntoConstraints = NO;
[imageviewRating2 sizeToFit];
imageviewRating3 = [UIImageView new];
[rate addSubview:imageviewRating3];
imageviewRating3.translatesAutoresizingMaskIntoConstraints = NO;
[imageviewRating3 sizeToFit];
imageviewRating4 = [UIImageView new];
[rate addSubview:imageviewRating4];
imageviewRating4.translatesAutoresizingMaskIntoConstraints = NO;
[imageviewRating4 sizeToFit];
imageviewRating5 = [UIImageView new];
[rate addSubview:imageviewRating5];
imageviewRating5.translatesAutoresizingMaskIntoConstraints = NO;
[imageviewRating5 sizeToFit];
UIImage *imageStarDisabled = [UIImage imageNamed:#"star.png"];
//UIImage *imageStarEnabled = [UIImage imageNamed:#"star2.png"];
imageviewRating1.image = imageStarDisabled;
imageviewRating2.image = imageStarDisabled;
imageviewRating3.image = imageStarDisabled;
imageviewRating4.image = imageStarDisabled;
imageviewRating5.image = imageStarDisabled;
}
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.labelTitle.preferredMaxLayoutWidth = CGRectGetWidth(self.labelTitle.frame);
}
- (void)updateConstraints {
[super updateConstraints];
if (self.didSetupConstraints) return;
//UIImage *imageStarDisabled = [UIImage imageNamed:#"star.png"];
UIImage *imageStarEnabled = [UIImage imageNamed:#"star2.png"];
if(rating > 0){
for(int i = 1; i < rating + 1; i++){
if(i == 1){
imageviewRating1.image = imageStarEnabled;
}
if (i == 2) {
imageviewRating2.image = imageStarEnabled;
}
if (i == 3) {
imageviewRating3.image = imageStarEnabled;
}
if (i == 4) {
imageviewRating4.image = imageStarEnabled;
}
if (i == 5) {
imageviewRating5.image = imageStarEnabled;
}
}
}
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};
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 = #{#"labelTitle":labelTitle,#"imageviewThreadImage":imageviewThreadImage};
NSArray *constraint_H48 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[labelTitle]|"
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-[labelTitle]|"
options:0
metrics:nil
views:viewsDictionary48];
NSDictionary *viewsDictionary488 = #{#"labelCat":labelCat,#"labelCountry":labelCountry,#"labelSubCat":labelSubCat,#"rate":rate};
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_H48898fgf54fdf = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-5-[rate]|"
options:0
metrics:nil
views:viewsDictionary488];
NSArray *constraint_H4488 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[labelCat]-10-[labelSubCat]-10-[labelCountry]-10-[rate]"
options:0
metrics:nil
views:viewsDictionary488];
NSDictionary *viewsDictionary4885 = #{#"imageviewRating1":imageviewRating1,#"imageviewRating2":imageviewRating2,#"imageviewRating3":imageviewRating3,#"imageviewRating4":imageviewRating4,#"imageviewRating5":imageviewRating5};
NSArray *constraint_H488fbfb = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageviewRating1(15)]|"
options:0
metrics:nil
views:viewsDictionary4885];
NSArray *constraint_H48898xfb = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageviewRating2(15)]|"
options:0
metrics:nil
views:viewsDictionary4885];
NSArray *constraint_H48898xfbfg = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageviewRating3(15)]|"
options:0
metrics:nil
views:viewsDictionary4885];
NSArray *constraint_H48898xfbxfg = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageviewRating4(15)]|"
options:0
metrics:nil
views:viewsDictionary4885];
NSArray *constraint_H48898xfrtbxfg = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageviewRating5(15)]|"
options:0
metrics:nil
views:viewsDictionary4885];
NSArray *constraint_H48898fgf54fxb = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imageviewRating1(15)]-2-[imageviewRating2(15)]-2-[imageviewRating3(15)]-2-[imageviewRating4(15)]-2-[imageviewRating5(15)]"
options:0
metrics:nil
views:viewsDictionary4885];
[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_H4488];
[main addConstraints:constraint_H48898];
[main addConstraints:constraint_H48342];
[main addConstraints:constraint_H48898fgf54];
[main addConstraints:constraint_H48898fgf54fdf];
[bottom addConstraints:constraint_H488fbfb];
[bottom addConstraints:constraint_H48898xfb];
[bottom addConstraints:constraint_H48898xfbfg];
[bottom addConstraints:constraint_H48898xfbxfg];
[bottom addConstraints:constraint_H48898xfrtbxfg];
[bottom addConstraints:constraint_H48898fgf54fxb];
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
ViewController that sets the rating from the Database:
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 3) Load picker in background
dispatch_async(concurrentQueue, ^{
NSString *myRequestString = [NSString stringWithFormat:#"threadTitle=%#&threadCountry=%#&threadCategory=%#&threadSubCategory=%#",searchThreadTitleTopThreads, searchThreadCountryTopThreads, searchThreadCategoryTopThreads, searchThreadSubCategoryTopThreads];
__block NSString *response = [self setupPhpCall:myRequestString :#"xxx.php"];
dispatch_async(dispatch_get_main_queue(), ^{
if(response.length > 0){
NSDictionary *dic = [response JSONValue];
if((NSNull*)dic != [NSNull null]){
int at_ID = 0;
int at_U_ID = 0;
int rating = 0;
NSString *at_Title;
NSString *at_Desc;
NSString *at_Cat;
NSString *at_SubCat;
NSString *at_Date;
NSString *at_Country;
NSString *at_FirstName;
NSString *at_LastName;
for(NSDictionary *dict in dic)
{
counter = counter + 1;
if((NSNull *)[dict objectForKey:#"AT_ID"] != [NSNull null]){
at_ID = [[dict objectForKey:#"AT_ID"] intValue];
}
if((NSNull *)[dict objectForKey:#"AT_U_ID"] != [NSNull null]){
at_U_ID = [[dict objectForKey:#"AT_U_ID"] intValue];
}
if((NSNull *)[dict objectForKey:#"AT_Title"] != [NSNull null]){
at_Title = [dict objectForKey:#"AT_Title"];
}
if((NSNull *)[dict objectForKey:#"AT_Desc"] != [NSNull null]){
at_Desc = [dict objectForKey:#"AT_Desc"];
}
if((NSNull *)[dict objectForKey:#"AT_Cat"] != [NSNull null]){
at_Cat = [dict objectForKey:#"AT_Cat"];
}
if((NSNull *)[dict objectForKey:#"AT_SubCat"] != [NSNull null]){
at_SubCat = [dict objectForKey:#"AT_SubCat"];
}
if((NSNull *)[dict objectForKey:#"AT_Country"] != [NSNull null]){
at_Country = [dict objectForKey:#"AT_Country"];
}
if((NSNull *)[dict objectForKey:#"U_FirstName"] != [NSNull null]){
at_FirstName = [dict objectForKey:#"U_FirstName"];
}
if((NSNull *)[dict objectForKey:#"U_LastName"] != [NSNull null]){
at_LastName = [dict objectForKey:#"U_LastName"];
}
if((NSNull *)[dict objectForKey:#"AVG(r.TR_Value)"] != [NSNull null]){
rating = [[dict objectForKey:#"AVG(r.TR_Value)"] intValue];
}
NSString *dateTS = [dict objectForKey:#"AT_Date"];
if((NSNull *)[dict objectForKey:#"AT_Date2"] != [NSNull null]){
NSString *timestampString = [dict objectForKey:#"AT_Date2"];
double timestampDate = [timestampString doubleValue];
NSDate *d = [NSDate dateWithTimeIntervalSince1970:timestampDate];
NSDateFormatter *_formatter=[[NSDateFormatter alloc]init];
[_formatter setDateFormat:#"dd.MM.yyyy HH:mm:ss"];
at_Date = [_formatter stringFromDate:d];
if (counter == 1) {
//lastDateForumActivity = dateTS;
}
}
if(counter == 1){
//lastDateForumActivity = dateTS;
}
Thread *thread = [[Thread alloc] init];
thread.tag = at_ID;
thread.idUser = at_U_ID;
thread.firstname = at_FirstName;
thread.lastname = at_LastName;
thread.idThread = at_ID;
thread.title = at_Title;
thread.desc = at_Desc;
thread.cat = at_Cat;
thread.date = at_Date;
thread.country = at_Country;
thread.subcat = at_SubCat;
thread.rating = rating; //RATING SET
[tmpArray4 addObject:thread];
//cell = nil;
}
at_ID = 0;
at_U_ID = 0;
at_Title = #"";
at_Desc = #"";
at_Cat = #"";
at_Date = #"";
at_Country = #"";
at_FirstName = #"";
at_LastName = #"";
}
}

You're problem is that you don't account for the cells being reused. Because the cells are reused, the initialization of the cells set the image to your disabled stars, but in your code to set the stars correctly, you only toggle them to the enabled star image. You never set them back if the current cell's rating is 0, but it is being applied to a reused cell that had a rating of 3. So your code will not change any of the images, so the 3 enabled star images will remain.
Add a setter for the rating property with something like this. Also, as of Xcode 4.4 or so, #synthesize isn't needed, so you can get rid of that.
- (void)setRating: (int)newRatingValue {
_rating = newRatingValue;
UIImage *imageStarDisabled = [UIImage imageNamed:#"star.png"];
UIImage *imageStarEnabled = [UIImage imageNamed:#"star2.png"];
imageviewRating1.image = rating >= 1 ? imageStarEnabled : imageStarDisabled;
imageviewRating2.image = rating >= 2 ? imageStarEnabled : imageStarDisabled;
imageviewRating3.image = rating >= 3 ? imageStarEnabled : imageStarDisabled;
imageviewRating4.image = rating >= 4 ? imageStarEnabled : imageStarDisabled;
imageviewRating5.image = rating >= 5 ? imageStarEnabled : imageStarDisabled;
}
I believe the below will work, although if you're updating the rating on the background thread, it may cause some problems. You may need to wrapp the updating of the images in a dispatch async call to execute it on the main (UI) thread like so:
dispatch_async( dispatch_get_main_queue(), ^{
imageviewRating1.image = rating >= 1 ? imageStarEnabled : imageStarDisabled;
imageviewRating2.image = rating >= 2 ? imageStarEnabled : imageStarDisabled;
imageviewRating3.image = rating >= 3 ? imageStarEnabled : imageStarDisabled;
imageviewRating4.image = rating >= 4 ? imageStarEnabled : imageStarDisabled;
imageviewRating5.image = rating >= 5 ? imageStarEnabled : imageStarDisabled;
});`
Also, you should learn how to use the debugger to put breakpoints and step through your code, inspecting the state of things. It will go a long way to helping to troubleshoot and diagnose these types of issues in the future.

I moved your logic here and worked #wottle:
if(tableView == tableViewTopThreads){
static NSString *simpleTableIdentifier = #"SimpleTableItem";
ThreadTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//cell.layer.shouldRasterize = YES;
//cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
if (cell == nil) {
cell = [[ThreadTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
Thread *t = (Thread*)[tmpArray4 objectAtIndex:indexPath.row];
cell.labelTitle.text = t.title;
cell.labelCat.text = t.cat;
cell.labelUser.text = [NSString stringWithFormat:#"%# %#", t.firstname, t.lastname];
cell.labelDate.text = [NSString stringWithFormat:#"%#", t.date];
cell.labelCountry.text = t.country;
cell.labelSubCat.text = t.subcat;
cell.rating = t.rating;
UIImage *imageStarDisabled = [UIImage imageNamed:#"star.png"];
UIImage *imageStarEnabled = [UIImage imageNamed:#"star2.png"];
cell.imageviewRating1.image = t.rating >= 1 ? imageStarEnabled : imageStarDisabled;
cell.imageviewRating2.image = t.rating >= 2 ? imageStarEnabled : imageStarDisabled;
cell.imageviewRating3.image = t.rating >= 3 ? imageStarEnabled : imageStarDisabled;
cell.imageviewRating4.image = t.rating >= 4 ? imageStarEnabled : imageStarDisabled;
cell.imageviewRating5.image = t.rating >= 5 ? imageStarEnabled : imageStarDisabled;
[cell.contentView setNeedsUpdateConstraints];
[cell.contentView updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
return cell;
}
Is this the best place to put the logic?

Related

NSAttributedString with image attachment and NSTextTab, text not aligned

I'm trying to have a UIlabel with an image and title on the left and a list of descriptions with bullets on the right.
To do that I'm using NSAttributedString like this :
NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init];
pStyle.tabStops =
#[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:tabLocation options:[NSDictionary dictionary]] ];
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:#"test_image"];
textAttachment.bounds = CGRectMake(0, -3, 15, 15);//resize the image
attString = [NSAttributedString attributedStringWithAttachment:textAttachment].mutableCopy;
[attString appendAttributedString:[[NSAttributedString alloc]
initWithString:[NSString stringWithFormat:#"title\t\u2022 %#",
[#[ #"description1", #"description2" ]
componentsJoinedByString:#"\n\t\u2022 "]]
attributes:#{NSParagraphStyleAttributeName : pStyle}]];
label.attributedText = attString;
I expect the list on the right to be left aligned but that's not the case, here is the result I get:
What I expect is the list to be aligned like this:
The issue is with location parameter in NSTextTab
According to description, location parameter helps to position text from left margin. So this is what we needed, just replace below lines
pStyle.tabStops = #[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:tabLocation options:[NSDictionary dictionary]] ];
with
pStyle.tabStops = #[[[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:[self getTextLocationFor:#"test"] options:[NSDictionary dictionary]] ];
Add getTextLocationFor: method to calculate location as follows
-(CGFloat)getTextLocationFor:(NSString *)inputStr{
CGSize maximuminputStringWidth = CGSizeMake(FLT_MAX, 30);
CGRect textRect = [inputStr boundingRectWithSize:maximuminputStringWidth
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:15]}
context:nil];
UIImageView * testImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"close_red"]];//Change image name with yours
return textRect.size.width + testImage.frame.size.width +2;
}
That's it we are ready to go run your project now everything will be fine.
RESULT:
if I understand you correctly then try these code:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 460, 460)];
label.numberOfLines = 0;
[self.view addSubview:label];
NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init];
pStyle.tabStops = #[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:40 options:#{}] ];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:#"img"];
textAttachment.bounds = CGRectMake(0, -3, 30, 30);
NSString *string = [NSString stringWithFormat:#"title\n\r\u2022 %#", [#[ #"description1", #"description2" ] componentsJoinedByString:#"\n\r\u2022 "]];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString attributedStringWithAttachment:textAttachment] mutableCopy];
[attributedString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:string attributes:#{NSParagraphStyleAttributeName : pStyle}]];
label.attributedText = attributedString;
Here is result
UPDATE
You can only achieve this using TextKit (NSTextLayoutManager) and specify area which should be use to draw text, or use simple solution and subclass from UIView.
Here is solution with view
ListView.h
#interface ListView : UIView
#property(nonatomic,strong) UIImage *image;
#property(nonatomic,strong) NSString *title;
#property(nonatomic,strong) NSArray *list;
#end
ListView.m
static const CGFloat ImageWidth = 13.f;
#interface ListView()
#property (nonatomic,weak) UIImageView *imageView;
#property (nonatomic,weak) UILabel *titleLabel;
#property (nonatomic,weak) UILabel *listLabel;
#end
#implementation ListView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
[self setup];
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
[self setup];
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
[self setup];
}
- (void)setup {
UIImageView *imageView = [[UIImageView alloc] init];
imageView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:imageView];
self.imageView = imageView;
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
titleLabel.numberOfLines = 0;
[titleLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
[titleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
[self addSubview:titleLabel];
self.titleLabel = titleLabel;
UILabel *listLabel = [[UILabel alloc] init];
listLabel.translatesAutoresizingMaskIntoConstraints = NO;
listLabel.numberOfLines = 0;
[listLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
[listLabel setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
[self addSubview:listLabel];
self.listLabel = listLabel;
NSDictionary *views = NSDictionaryOfVariableBindings(imageView,titleLabel,listLabel);
NSDictionary *metrics = #{ #"ImageHeight" : #(ImageWidth) };
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[imageView(ImageHeight)]-0-[titleLabel]-0-[listLabel]-0-|" options:0 metrics:metrics views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[imageView(ImageHeight)]" options:NSLayoutFormatAlignAllTop metrics:metrics views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[titleLabel]" options:NSLayoutFormatAlignAllTop metrics:metrics views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[listLabel]-0-|" options:NSLayoutFormatAlignAllTop metrics:metrics views:views]];
}
- (void)setImage:(UIImage *)image {
_image = image;
self.imageView.image = image;
[self setNeedsLayout];
}
- (void)setTitle:(NSString *)title {
_title = title;
self.titleLabel.text = title;
[self setNeedsLayout];
}
- (void)setList:(NSArray *)list {
_list = list;
NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init];
pStyle.tabStops = #[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:40 options:#{}] ];
NSString *string = [NSString stringWithFormat:#"\u2022 %#", [list componentsJoinedByString:#"\n\u2022 "]];
self.listLabel.attributedText = [[NSAttributedString alloc] initWithString:string attributes:#{NSParagraphStyleAttributeName : pStyle}];
[self setNeedsLayout];
}
#end

Objective c - Can't get Auto Layout to work for UIWebView inside UIView

I have a custom UITableView Cell and inside the cell there are many subviews and they all use auto layout, they work fine apart from the UIWebView, i set it inside a UIView at H:|-5-[webView] and V:[webView] but the thing is that my cells dynamically resize and instead of the UIWebView sitting in its UIView the UIWebView sits 5 from the left and 0 from the top of the cell:
Here is the custom UITableViewCell:
#import "PostTableViewYoutubeCell.h"
#implementation PostTableViewYoutubeCell
#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 youtube;
#synthesize webviewYoutube;
#synthesize labelYoutubeTitle;
NSString *vID = #"";
- (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];
[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 = 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:12]];
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:12]];
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:12]];
labelCountry.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];
youtube = [UIView new];
[main addSubview:youtube];
youtube.translatesAutoresizingMaskIntoConstraints = NO;
[youtube sizeToFit];
webviewYoutube = [UIWebView new];
[youtube addSubview:webviewYoutube];
webviewYoutube.translatesAutoresizingMaskIntoConstraints = NO;
//[webviewYoutube sizeToFit];
[webviewYoutube setAllowsInlineMediaPlayback:YES];
[webviewYoutube setMediaPlaybackRequiresUserAction:NO];
youtube.backgroundColor = [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];
//NSString *text = labelMessage.text;
NSDictionary *viewsDictionary3 = #{#"top":top,#"center":center,#"bottom":bottom,#"youtube":youtube};
NSArray *constraint_H3 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-10-[top]-5-[center(>=50)]-5-[bottom]-5-[youtube(100)]-10-|"
options:0
metrics:nil
views:viewsDictionary3];
NSArray *constraint_H33cvcv4545 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[youtube]|"
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];
NSDictionary *viewsDictionary8 = #{#"webviewYoutube":webviewYoutube};
NSArray *constraint_H378 = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[webviewYoutube(80)]"
options:0
metrics:nil
views:viewsDictionary8];
NSArray *constraint_V378 = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[webviewYoutube(100)]"
options:0
metrics:nil
views:viewsDictionary8];
[youtube addConstraints:constraint_H378];
[youtube addConstraints:constraint_V378];
[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_H448345fgdfgdfdf454];
[self.contentView addConstraints:constraint_H33cvcv4545];
self.didSetupConstraints = YES;
}
-(void)setYoutube: (NSString*)youtubeID :(NSString*)title {
dispatch_async( dispatch_get_main_queue(), ^{
NSString* embedHTML = [NSString stringWithFormat:#"\
<html>\
<body style='margin:0px;padding:0px;'>\
<script type='text/javascript'>\
</script>\
<iframe id='playerId' type='text/html' width='%d' height='%d' src='http://www.youtube.com/embed/%#?enablejsapi=1&rel=0&playsinline=1' frameborder='0'>\
</body>\
</html>", 100, 80, youtubeID];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[webviewYoutube loadHTMLString:embedHTML baseURL:[[NSBundle mainBundle] resourceURL]];
});
}
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end

buttons repeat issue in Dynamic adding using Visual Format Language

I am using the below function to add buttons same like Fred and No in the next line but no getting same button size and text at same place.
- (IBAction)addAnotherBranchField:(id)sender
{
NSLog(#"Add Another Branch");
UIView *superview = self;
_buttons = [NSMutableArray array];
self.translatesAutoresizingMaskIntoConstraints = NO;
self.backgroundColor = [UIColor clearColor];
_verticalButtonConstraints = [NSMutableArray array];
NSString* previousAnswer = [_datasource valueForField:_field.guid branchIndex:0];
id buttonForLoadedAnswer = nil;
for (FormListOption* option in _field.options) {
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.translatesAutoresizingMaskIntoConstraints = NO;
//Add a little padding around the text - Using edge insets does not play well with the autolayout so do it with a space instead
[button setTitle:[NSString stringWithFormat:#" %# ",option.text] forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[_buttons addObject:button];
[superview addSubview: button];
if ([option.text isEqualToString:previousAnswer]) {
buttonForLoadedAnswer = button;
}
}
paddingCounter = paddingCounter + 100;
UIButton *addButton = [[UIButton alloc] initWithFrame:CGRectMake(200, paddingCounter, 32, 32)];
[addButton setImage:[UIImage imageNamed:#"nav_newanswers.png"] forState:UIControlStateNormal];
[addButton addTarget:self action:#selector(addAnotherBranchField:) forControlEvents:UIControlEventTouchUpInside];
[superview addSubview:addButton];
[superview bringSubviewToFront:addButton];
//Add the constraints
NSMutableDictionary* views = [NSMutableDictionary dictionary];
NSMutableString* visualLayout = [NSMutableString stringWithString:#"H:|-(5)-"];
for (NSInteger i=0; i < [_buttons count]; i++) {
NSString* name = [NSString stringWithFormat:#"button_%d", i];
[views setValue:[_buttons objectAtIndex:i] forKey:name];
[visualLayout appendFormat:#"[%#(>=80)]-", name];
}
[visualLayout appendString:#"(>=10)-|"];
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualLayout
options:NSLayoutFormatAlignAllBottom
metrics:nil
views:views]];
}
- (void)updateVerticalConstrainsAgain:(UIView*)expandedView padding:(float)padding
{
[self removeConstraints:_verticalButtonConstraints];
[_verticalButtonConstraints removeAllObjects];
NSString* visualFormat = [NSString stringWithFormat: #"V:|[button]-(5)-%#|", expandedView ? [NSString stringWithFormat:#"[expanded]-(20)-"] : #""];
if (padding != 0 && expandedView == nil)
{
visualFormat = [NSString stringWithFormat:#"V:|[button(button)]-(%f)-|",padding];
}
for (UIView* button in _buttons) {
NSMutableDictionary* views = [NSMutableDictionary dictionaryWithObject:button forKey:#"button"];
if (expandedView) {
[views setObject:button forKey:#"expanded"];
}
NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:visualFormat
options:0
metrics:nil
views:views];
[self addConstraints:constraints];
[_verticalButtonConstraints addObjectsFromArray:constraints];
}
}
Please explain me whaere i am getting wrong. spend my full day to get out from problems.

Terminated due to Memory Error when load number of view into UIScrollView

I am using UIScrollView in my app that 25 view first time.
user scroll on bottom next 25 view add in scrollview.
I am still entirely not sure this is a memory problem.But i didn't found the code cause of the Memory Problem.
Even I have checked memory leak issue through the instrument tool there is no memory leak.
My code:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float scrollViewHeight = _scrl_ipad.frame.size.height;
float scrollContentSizeHeight = _scrl_ipad.contentSize.height;
float scrollOffset = _scrl_ipad.contentOffset.y;
if (scrollOffset == 0)
{
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
if (scrl_bottom_reload_view)
{
scrl_bottom_reload_view=nil;
[scrl_bottom_reload_view release];
}
scrl_bottom_reload_view = [[UIView alloc]initWithFrame:CGRectMake(10, scrollContentSizeHeight-100, _scrl_ipad.frame.size.width-20, 60.0)];
scrl_bottom_reload_view.tag = -50;
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake((_scrl_ipad.frame.size.width/2)-100, 10, 200, 40)];
lbl.font = [UIFont fontWithName:#"ArialMT" size:22];
lbl.textColor = [UIColor darkGrayColor];
lbl.backgroundColor = [UIColor clearColor];
lbl.text = #"Loading deals...";
[scrl_bottom_reload_view addSubview:lbl];
[lbl release];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.alpha = 1.0;
activityIndicator.color = [UIColor lightGrayColor];
activityIndicator.frame = CGRectMake((_scrl_ipad.frame.size.width/2)-150, 12, 37, 37);
activityIndicator.hidesWhenStopped = NO;
[scrl_bottom_reload_view addSubview:activityIndicator];
[activityIndicator startAnimating];
scrl_bottom_reload_view.hidden = FALSE;
scrl_bottom_reload_view.backgroundColor = [UIColor clearColor];
[self.scrl_ipad addSubview:scrl_bottom_reload_view];
[self performSelector:#selector(LoadScrl) withObject:nil afterDelay:0.3];
}
}
-(void)LoadScrl
{
//called api and fill arrayalldeals arry
[self func_scrl_ipad];
}
-(void)func_scrl_ipad
{
NSArray *viewsToRemove = [_scrl_ipad subviews];
for (UIView *view in viewsToRemove)
{
[view removeFromSuperview];
view = nil;
}
int temp;
if([arrayalldeals count] % 2 == 0)
{
temp = ([arrayalldeals count] / 2);
}
else
{
temp = ([arrayalldeals count] / 2) + 1;
}
_scrl_ipad.contentSize = CGSizeMake(768,(258*temp)+150);
_scrl_ipad.showsVerticalScrollIndicator=NO;
int x = 35;
int y = 35;
for (int i = 1 ; i <= [arrayalldeals count]; i++)
{
UIView *bgview = [[UIView alloc]initWithFrame:CGRectMake(x, y, 328, 243)];
bgview.backgroundColor = [UIColor whiteColor];
//bgview.layer.borderWidth = 0;
//bgview.layer.cornerRadius = 0;
bgview.tag = i;
//bgview.layer.masksToBounds = YES;
//bgview.layer.borderColor =[[UIColor clearColor] CGColor];
//bgview.layer.shadowColor = [[UIColor whiteColor] CGColor];
//bgview.layer.shadowOffset = CGSizeMake(0.0, 0.0);
//bgview.layer.shadowOpacity = 0.0;
AsyncImageView *imageView = [[AsyncImageView alloc] initWithFrame:CGRectMake(0, 0, 328, 223)];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
imageView.layer.cornerRadius = 0;
imageView.imageURL =[NSURL URLWithString:[NSString stringWithFormat:#"%#uploads/%#-5.jpg",app.Main_url,[[arrayalldeals objectAtIndex:i-1] objectForKey:#"deal_id"]]];
//cell.autoresizesSubviews=YES;
[bgview addSubview:imageView];
[imageView release];
UIView *shadoeview = [[UIView alloc]initWithFrame:CGRectMake(0,115, 328, 112)];
CAGradientLayer *bgLayer = [BackgroundLayer greyGradient];
bgLayer.frame = shadoeview.bounds;
[shadoeview.layer insertSublayer:bgLayer atIndex:0];
shadoeview.alpha = 0.9;
[bgview addSubview:shadoeview];
[shadoeview release];
UIImageView *img_discount = [[UIImageView alloc]initWithFrame:CGRectMake(0,0, 57, 57)];
img_discount.image = [UIImage imageNamed:#"discount_tag.png"];
[bgview addSubview:img_discount];
[img_discount release];
UILabel *lbl_disc_text=[[UILabel alloc]init];
lbl_disc_text.frame=CGRectMake(-2,-10,100,20);
lbl_disc_text.backgroundColor=[UIColor clearColor];
lbl_disc_text.font = [UIFont fontWithName:#"ArialMT" size:14];
lbl_disc_text.textColor = [UIColor whiteColor];
int disc = 0;
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"])
{
int main_price = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"] intValue];
int disc_price = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"price"] intValue];
int multiply = disc_price *100 /main_price;
disc = 100 - multiply;
}
lbl_disc_text.text = [NSString stringWithFormat:#"- %d%%",disc];
[bgview addSubview:lbl_disc_text];
float degrees = -40; //the value in degrees
lbl_disc_text.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);
[lbl_disc_text release];
UILabel *lbl_desc=[[UILabel alloc]init];
lbl_desc.frame=CGRectMake(8,162, 240, 50);
lbl_desc.backgroundColor=[UIColor clearColor];
lbl_desc.font = [UIFont fontWithName:#"Arial Rounded MT Bold" size:16];
lbl_desc.textColor = [UIColor whiteColor];
lbl_desc.numberOfLines = 2 ;
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"name"])
{
lbl_desc.text=[NSString stringWithFormat:#"%#",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"name"]];
}
else
{
lbl_desc.text=#"";
}
[bgview addSubview:lbl_desc];
[lbl_desc release];
UILabel *lbl_unprice=[[UILabel alloc]init];
lbl_unprice.frame=CGRectMake(255,165,60,20);
lbl_unprice.backgroundColor=[UIColor clearColor];
lbl_unprice.textAlignment = NSTextAlignmentRight;
lbl_unprice.textColor = [UIColor whiteColor];
lbl_unprice.font = [UIFont fontWithName:#"ArialMT" size:14];
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"])
{
int unprice = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"] intValue];
lbl_unprice.text = [NSString stringWithFormat:#"$%d",unprice];
}
else
{
lbl_unprice.text=[NSString stringWithFormat:#"$0"];
}
[bgview addSubview:lbl_unprice];
[lbl_unprice release];
NSString *str_price_line;
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"])
{
int unprice = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"] intValue];
str_price_line = [NSString stringWithFormat:#"$%d",unprice];
}
else
{
str_price_line=[NSString stringWithFormat:#"$0"];
}
UIFont *font = [UIFont fontWithName:#"ArialMT" size:14];
CGSize size = [(str_price_line ? str_price_line : #"") sizeWithFont:font constrainedToSize:CGSizeMake(281, 9999) lineBreakMode:NSLineBreakByWordWrapping];
int temp = 60 - size.width;
UILabel *lbl_line=[[UILabel alloc]init];
lbl_line.frame=CGRectMake(253+temp,174,size.width+4,2);
lbl_line.backgroundColor=[UIColor colorWithRed:252.0/255.0 green:36.0/255.0 blue:148.0/255.0 alpha:1.0];
float degre = -20; //the value in degrees
lbl_line.transform = CGAffineTransformMakeRotation(degre * M_PI/250);
[bgview addSubview:lbl_line];
[lbl_line release];
UILabel *lbl_price=[[UILabel alloc]init];
lbl_price.frame=CGRectMake(215,180, 100, 35);
lbl_price.textAlignment = NSTextAlignmentRight;
lbl_price.backgroundColor=[UIColor clearColor];
lbl_price.font = [UIFont fontWithName:#"ArialMT" size:24];
lbl_price.textColor = [UIColor colorWithRed:93.0/255.0 green:202.0/255.0 blue:242.0/255.0 alpha:1.0];
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"price"])
{
int price = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"price"] intValue];
lbl_price.text = [NSString stringWithFormat:#"$%d",price];
}
else
{
lbl_price.text=[NSString stringWithFormat:#"$0"];
}
[bgview addSubview:lbl_price];
[lbl_price release];
UILabel *lbl_bottom_view=[[UILabel alloc]init];
lbl_bottom_view.frame=CGRectMake(0,223, 328,20);
lbl_bottom_view.backgroundColor=[UIColor darkGrayColor];
[bgview addSubview:lbl_bottom_view];
[lbl_bottom_view release];
UILabel *lbl_vertical1=[[UILabel alloc]init];
lbl_vertical1.frame=CGRectMake(100,223,2,20);
lbl_vertical1.backgroundColor=[UIColor grayColor];
[bgview addSubview:lbl_vertical1];
[lbl_vertical1 release];
UILabel *lbl_vertical2=[[UILabel alloc]init];
lbl_vertical2.frame=CGRectMake(222,223,2,20);
lbl_vertical2.backgroundColor=[UIColor grayColor];
[bgview addSubview:lbl_vertical2];
[lbl_vertical2 release];
UILabel *lbl_address=[[UILabel alloc]init];
lbl_address.frame=CGRectMake(4,226, 94, 14);
lbl_address.textAlignment = NSTextAlignmentCenter;
lbl_address.backgroundColor=[UIColor clearColor];
lbl_address.font = [UIFont fontWithName:#"ArialMT" size:12];
lbl_address.textColor = [UIColor whiteColor];
if ((NSNull *)app.city_dict == NULL)
{
lbl_address.text= #"Vancouver";
}
else
{
lbl_address.text=[NSString stringWithFormat:#"%#",[app.city_dict objectForKey:#"title"]];
}
[bgview addSubview:lbl_address];
[lbl_address release];
//LeftTime
NSString *strDatehere = [NSString stringWithFormat:#"%#",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"d_expires"]];
NSDateFormatter *heredateFormatter = [[NSDateFormatter alloc] init];
[heredateFormatter setDateFormat:#"yyyy-MM-dd"]; // set date formate with your dates
NSDate *datehere = [heredateFormatter dateFromString: strDatehere];
NSTimeInterval timeDifference = [datehere timeIntervalSinceDate:[NSDate date]];
[heredateFormatter release];
double hours = timeDifference / 3600;
NSInteger remainder = ((NSInteger)timeDifference)% 3600;
double minutes = remainder / 60;
double seconds = remainder % 60;
NSString *strleft_time = [NSString stringWithFormat:#"%.0fh, %.0fm, %.0fs",hours,minutes,seconds];
UILabel *lbl_time=[[UILabel alloc]init];
lbl_time.frame=CGRectMake(105,226, 110, 14);
lbl_time.textAlignment = NSTextAlignmentCenter;
lbl_time.backgroundColor=[UIColor clearColor];
lbl_time.font = [UIFont fontWithName:#"ArialMT" size:12];
lbl_time.textColor = [UIColor whiteColor];
lbl_time.text=strleft_time;
[bgview addSubview:lbl_time];
[lbl_time release];
UILabel *lbl_bought=[[UILabel alloc]init];
lbl_bought.frame=CGRectMake(222,226, 98, 14);
lbl_bought.textAlignment = NSTextAlignmentCenter;
lbl_bought.backgroundColor=[UIColor clearColor];
lbl_bought.font = [UIFont fontWithName:#"ArialMT" size:12];
lbl_bought.textColor = [UIColor whiteColor];
lbl_bought.text= [NSString stringWithFormat:#"%# Bought",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"buys"]];
[bgview addSubview:lbl_bought];
[lbl_bought release];
UIButton *btn_scrl=[UIButton buttonWithType:UIButtonTypeCustom];
[btn_scrl setFrame:CGRectMake(0,0, 328, 243)];
btn_scrl.tag=i-1;
[btn_scrl addTarget:self action:#selector(btn_scrl_tag:) forControlEvents:UIControlEventTouchUpInside];
[bgview addSubview:btn_scrl];
UIButton *btn_fav=[UIButton buttonWithType:UIButtonTypeCustom];
[btn_fav setFrame:CGRectMake(285,5, 35, 35)];
if([[[arrayalldeals objectAtIndex:i-1] objectForKey:#"user_faves"] isEqualToString:#"1"])
{
[btn_fav setBackgroundImage:[UIImage imageNamed:#"all_deals_fave_pink_icon.png"] forState:UIControlStateNormal];
}
else
{
[btn_fav setBackgroundImage:[UIImage imageNamed:#"all_deals_fave_icon.png"] forState:UIControlStateNormal];
}
[btn_fav.titleLabel setFont:[UIFont boldSystemFontOfSize:12]];
if([[[arrayalldeals objectAtIndex:i-1] objectForKey:#"faves"] isEqualToString:#"0"])
{
[btn_fav setTitle:#"" forState:UIControlStateNormal];
}
else
{
[btn_fav setTitle:[NSString stringWithFormat:#"%#",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"faves"]] forState:UIControlStateNormal];
}
btn_fav.tag=i-1;
[btn_fav addTarget:self action:#selector(btn_favorite:) forControlEvents:UIControlEventTouchUpInside];
[bgview addSubview:btn_fav];
[_scrl_ipad addSubview:bgview];
[bgview release];
if(i % 2 == 0)
{
y = y + 258;
x = 35;
}
else
{
x = 399;
}
}
}
}
////
now api called more then 10 times i got Terminated due to Memory Pressure Error and App crase
Didn't understand, what are you trying to do? But found many bugs in your code. List out some of them.
1) In this line, you already set as nil and try to release nil object. This won't release any object, this is main reason for memory leak.
if (scrl_bottom_reload_view)
{
scrl_bottom_reload_view=nil;
[scrl_bottom_reload_view release];
}
2) Try to assign nil to local variable which does nothing.
for (UIView *view in viewsToRemove)
{
[view removeFromSuperview];
view = nil;
}
3) Where did you release this object.
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc].....
Suggestion : Above code is more complex, try with Tableview. Use xib to like this job. Otherwise more complex to design as well consume more time to develop.

depth loop an array use block or something others

I had an comments array, witch contains the comment message and the reply message and follow the reply message.want to show all the messages orderly, seems its An infinite loop.
My code is like below:
if (self.commentArray.count > 0) {
//comments
NSDictionary *message = [self.commentArray objectAtIndex:indexPath.row];
if ([FHWServiceManager isValidObject:[message objectForKey:#"UserIcon"]]) {
[cell.photoImageView setImageWithURL:[NSURL URLWithString:[message objectForKey:#"UserIcon"]] placeholderImage:[UIImage imageNamed:#"face_poor"]];
}else {
cell.photoImageView.image = [UIImage imageNamed:#"face_poor"];
}
cell.photoImageView.layer.cornerRadius = 15;
cell.photoImageView.layer.masksToBounds = YES;
cell.nameLabel.text = [message objectForKey:#"Username"];
cell.nameLabel.textColor = UIColorFromRGB(0xbf6327);
cell.contentLabel.text = [message objectForKey:#"Comment"];
cell.timeLabel.text = [DateUtil timePassedDescriptionFor:[DateUtil dateFromRFC3339DateString:[message objectForKey:#"CreateTime"]]];
//follow comment
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"PId == %d",[[message objectForKey:#"Id"] intValue]];
NSArray *tempArray = [self.replyCommentArray filteredArrayUsingPredicate:predicate];
if (tempArray.count > 0) {
UIImageView *triangleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(67, 80, 10, 5)];
triangleImageView.image = [UIImage imageNamed:#"comment_reply_arrow_top"];
[cell.contentView addSubview:triangleImageView];
UIView *followBackView = [[UIView alloc] initWithFrame:CGRectMake(55, 85, 245, tempArray.count * 21 + 10)];
followBackView.backgroundColor = UIColorFromRGB(0xf6f6f6);
followBackView.layer.cornerRadius = 5;
float lastHeight = 0.0;
for (int i = 0; i < tempArray.count; i ++) {
NSDictionary *replyMessage = [tempArray objectAtIndex:i];
NSString *replyStr;
replyStr = [NSString stringWithFormat:#"%#: %#",[replyMessage objectForKey:#"Username"],[replyMessage objectForKey:#"Comment"]];
TTTAttributedLabel *followCommentLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(5, lastHeight + 5, followBackView.frame.size.width, 21)];
// followCommentLabel.numberOfLines = 0;
followCommentLabel.font = [UIFont systemFontOfSize:13];
followCommentLabel.textColor = [UIColor darkGrayColor];
followCommentLabel.backgroundColor = [UIColor clearColor];
[followCommentLabel setText:replyStr afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange redColorRange = [[mutableAttributedString string] rangeOfString:[NSString stringWithFormat:#"%#:",[replyMessage objectForKey:#"Username"]] options:NSCaseInsensitiveSearch];
// Core Text APIs use C functions without a direct bridge to UIFont. See Apple's "Core Text Programming Guide" to learn how to configure string attributes.
NSDictionary *colorDic = [NSDictionary dictionaryWithObjectsAndKeys:UIColorFromRGB(0xbf6327),kCTForegroundColorAttributeName, nil];
[mutableAttributedString addAttributes:colorDic range:redColorRange];
return mutableAttributedString;
}];
[followBackView addSubview:followCommentLabel];
UIButton *followButton = [UIButton buttonWithType:UIButtonTypeCustom];
followButton.frame = followCommentLabel.frame;
NSString *identify = [NSString stringWithFormat:#"%d",i];
[followButton setTitle:identify forState:UIControlStateSelected];
followButton.titleLabel.textColor = [UIColor clearColor];
[followButton addTarget:self action:#selector(handleFollowComment:) forControlEvents:UIControlEventTouchUpInside];
followButton.tag = indexPath.row + 10000;
[followBackView addSubview:followButton];
[followBackView bringSubviewToFront:followButton];
// CGSize size = [followCommentLabel.text sizeWithFont:followCommentLabel.font
// constrainedToSize:CGSizeMake(240, 800)
// lineBreakMode:NSLineBreakByWordWrapping];
// followCommentLabel.frame = CGRectMake(5, 0, 418, size.height);
predicate = [NSPredicate predicateWithFormat:#"PId == %d",[[replyMessage objectForKey:#"Id"] intValue]];
NSArray *subTempArray = [self.replyCommentArray filteredArrayUsingPredicate:predicate];
lastHeight += 21;
if (subTempArray.count > 0) {
lastHeight += subTempArray.count * 21;
float height = followBackView.frame.size.height;
height += 21*subTempArray.count;
followBackView.frame = CGRectMake(followBackView.frame.origin.x, followBackView.frame.origin.y, followBackView.frame.size.width, height);
float followLabelHeight = 0.0;
for (int j =0 ; j < subTempArray.count; j ++) {
NSDictionary *ohterMessage = [subTempArray objectAtIndex:j];
replyStr = [NSString stringWithFormat:#"%#reply%#: %#",[ohterMessage objectForKey:#"Username"],[replyMessage objectForKey:#"Username"],[ohterMessage objectForKey:#"Comment"]];
TTTAttributedLabel *subCommentLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(5, followCommentLabel.frame.origin.y + followCommentLabel.frame.size.height + followLabelHeight, followBackView.frame.size.width, 21)];
// subCommentLabel.numberOfLines = 0;
subCommentLabel.font = [UIFont systemFontOfSize:13];
subCommentLabel.textColor = [UIColor darkGrayColor];
subCommentLabel.backgroundColor = [UIColor clearColor];
[subCommentLabel setText:replyStr afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange redColorRange = [[mutableAttributedString string] rangeOfString:[NSString stringWithFormat:#"%#reply%#:",[ohterMessage objectForKey:#"Username"],[replyMessage objectForKey:#"Username"]] options:NSCaseInsensitiveSearch];
// Core Text APIs use C functions without a direct bridge to UIFont. See Apple's "Core Text Programming Guide" to learn how to configure string attributes.
NSDictionary *colorDic = [NSDictionary dictionaryWithObjectsAndKeys:UIColorFromRGB(0xbf6327),kCTForegroundColorAttributeName, nil];
[mutableAttributedString addAttributes:colorDic range:redColorRange];
return mutableAttributedString;
}];
[followBackView addSubview:subCommentLabel];
UIButton *subfollowButton = [UIButton buttonWithType:UIButtonTypeCustom];
subfollowButton.frame = subCommentLabel.frame;
NSString *subIdentify = [NSString stringWithFormat:#"%d-%d",i,j];
[subfollowButton setTitle:subIdentify forState:UIControlStateSelected];
subfollowButton.titleLabel.textColor = [UIColor clearColor];
[subfollowButton addTarget:self action:#selector(handleFollowComment:) forControlEvents:UIControlEventTouchUpInside];
subfollowButton.tag = indexPath.row + 10000;
[followBackView addSubview:subfollowButton];
[followBackView bringSubviewToFront:subfollowButton];
// CGSize size = [followCommentLabel.text sizeWithFont:followCommentLabel.font
// constrainedToSize:CGSizeMake(240, 800)
// lineBreakMode:NSLineBreakByWordWrapping];
// followCommentLabel.frame = CGRectMake(5, 0, 418, size.height);
predicate = [NSPredicate predicateWithFormat:#"PId == %d",[[ohterMessage objectForKey:#"Id"] intValue]];
NSArray *subFollowTempArray = [self.replyCommentArray filteredArrayUsingPredicate:predicate];
followLabelHeight += 21;
if (subFollowTempArray.count > 0) {
followLabelHeight += subFollowTempArray.count * 21;
lastHeight += subFollowTempArray.count * 21;
float height = followBackView.frame.size.height;
height += 21*subFollowTempArray.count;
followBackView.frame = CGRectMake(followBackView.frame.origin.x, followBackView.frame.origin.y, followBackView.frame.size.width, height);
for (int k =0 ; k < subFollowTempArray.count; k ++) {
NSDictionary *ohterFollowMessage = [subFollowTempArray objectAtIndex:k];
NSString *replyFollowStr = [NSString stringWithFormat:#"%#reply%#: %#",[ohterFollowMessage objectForKey:#"Username"],[ohterMessage objectForKey:#"Username"],[ohterFollowMessage objectForKey:#"Comment"]];
TTTAttributedLabel *subFollowCommentLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(5, subCommentLabel.frame.origin.y + subCommentLabel.frame.size.height + k * 21, followBackView.frame.size.width, 21)];
// subCommentLabel.numberOfLines = 0;
subFollowCommentLabel.font = [UIFont systemFontOfSize:13];
subFollowCommentLabel.textColor = [UIColor darkGrayColor];
subFollowCommentLabel.backgroundColor = [UIColor clearColor];
[subFollowCommentLabel setText:replyFollowStr afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange redColorRange = [[mutableAttributedString string] rangeOfString:[NSString stringWithFormat:#"%#reply%#:",[ohterFollowMessage objectForKey:#"Username"],[ohterMessage objectForKey:#"Username"]] options:NSCaseInsensitiveSearch];
// Core Text APIs use C functions without a direct bridge to UIFont. See Apple's "Core Text Programming Guide" to learn how to configure string attributes.
NSDictionary *colorDic = [NSDictionary dictionaryWithObjectsAndKeys:UIColorFromRGB(0xbf6327),kCTForegroundColorAttributeName, nil];
[mutableAttributedString addAttributes:colorDic range:redColorRange];
return mutableAttributedString;
}];
[followBackView addSubview:subFollowCommentLabel];
}
}
}
}
}
[cell.contentView addSubview:followBackView];
}
Try this, this may not be the exact solution. But you can follow this approach with some minor changes
- (NSArray *) replyforPid:(int) pID {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"PId == %d",pID];
NSArray *tempArray = [self.replyCommentArray filteredArrayUsingPredicate:predicate];
return tempArray;
}
- (void) addReplyInView:(UIView *) followBackView forPid:(int) pID lastHeight:(float) lastHeight {
NSArray *tempArray = [self replyforPid:pID];
if ([tempArray count] > 0) {
if (lastHeight != 0) {
float height = followBackView.frame.size.height;
height += 21*subTempArray.count;
followBackView.frame = CGRectMake(followBackView.frame.origin.x, followBackView.frame.origin.y, followBackView.frame.size.width, height);
}
for (int i = 0; i < tempArray.count; i ++) {
NSDictionary *replyMessage = [tempArray objectAtIndex:i];
NSString *replyStr;
replyStr = [NSString stringWithFormat:#"%#: %#",[replyMessage objectForKey:#"Username"],[replyMessage objectForKey:#"Comment"]];
TTTAttributedLabel *followCommentLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(5, lastHeight + 5, followBackView.frame.size.width, 21)];
followCommentLabel.font = [UIFont systemFontOfSize:13];
followCommentLabel.textColor = [UIColor darkGrayColor];
followCommentLabel.backgroundColor = [UIColor clearColor];
[followCommentLabel setText:replyStr afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange redColorRange = [[mutableAttributedString string] rangeOfString:[NSString stringWithFormat:#"%#:",[replyMessage objectForKey:#"Username"]] options:NSCaseInsensitiveSearch];
// Core Text APIs use C functions without a direct bridge to UIFont. See Apple's "Core Text Programming Guide" to learn how to configure string attributes.
NSDictionary *colorDic = [NSDictionary dictionaryWithObjectsAndKeys:UIColorFromRGB(0xbf6327),kCTForegroundColorAttributeName, nil];
[mutableAttributedString addAttributes:colorDic range:redColorRange];
return mutableAttributedString;
}];
[followBackView addSubview:followCommentLabel];
UIButton *followButton = [UIButton buttonWithType:UIButtonTypeCustom];
followButton.frame = followCommentLabel.frame;
NSString *identify = [NSString stringWithFormat:#"%d",i];
[followButton setTitle:identify forState:UIControlStateSelected];
followButton.titleLabel.textColor = [UIColor clearColor];
[followButton addTarget:self action:#selector(handleFollowComment:) forControlEvents:UIControlEventTouchUpInside];
[followBackView addSubview:followButton];
[followBackView bringSubviewToFront:followButton];
lastHeight += 21;
[self addReplyInView:followBackView forPid:[[replyMessage objectForKey:#"Id"] intValue] lastHeight:lastHeight];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.commentArray.count > 0) {
//comments
NSDictionary *message = [self.commentArray objectAtIndex:indexPath.row];
if ([FHWServiceManager isValidObject:[message objectForKey:#"UserIcon"]]) {
[cell.photoImageView setImageWithURL:[NSURL URLWithString:[message objectForKey:#"UserIcon"]] placeholderImage:[UIImage imageNamed:#"face_poor"]];
}else {
cell.photoImageView.image = [UIImage imageNamed:#"face_poor"];
}
cell.photoImageView.layer.cornerRadius = 15;
cell.photoImageView.layer.masksToBounds = YES;
cell.nameLabel.text = [message objectForKey:#"Username"];
cell.nameLabel.textColor = UIColorFromRGB(0xbf6327);
cell.contentLabel.text = [message objectForKey:#"Comment"];
cell.timeLabel.text = [DateUtil timePassedDescriptionFor:[DateUtil dateFromRFC3339DateString:[message objectForKey:#"CreateTime"]]];
//follow comment
NSArray *tempArray = [self replyforPid:[[message objectForKey:#"Id"] intValue]];
if (tempArray.count > 0) {
UIImageView *triangleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(67, 80, 10, 5)];
triangleImageView.image = [UIImage imageNamed:#"comment_reply_arrow_top"];
[cell.contentView addSubview:triangleImageView];
UIView *followBackView = [[UIView alloc] initWithFrame:CGRectMake(55, 85, 245, tempArray.count * 21 + 10)];
followBackView.backgroundColor = UIColorFromRGB(0xf6f6f6);
followBackView.layer.cornerRadius = 5;
[self addReplyInView:followBackView forPid:[[message objectForKey:#"Id"] intValue] intValue] lastHeight:0.0];
}
}
}

Resources