Helo all,
I am having a very strange situation here.I have a table view in which i have custom cells. So i have designed my own custom cell.In custom cell i am displaying the image as well text.The data of table comes from server.If any image in json then image will be displayed else only text is displayed.So cell will dynamic.I have used bezier path to wrap text around image.No if image is there so text will be wrapped.When i add new post from server with image & i refresh the table then it automatically display the image for other post as well.It will display the same image which is same image for last.I don;t know why new cell is adding image in it's cell even the code works fine i have dbugged it using breakpoints.Please tell what could be the issue.
Here is code for cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//define variables here
static NSString *CellIdentifier = #"homeCell";
HomeCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
if([arr_post count]>0)
{
NSMutableAttributedString *mutableAttributeStr;
NSAttributedString *attributeStr;
[cell layoutIfNeeded];
//get the post data
Post *user_post=[arr_post objectAtIndex:indexPath.row];
//set the button tags
cell.btn_like.tag=indexPath.row;
cell.btn_comment.tag=indexPath.row;
cell.btn_fav.tag=indexPath.row;
cell.btn_con.tag=indexPath.row;
cell.btn_book.tag=indexPath.row;
//add info to buttons
cell.btn_like.selected=user_post.isPostLiked;
cell.btn_comment.selected=user_post.isPostCommented;
cell.btn_fav.selected=user_post.isPostFavourite;
cell.btn_con.selected=user_post.isPostCondolence;
cell.btn_book.selected=user_post.isPostBookmarked;
//add user info
cell.label_name.text=user_post.username;
cell.img_profile.layer.cornerRadius = 25;
cell.img_profile.clipsToBounds = YES;
[cell.img_profile setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
//add location
if([user_post.location isEqualToString:#"Not Available"])
{
[cell.img_icon_location setHidden:true];
[cell.label_location setHidden:true];
}
else
{
[cell.img_icon_location setHidden:false];
[cell.label_location setHidden:false];
cell.label_location.text=user_post.location;
}
//ad post info
cell.tv_post.text=user_post.post_description;
cell.tv_post.font = [UIFont fontWithName:user_post.font_family size:[user_post.font_size floatValue]];
[cell.tv_post setTextColor:[self colorFromHexString:user_post.font_color]];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [formatter dateFromString:user_post.modification_date];
NSLog(#"user post image is %#",user_post.post_image);
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
NSLog(#"NOT INSIDE THE CONDITION");
}
else
{
NSLog(#"INSIDE BEIZER PATH CONDITION");
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)];
cell.tv_post.textContainer.exclusionPaths = #[imgRect];
UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)];
if(![user_post.post_image isEqualToString:#"none"])
{
[tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
if(![user_post.post_video isEqualToString:#"none"])
{
[tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
[cell.tv_post addSubview:tv_image];
}
//make textview height dynamic
cell.tv_post.scrollEnabled=NO;
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
CGFloat fixedWidth = cell.tv_post.frame.size.width;
CGSize newSize = [cell.tv_post sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = cell.tv_post.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
cell.tv_post.frame = newFrame;
cell.tv_height.constant=cell.tv_post.frame.size.height;
[cell.view_tvContainer layoutIfNeeded];
}
//set the border of uiview
cell.view_tvContainer.layer.borderColor = [UIColor blackColor].CGColor;
cell.view_tvContainer.layer.borderWidth = 2.0f;
//set the like count
NSString *first_like_user=recent_like_name=user_post.recent_like_name;
NSLog(#"FIRST LIEK USER IS %#",first_like_user);
NSString *str_recent_like_name;
int count=(int)[first_like_user length];
int like_count=[user_post.like_count intValue];
if(like_count>0)
{
cell.label_like_count.lineBreakMode=NSLineBreakByWordWrapping;
[cell.label_like_count sizeToFit];
[cell.label_like_count setHidden:false];
NSString *str_like_count=[NSString stringWithFormat:#"%lu",(unsigned long)like_count-1];
if(like_count==1)
{
if([myUsername isEqualToString:first_like_user])
{
first_like_user=#"You like this post ";
count=3;
}
else
{
first_like_user=[first_like_user stringByAppendingString:#" like this post"];
}
}
else if(like_count==2)
{
if([first_like_user isEqualToString:myUsername])
{
first_like_user=#"You";
}
Post *temp_user_post=[copy_arr_user_post objectAtIndex:indexPath.row];
first_like_user=[first_like_user stringByAppendingString:#" and "];
if(temp_user_post.recent_like_name==nil)
{
temp_user_post.recent_like_name=#"";
}
str_recent_like_name=[temp_user_post.recent_like_name_two stringByAppendingString:#" like this post"];
first_like_user=[first_like_user stringByAppendingString:str_recent_like_name];
}
else
{
if(like_count>1000)
{
like_count=like_count/1000;
str_like_count=[NSString stringWithFormat:#"%lu",(unsigned long)like_count];
str_like_count=[str_like_count stringByAppendingString:#"k"];
first_like_user=[first_like_user stringByAppendingString:#" and "];
str_like_count=[str_like_count stringByAppendingString:#" others like this post"];
first_like_user=[first_like_user stringByAppendingString:str_like_count];
}
else
{
if([first_like_user isEqualToString:myUsername])
{
first_like_user=#"You";
}
first_like_user=[first_like_user stringByAppendingString:#" and "];
str_like_count=[str_like_count stringByAppendingString:#" others like this post"];
first_like_user=[first_like_user stringByAppendingString:str_like_count];
}
}
mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:first_like_user];
attributeStr = [[NSAttributedString alloc]initWithString:#"\n" attributes:#{NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue-Bold" size:8]}];
[mutableAttributeStr addAttribute:NSFontAttributeName value: [UIFont fontWithName:#"Helvetica-Bold" size:14.0] range:NSMakeRange(0, count)];
[mutableAttributeStr addAttribute:NSForegroundColorAttributeName value:[self colorFromHexString:#"#48a0dd"] range:NSMakeRange(0, count)];
[mutableAttributeStr appendAttributedString:attributeStr];
[cell.label_like_count setAttributedText:mutableAttributeStr];
}
else
{
[cell.label_like_count setHidden:true];
}
// show dynamic comment
NSMutableArray *user_comments=user_post.comments;
float comment_count=[user_post.comment_count intValue];
NSLog(#"ID IS %#",user_post.id);
if(comment_count>0)
{
//make label multiline
cell.first_comment.lineBreakMode=NSLineBreakByWordWrapping;
[cell.first_comment sizeToFit];
cell.second_cmment.lineBreakMode=NSLineBreakByWordWrapping;
[cell.second_cmment sizeToFit];
cell.third_comment.lineBreakMode=NSLineBreakByWordWrapping;
[cell.third_comment sizeToFit];
if(comment_count==1)
{
[cell.first_comment setHidden:false];
[cell.second_cmment setHidden:true];
[cell.third_comment setHidden:true];
}
else if(comment_count==2)
{
[cell.first_comment setHidden:false];
[cell.second_cmment setHidden:false];
[cell.third_comment setHidden:true];
}
else
{
[cell.first_comment setHidden:false];
[cell.second_cmment setHidden:false];
[cell.third_comment setHidden:false];
[cell.btn_more_comments setHidden:false];
}
for(l=0;l<[user_comments count];l++)
{
Comment *comment=[user_comments objectAtIndex:l];
NSString *comment_string=[comment.user_name stringByAppendingString:#" "];
comment_string=[comment_string stringByAppendingString:comment.comment];
int count=(int)[comment.user_name length];
NSMutableAttributedString* mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:comment_string];
NSAttributedString *attributeStr = [[NSAttributedString alloc]initWithString:#"\n" attributes:#{NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue-Bold" size:8]}];
[mutableAttributeStr addAttribute:NSFontAttributeName value: [UIFont fontWithName:#"Helvetica-Bold" size:14.0] range:NSMakeRange(0, count)];
[mutableAttributeStr addAttribute:NSForegroundColorAttributeName value:[self colorFromHexString:#"#48a0dd"] range:NSMakeRange(0, count)];
[mutableAttributeStr appendAttributedString:attributeStr];
// end of the repetitive pattern
if (l == 0)
{
[cell.first_comment setAttributedText:mutableAttributeStr];
}
else if (l == 1)
{
[cell.second_cmment setAttributedText:mutableAttributeStr];
}
else if (l == 2)
{
[cell.third_comment setAttributedText:mutableAttributeStr];
}
}
}
else
{
[cell.first_comment setHidden:true];
[cell.second_cmment setHidden:true];
[cell.third_comment setHidden:true];
[cell.btn_more_comments removeFromSuperview];
}
cell.label_time.text=[BaseController timeAgoStringFromDate:date];
[arr_indexpath addObject:indexPath];
}
return cell;
}
Keep in mind that the cells is reused. If you have, say, 10000 rows in your table datasource, the table view won't create that many rows. It will only create enough rows to be displayed on the screen and a few others to be preloaded.
For every time you scroll your table, the tableview will use those cells that go invisible to load the new cells that just become visible, to make a illusion of infinite amount of rows. That why those new cells have the old data. So basically, you will have to set your UIImageView's image to nil in cellForRowAtIndexpath: if no image is available.
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
NSLog(#"NOT INSIDE THE CONDITION");
}
In the code of you above, you simply print out a log, while what you also have to do is setting the UIImageView's image to nil.
So this is my suggestion:
//if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
//{
// NSLog(#"NOT INSIDE THE CONDITION");
//}
//else
{
NSLog(#"INSIDE BEIZER PATH CONDITION");
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)];
cell.tv_post.textContainer.exclusionPaths = #[imgRect];
UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)];
if(![user_post.post_image isEqualToString:#"none"])
{
[tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
else{
[tv_image setImage:nil]; //Prevent the old data to be shown
}
if(![user_post.post_video isEqualToString:#"none"])
{
[tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
else{
[tv_image setImage:nil];//Prevent the old data to be shown
}
[cell.tv_post addSubview:tv_image];
}
Maybe this code doesn't fit your requirements about how the data will be displayed, but hope it helps you to get the idea!
When a tableview cell is needed to be displayed you will either create a new one or reuse one that you created previously but is no longer visible on screen. Since you have created a UIImageView and added it to a cell, when you reuse it the image is still there.
To stop this happening, you need to keep a reference to the imageview so the next time around you are able to remove it. Since you are adding them dynamically and don't have an IBOutlet your quickest option is to assign the image a tag
UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)];
tv_image.tag = 21; // arbitrary number but must be unique to the image
By tagging the image, the next time around you can get access to it:
UIImageView *tv_image = (UIImageView*)[cell viewWithTag:21];
if (tv_image != nil) {
tv_image.image = nil; // remove the image (or remove the image view from the cell etc)
}
Just be sure to refactor the code accordingly so that if you find the image from a tag you don't need to recreate it etc
Your img_profile is getting repeated because your are re-using the cell.
Replace the below line of code
[cell.img_profile setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
with below code:-
if (user_post.user_profileImage.length == 0) {
cell.img_profile.hidden = true;
}else{
[cell.img_profile setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
Explanation:-
Check if your json contains the user profile image then set the image, else hide the profile image view.
A table view reuses cells. This means that if you add a subview to a cell, as you do on the line [cell.tv_post addSubview:tv_image], then that subview will still be in the cell when it is reused.
Basically, if you are adding subviews to a custom cell in tableView:cellForRowAtIndexPath:, you are probably making a mistake.
Just design the tv_image view into the HomeCell in the first place. HomeView should have an outlet named tv_image, connected to the image view in your storyboard or XIB. When you need tv_image, show it. Otherwise, hide it.
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
NSLog(#"NOT INSIDE THE CONDITION");
cell.tv_image.image = nil;
cell.tv_image.hidden = YES;
cell.tv_post.textContainer.exclusionPaths = #[];
}
else
{
NSLog(#"INSIDE BEIZER PATH CONDITION");
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)];
cell.tv_post.textContainer.exclusionPaths = #[imgRect];
if(![user_post.post_image isEqualToString:#"none"])
{
[cell.tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
if(![user_post.post_video isEqualToString:#"none"])
{
[cell.tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
cell.tv_image.hidden = NO;
}
Also, make sure setImageWithURL:placeholderImage: doesn't set the image view's hidden = NO when it loads the image.
I wonder where you are allocating you custom cell. Shouldn't you be creating cell only if it's not created. Something like this:
static NSString *CellIdentifier = #"homeCell";
HomeCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(!cell)
{
cell = [[[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]];
}
And then updating the UI components.
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
NSLog(#"NOT INSIDE THE CONDITION");
}
else
{
NSLog(#"INSIDE BEIZER PATH CONDITION");
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)];
cell.tv_post.textContainer.exclusionPaths = #[imgRect];
UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)];
if(![user_post.post_image isEqualToString:#"none"])
{
[tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
if(![user_post.post_video isEqualToString:#"none"])
{
[tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
[cell.tv_post addSubview:tv_image];
}
perhaps you should write an "update method" inside your "HomeCell" class. To update the UI components.
I recommend to use [SDWebImage][1]https://github.com/rs/SDWebImage , where you can update your cell in completion block or cache image if need
The problem is two folds:
cells are reused, this is common place for miss, but not in your case.
your line [cell.img_profile setImageWithURL:...]; is asynchronous, which mean by the time the image is downloaded, your cell may be reused, so clearing the imageView at reuse won't help.
To properly use async-loading of image in a reusable cell, you have to double check that it's the correct image on loading success.
add a property to the cell class:
#property (weak) NSURL *targetImageUrl;
then change the loading to add a check:
NSURL *targetImageUrl = [NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]];
cell.targetImageUrl = targetImageUrl; // <!> replace latest target
[cell.img_profile
setImageWithURLRequest: [NSMutableURLRequest requestWithURL:targetImageUrl]
placeholderImage: [UIImage imageNamed:#"post_placeholder.png"]
success: ^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
if (cell.targetImageUrl != targetImageUrl) return; // <!> this is the trick
cell.img_profile.image = image;
}
failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
}];
Since the cellForRowAtIndexPath is called whenever the cell becomes visible, I always use the next strategy for displaying images that need to be loaded from the web: I either associate the image (when downloaded) with objc_setAssociatedObject with the object that contains data for table row, or create some hashMap where i put the images with some id for the key. Then in cellForRowAtIndexPath I check if associated object is nil (or if image for the key exists in hashmap). If it's nil or doesn't exist (which means it's still downloading) i set a placeholder image for the imageView's image, otherwise I set the downloaded image.
And after download you reload table (or just the needed cell)
Related
So, I have repeating views containing thumbnails, once a thumbnail is pressed the thumbnail ID is sent as the tag.
With this information I want to get the frame of the subview of that view;
- (IBAction)thumbPressed:(id)sender {
NSLog(#"Thumb %i pressed", (int)[sender tag]);
for (int i = 0; i < _thumbCounter; i++) {
if (i == [sender tag]) {
NSLog(#"thumb view %i", i);
//Up To HERE
break;
}
}
// [self moveToVideoControllerWithInfoID:[NSString stringWithFormat:#"%li", (long)[sender tag]]];
}
For the thumbnails to be drawn they're drawn in a random order retrieved by JSON.
The Button
UIButton *thumbButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[thumbButton addTarget:self
action:#selector(thumbPressed:)
forControlEvents:UIControlEventTouchUpInside];
thumbButton.frame = CGRectMake(0, 0, _thumbView.frame.size.width, _thumbView.frame.size.height);
thumbButton.tag = _thumbCounter;
[_thumbView addSubview:thumbButton];
The subview I want to get the frame of
NSString *string = [NSString stringWithFormat:#"***.jpg",Link];
NSURL * imageURL = [NSURL URLWithString:string];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(thumbGap, thumbGap, thumbHeight - 5, thumbHeight - 5)];
imageView.image = image;
[_thumbView addSubview:imageView];
Where the thumbnail shell is drawn
_thumbView = [[ThumbView alloc] initWithFrame:CGRectMake(0, margin, _scrollView.frame.size.width, thumbHeight)];
_thumbView.backgroundColor = [UIColor whiteColor];
_thumbView.thumbId = _thumbCounter;
[_scrollView addSubview:_thumbView];
_thumbview is a class of UIVIEW with the added thumbId
How once that button is pressed can I locate the imageView frame inside of _thumbview ( bare in mind there are multiple ).
First off, let's make life easier for you:
- (IBAction)thumbPressed:(UIButton*)sender {
NSLog(#"Thumb %i pressed", (int)[sender tag]);
ThumbView *thumbView = (ThumbView*)[sender superView];
for(UIView* subview in thumbView.subViews) {
if([subView iKindOfClass:[UIImageView class]]) {
//you got it here
}
}
}
You could shortcut the whole thing by making ThumbView have an imageView property as well.
I've tried to determine that this is what you are doing:
_scrollView
->_thumbView[0]
--->thumbButton
--->imageView
->_thumbView[1]
--->thumbButton
--->imageView
...
->_thumbView[N]
--->thumbButton
--->imageView
Assumed that you want the image view who is in the same thumbView as the button who is pressed.
Best Possible Solution (IMHO):
#Interface ThumbView()
#property (nonatomic,weak) UIImageView *imageView;
#end
AND:
(After making sure to first add, and THEN SET .imageView)
- (IBAction)thumbPressed:(UIButton*)sender {
NSLog(#"Thumb %i pressed", (int)[sender tag]);
UIImageView *imageView = ((ThumbView*)[sender superView]).imageView
}
for (UIView *i in _scrollView.subviews) {
if ([i isKindOfClass:[ThumbView class]]) {
ThumbView *tempThumb = (ThumbView *)i;
if (tempThumb.thumbId == (int)[sender tag]) {
for (UIView *y in tempThumb.subviews) {
if ([y isKindOfClass:[UIImageView class]]) {
UIImageView *tempIMG = (UIImageView *)y;
[self playVideo:[loadedInput objectForKey:#"link"] frame:tempIMG.frame andView:tempThumb];
}
}
}
}
}
I'm using the QuickBlox Framework to build a chatting application. Currently, when the chat view opens up, everything looks great.
However, when the users begins to scroll up and down the chat history, some of the cells begin to change (for example, they'll show an image which should be placed in a different row).
Below is my code for cellForRowAtIndexPath, if anyone can tell me what I'm doing wrong
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
QBChatMessage *message = [[ChatService shared] messagsForDialogId:self.dialog.ID][indexPath.row];
if (message.attachments.count > 0) {
ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ImageCellIdentifier];
[cell configureCellWithImage:message];
cell.backgroundColor = [UIColor whiteColor];
return cell;
} else {
ChatMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ChatMessageCellIdentifier];
[cell configureCellWithMessage:message];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
}
EDIT Please see below my ImageTableViewCell configureCellWithImage method:
- (void) configureCellWithImage:(QBChatMessage*)message {
NSString *time = [message.dateSent timeAgoSinceNow];
if ([QBSession currentSession].currentUser.ID == message.senderID) {
// Message was sent by me
NSData *imageData = [FTWCache objectForKey:[NSString stringWithFormat:#"%#", [message.attachments[0] valueForKey:#"ID"]]];
if (imageData) {
// image is already downloaded
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
UIImageView *cellImage = [[UIImageView alloc] init];
[self.backgroundImageView setFrame:CGRectMake(320-155, 10, 140, 140)];
cellImage.frame = CGRectMake(7, 7, 120, 120);
[cellImage setContentMode:UIViewContentModeScaleAspectFill];
cellImage.clipsToBounds = YES;
cellImage.layer.cornerRadius = 5;
cellImage.image = image;
self.backgroundImageView.image = aquaBubble;
[self.backgroundImageView addSubview:cellImage];
[self.contentView addSubview:self.backgroundImageView];
});
} else {
// downloads the image and displays as above
}
} else {
// Message was sent by another user
NSData *imageData = [FTWCache objectForKey:[NSString stringWithFormat:#"%#", [message.attachments[0] valueForKey:#"ID"]]];
if (imageData) {
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
UIImageView *cellImage = [[UIImageView alloc] init];
[self.backgroundImageView setFrame:CGRectMake(padding/2, padding+5, 140, 140)];
cellImage.frame = CGRectMake(13, 7, 120, 120);
[cellImage setContentMode:UIViewContentModeScaleAspectFill];
cellImage.layer.cornerRadius = 5;
cellImage.clipsToBounds = YES;
cellImage.image = image;
self.timeLabel.frame = CGRectMake(20, self.backgroundImageView.frame.size.height + 20, 80, 20);
self.timeLabel.text = [NSString stringWithFormat:#"%#", time];
[self.timeLabel setFont:[UIFont systemFontOfSize:10.0]];
[self.timeLabel setTextColor:[UIColor blackColor]];
[self.contentView addSubview:self.timeLabel];
self.nameAndDateLabel.textAlignment = NSTextAlignmentLeft;
QBUUser *sender = [ChatService shared].usersAsDictionary[#(message.senderID)];
NSInteger loginForColor = [sender.login integerValue];
loginForColor = loginForColor % 255;
self.nameAndDateLabel.text = [NSString stringWithFormat:#"%#", sender.fullName];
self.backgroundImageView.image = orangeBubble;
[self.backgroundImageView addSubview:cellImage];
[self.contentView addSubview:self.backgroundImageView];
});
} else {
// downloads the image and displays as above
}
}
}
Cells get reused. Therefore you must always set/reset all properties of the cell each time.
For every if statement that sets a cell's property, there must be an else statement that resets the same property - even if it just clears the value.
Also you must avoid adding subviews over and over each time the cell is used. You have code that creates and adds an image view to the cell. But you keep adding new image views over and over. Just add it once if needed. If it's already there, update it with the new image instead of adding a new one.
The error should be on the functions configureCellWithImage and configureCellWithMessage.
I didn't see the code of those functions, but i bet that you didn't clean the image content on the configureCellWithMessage.
Overview
I'm creating a UITableView with custom UITableViewCell (in iOS 8.4,Objective-C). i've created IBoutlets of each and every items in Custom Cell. it seems working well, but randomly my UIButton gets disappeared from custom cell.
here my CellForRowAtIndexPath Code
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
linkCell*cell = (linkCell*)[tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if(!cell){
cell = [[linkCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.contentView.backgroundColor = [UIColor clearColor];
NSDictionary *aDict = [numberOfSections objectAtIndex:indexPath.section];
NSDictionary* info = [[aDict objectForKey:#"Data"]objectAtIndex:indexPath.row];
static float span = 5;
static float dateviewsize = 83;
static float linesize = 1;
static float descriptionsize = 65;
//DAY_NAME
NSString* string = [self getDayNameFromDate:[info valueForKey:#"copied_url_date"]];
cell.lblDayName.text = string;
//DAY_NUMBER
string = [self getDayNumberFromDate:[info valueForKey:#"copied_url_date"]];
cell.lblDayNumber.text = string;
//DAY_TIME
string = [self getTimeFromDate:[info valueForKey:#"copied_url_date"]];
cell.lblDayTime.text = string;
//Link Label
if([[info objectForKey:#"copied_url_title"] isEqualToString:#"nil"]){
string = [NSString stringWithFormat:#"%#",[info valueForKey:#"copied_url"]];
cell.lblLink.font = [UIFont fontWithName:FONT_LIGHT size:14];
cell.lblLink.textColor = [UIColor colorWithRed:51.0/255.0 green:0/255.0 blue:135.0/255.0 alpha:1.0];
}else{
string = [NSString stringWithFormat:#"%#",[info objectForKey:#"copied_url_title"]];
cell.lblLink.font = [UIFont fontWithName:FONT_MEDIUM size:16];
cell.lblLink.textColor = [UIColor darkGrayColor];
}
cell.lblLink.text = string;
float w,h,y;
w = self.view.frame.size.width-(span*2);
CGRect dataviewframe,titleRect,buttonviewrect,imageRect;
CGSize newsize;
[cell.lblDescreption setFont:[UIFont fontWithName:FONT_LIGHT size:16]];
[cell.lblDescreption setNumberOfLines:3];
[cell.linkimage setHidden:NO];
if([AFNetworkReachabilityManager sharedManager].isReachable){
//Unspacified ImageView
if([[info objectForKey:#"copied_url_img"]isEqualToString:#"nil"]){
[cell.linkimage setHidden:YES];//hide image
//make call to get image & title of Copied URL
[self MakeCallAndSetImageToImageView:indexPath ToGetImageFromURL:[info valueForKey:#"copied_url"]];
//new size of link title
y = span+dateviewsize+span+linesize+1;
if([[info objectForKey:#"copied_url_description"] isEqualToString:#"nil"]){
[cell.lblDescreption setHidden:YES];//hide description
//set dataview's new height
h = span+dateviewsize+span;
}
else{
[cell.lblDescreption setHidden:NO];//show description
NSString* string = [NSString stringWithFormat:#"%#",[info objectForKey:#"copied_url_description"]];
[cell.lblDescreption setText:string];
newsize = [self getStringHeightWithMaxWidth:w-(span*2) AndText:cell.lblDescreption];
if(newsize.height > descriptionsize){
titleRect = CGRectMake(span,y,w-(span*2),descriptionsize);
//set dataview's new height
h = y+descriptionsize+span;
}else{
titleRect = CGRectMake(span,y,w-(span*2),newsize.height);
//set dataview's new height
h = y+newsize.height+span;
}
[cell.lblDescreption setFrame:titleRect];
}
dataviewframe = CGRectMake(span,span,w,h);
//set buttonview's new frame
buttonviewrect = CGRectMake(span,h+span+2,w,50);
}else{
[cell.linkimage setHidden:NO];//show image
//new size of link image
y = span+dateviewsize+span+linesize+1;
float imageH = [self SizeWithScaledToWidth:w-(span*2)].height;
imageRect = CGRectMake(span,y,w-(span*2),imageH);
NSString* imgurl=[NSString stringWithFormat:#"%#",[info objectForKey:#"copied_url_img"]];
[cell.linkimage setImageWithURL:[NSURL URLWithString:imgurl]];
[cell.linkimage setFrame:imageRect];
y = y+imageH+span;
//new size of link title
if([[info objectForKey:#"copied_url_description"] isEqualToString:#"nil"]){
[cell.lblDescreption setHidden:YES];
h = y+span;
}else{
[cell.lblDescreption setHidden:NO];//show description
NSString* string = [NSString stringWithFormat:#"%#",[info objectForKey:#"copied_url_description"]];
[cell.lblDescreption setText:string];
newsize = [self getStringHeightWithMaxWidth:w-(span*2) AndText:cell.lblDescreption];
if(newsize.height > descriptionsize){
titleRect = CGRectMake(span,y,w-(span*2),descriptionsize);
//set dataview's new height
h = y+descriptionsize+span;
}else{
titleRect = CGRectMake(span,y,w-(span*2),newsize.height);
//set dataview's new height
h = y+newsize.height+span;
}
[cell.lblDescreption setFrame:titleRect];
}
//set dataview's new frame
dataviewframe = CGRectMake(span,span,w,h);
//set buttonview's new frame
buttonviewrect = CGRectMake(span,h+span+2,w,50);
}
}else{
//NO INTERNET CONNECTION
//hide link image
[cell.linkimage setHidden:YES];
//hide link title
[cell.lblDescreption setHidden:YES];
//set dataview's new frame
h = span+dateviewsize;
dataviewframe = CGRectMake(span,span,w,h);
//set buttonview's new frame
buttonviewrect = CGRectMake(span,h+span+2,w,50);
}
cell.dataview.frame = dataviewframe;
cell.buttonview.frame = buttonviewrect;
if([selectedRow isEqual:indexPath]){
cell.buttonview.alpha=1;
}else{
cell.buttonview.alpha=0;
}
[cell.btnShare setHidden:NO];
[cell.buttonview bringSubviewToFront:cell.btnShare];
[cell.buttonview bringSubviewToFront:cell.btnOpen];
[cell.buttonview bringSubviewToFront:cell.btnCopy];
[cell.buttonview bringSubviewToFront:cell.btnDelete];
[cell.btnShare addTarget:self action:#selector(Action:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnOpen addTarget:self action:#selector(Action:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnCopy addTarget:self action:#selector(Action:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnDelete addTarget:self action:#selector(Action:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnShare setTag:indexPath.row];
[cell.btnOpen setTag:indexPath.row];
[cell.btnCopy setTag:indexPath.row];
[cell.btnDelete setTag:indexPath.row];
return cell;
}
here is my screen shots
Thanks in Advance tell me if you want more info.
You're doing way too much in the -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method. It's good practice to give a custom cell a configuration method, like -(void)configureCell, where the content and lay-out of the cell will be defined. In other words, let the cell be responsible (as much as possible) for its content and lay-out instead of the tableview.
I guess this part causes problems:
if([AFNetworkReachabilityManager sharedManager].isReachable) {
...
}
Especially:
[self MakeCallAndSetImageToImageView:indexPath ToGetImageFromURL:[info valueForKey:#"copied_url"]];
I don't know the implementation of this method, but I have the feeling you have to look over there, as it can be a threading issue at retrieving the image you requested.
One more tip: the way you name your classes and methods doesn't always follow the Objective-C conventions. Check linkCell (class) and MakeCallAndSetImageToImageView ... (method).
Possible layout broken. Try to capture view hierarchy. In Xcode: Debug > View Debugging > Capture View Hierarchy.
Also, method dequeueReusableCellWithIdentifier:forIndexPath: always returns a valid cell. if(!cell){ ... } will never be executed, you can remove it.
Try to use this block of GCD, i think it will work.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Do data fetching and calculation
dispatch_async(dispatch_get_main_queue(), ^(void) {
//Update UI on main thread
});
});
After a long time, i found the mistake in my code. i was setting buttonview tag indexPath.row and also gave same to button tag. and when DidSelectRowAtIndexPath get called, i was doing,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
linkCell*cell = (linkCell*)[tableView cellForRowAtIndexPath:indexPath];
if([selectedRow isEqual:indexPath]){
selectedRow = nil;
//this is where i'm mistaking.
[[cell viewWithTag: indexPath.row]setAlpha:1];
}else{
selectedRow = indexPath;
//this is where i'm mistaking.
[[cell viewWithTag: indexPath.row]setAlpha:0];
}
[tableView reloadData];
}
so, i gave -1 tag to buttonview and the problem is solved.
if([selectedRow isEqual:indexPath]){
selectedRow = nil;
[[cell viewWithTag: -1]setAlpha:1];
}else{
selectedRow = indexPath;
[[cell viewWithTag: -1]setAlpha:0];
}
by the way thanks for your valuable Tips and Advises.
In my iOS app, I have a UICollectionView where each cell contains an image. To prevent the view from taking a long time to load, I load each with a blank image and title before loading the image contents in a background task.
I logged which images are getting loaded through in the background async task, and it seems like the images of cells off screen get loaded first, followed by the cells at the top of the screen. This makes the app seem unresponsive, and I'd rather have the cells at the top take priority in terms of loading:
I also notice that once I start scrolling, the images in the cells suddenly start appearing, but they take much longer to appear on their own. Can anyone suggest strategies to control the ordering that UICollectionCells load in?
Here is my code:
Iterate over projects and add imageViews to an NSMutableArray projectContainers, which then gets turned into cells
for (NSDictionary *currentProject in projects)
{
// data entry
[projectIDs addObject: [currentProject objectForKey:#"id"]];
NSString *projectTitle = [currentProject objectForKey:#"title"];
id delegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = [delegate managedObjectContext];
CustomLabel *cellLabel=[[CustomLabel alloc]init];
cellLabel.text = trimmedProjectTitle;
[titles addObject:projectTitle];
CGSize maxLabelSize = CGSizeMake(cellWidth,100);
CustomLabel *titleLabel = [[CustomLabel alloc]init];
// titleLabel styling
titleLabel.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.5f];
titleLabel.textColor =[UIColor whiteColor];
[titleLabel setFont: [UIFont fontWithName: #"HelveticaNeue" size:12]];
titleLabel.text = trimmedProjectTitle;
CGSize expectedLabelSize = [titleLabel.text sizeWithFont:titleLabel.font constrainedToSize:maxLabelSize lineBreakMode:NSLineBreakByWordWrapping];
CGRect labelFrame = (CGRectMake(0, 0, cellWidth, 0));
labelFrame.origin.x = 0;
labelFrame.origin.y = screenWidth/2 - 80 - expectedLabelSize.height;
labelFrame.size.height = expectedLabelSize.height+10;
titleLabel.frame = labelFrame;
// add placeholder image with textlabel
UIImageView *imagePreview = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, cellWidth, cellHeight)];
imagePreview.contentMode= UIViewContentModeScaleAspectFill;
imagePreview.clipsToBounds = YES;
[imagePreview setImage:[UIImage imageNamed:#"blank.png"]];
[imagePreview addSubview:titleLabel];
[imagePreview.subviews[0] setClipsToBounds:YES];
[projectContainers addObject: imagePreview];
// add project thumbnail images in async
dispatch_async(bgQueue, ^{
NSDictionary *imagePath = [currentProject objectForKey:#"image_path"];
NSString *imageUrlString = [imagePath objectForKey: #"preview"];
NSURL *imageUrl = [NSURL URLWithString: imageUrlString];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:(imageUrl)];
UIImage *image = [[UIImage alloc] initWithData:(imageData)];
if(image){
NSLog(#"project with image: %#", projectTitle);
[imagePreview setImage: image];
}
BOOL *builtVal = [[currentProject objectForKey:#"built"]boolValue];
if(builtVal){
UIImageView *builtBanner =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"built_icon.png"]];
builtBanner.frame = CGRectMake(screenWidth/2 -80, 0, 50, 50);
[imagePreview addSubview: builtBanner];
}
});
}
renders cells using the NSMutableArray projectContainers:
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// NSLog(#"cellForItemAtIndexPath");
static NSString *identifier = #"NewCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
if(!reloadProjects){
UIImageView *preview = (UIImageView*) [cell.contentView viewWithTag:[[projectIDs objectAtIndex:indexPath.row]intValue]];
UIImageView *previewContent = [projectContainers objectAtIndex:indexPath.row];
// NSLog(#"fetching image tag %d", [[projectIDs objectAtIndex:indexPath.row]intValue]);
if (!preview)
{
previewContent.tag = [[projectIDs objectAtIndex:indexPath.row]intValue];
// NSLog(#"creating previewContent %li", (long) previewContent.tag);
[cell addSubview: previewContent];
}
[self.collectionView setBackgroundColor:collectionGrey];
cell.contentView.layer.backgroundColor = [UIColor whiteColor].CGColor;
return cell;
}
return cell;
}
EDIT: Working Solution
Thanks to rob mayoff for helping me come out with a solution. This is what I ended up doing, which loads the images much faster:
// add project thumbnail images in async
dispatch_async(imageQueue, ^{
NSDictionary *imagePath = [currentProject objectForKey:#"image_path"];
NSString *imageUrlString = [imagePath objectForKey: #"preview"];
NSURL *imageUrl = [NSURL URLWithString: imageUrlString];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:(imageUrl)];
UIImage *image = [[UIImage alloc] initWithData:(imageData)];
if(image){
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"project with image: %#", projectTitle);
[imagePreview setImage: image];
});
}
BOOL *builtVal = [[currentProject objectForKey:#"built"]boolValue];
if(builtVal){
UIImageView *builtBanner =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"built_icon.png"]];
builtBanner.frame = CGRectMake(screenWidth/2 -80, 0, 50, 50);
dispatch_async(dispatch_get_main_queue(), ^{
[imagePreview addSubview: builtBanner];
});
}
});
There are several things that code be improved in your code, but your chief complaint (“once I start scrolling, the images in the cells suddenly start appearing, but they take much longer to appear on their own”) is because you violated the commandment:
Thou shalt only access
thy view hierarchy
from the main thread.
Look at your code:
dispatch_async(bgQueue, ^{
...
[imagePreview addSubview: builtBanner];
You're manipulating the view hierarchy from a background thread. This is not allowed. For example, see the note at the bottom of this page, or the “Threading Considerations” in the UIView Class Reference.
You need to dispatch back to the main thread to update the view hierarchy.
Watch the Session 211 - Building Concurrent User Interfaces on iOS video from WWDC 2012. It talks in depth about how to do what you're trying to do, efficiently. See also this answer.
I have a table view and when it scrolls the cell title text overlap each other.
I'm I setting up the cellForIndexPath: incorrectly?
here's my cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath{
BOOL isLandscape = YES;
if (nextOrientation == UIInterfaceOrientationPortrait || nextOrientation == UIInterfaceOrientationPortraitUpsideDown) {
isLandscape = NO;
}
UIImageView* bgImage;
UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:(isLandscape) ? #"landscape-cell":#"portrait-cell"];
if (cell == nil){
// cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:(isLandscape) ? #"landscape-cell":#"portrait-cell"] autorelease];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:(isLandscape) ? #"landscape-cell":#"portrait-cell"] autorelease];
if (isLandscape) {
bgImage = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 480, 125)] autorelease];
[bgImage setTag:BACK_IMAGE];
//
[cell addSubview:bgImage];
}else {
bgImage = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 125)] autorelease];
[bgImage setTag:BACK_IMAGE];
[cell addSubview:bgImage];
}
}else {
bgImage = (UIImageView*)[cell viewWithTag:BACK_IMAGE];
}
for (UIView* v in cell.subviews) {
if ([v isKindOfClass:[CatalogeView class]]) {
[v removeFromSuperview];
}
}
if (isLandscape) {
if (IPADAPP) {
[bgImage setFrame:CGRectMake(0, 0, 1024, 250)];
[bgImage setImage:[ImgUtil image:#"polka_gor#2x.png"]];
int num = 0;
for(int i = indexPath.row*CATALOGE_ON_SHELF_HORIZONTAL; i < [cataloges count] && i < (indexPath.row + 1)*CATALOGE_ON_SHELF_HORIZONTAL; i++){
CatalogeView* catalogeView = [cataloges objectAtIndex:i];
[catalogeView setPosition:CGPointMake(40 + 120*(num%CATALOGE_ON_SHELF_HORIZONTAL) * 2 , 30)];
[cell addSubview:catalogeView];
num++;
}
}else{
[bgImage setFrame:CGRectMake(0, 0, 480, 125)];
[bgImage setImage:[ImgUtil image:#"polka_gor.png"]];
int num = 0;
for(int i = indexPath.row*CATALOGE_ON_SHELF_HORIZONTAL; i < [cataloges count] && i < (indexPath.row + 1)*CATALOGE_ON_SHELF_HORIZONTAL; i++){
CatalogeView* catalogeView = [cataloges objectAtIndex:i];
[catalogeView setPosition:CGPointMake(20 + 120*(num%CATALOGE_ON_SHELF_HORIZONTAL),15)];
[cell addSubview:catalogeView];
num++;
}
}
}else {
if (IPADAPP) {
[bgImage setFrame:CGRectMake(0, 0, 768, 250)];
[bgImage setImage:[ImgUtil image:#"polka#2x.png"]];
int num = 0;
for(int i = indexPath.row*CATALOGE_ON_SHELF_VERTICAL; i < [cataloges count] && i < (indexPath.row + 1)*CATALOGE_ON_SHELF_VERTICAL; i++){
CatalogeView* catalogeView = [cataloges objectAtIndex:i];
[catalogeView setPosition:CGPointMake(20 + 105*(num%CATALOGE_ON_SHELF_VERTICAL) * 2.5 ,30)];
[cell addSubview:catalogeView];
num++;
}
}else{
[bgImage setFrame:CGRectMake(0, 0, 320, 125)];
[bgImage setImage:[ImgUtil image:#"polka.png"]];
int num = 0;
for(int i = indexPath.row*CATALOGE_ON_SHELF_VERTICAL; i < [cataloges count] && i < (indexPath.row + 1)*CATALOGE_ON_SHELF_VERTICAL; i++){
CatalogeView* catalogeView = [cataloges objectAtIndex:i];
[catalogeView setPosition:CGPointMake(10 + 105*(num%CATALOGE_ON_SHELF_VERTICAL),15)];
[cell addSubview:catalogeView];
num++;
}
}
}
return cell;
}
and the Catalogue View class:
#implementation CatalogeView
#synthesize delegate;
#synthesize cataloge;
- (void)dealloc {
[cataloge release];
[image release];
[title release];
[button release];
[super dealloc];
}
+(id) make{
NSInteger koef = 1;
if (IPADAPP) {
koef = 2;
}
CatalogeView* ctrl = [[[CatalogeView alloc] initWithFrame:CGRectMake(0, 0, FULL_VIEW_WIDTH * koef, FULL_VIEW_HEIGTH * koef)] autorelease];
[ctrl addAllSubviews];
return ctrl;
}
-(void) addAllSubviews{
NSInteger koef = 1;
if (IPADAPP) {
koef = 2;
}
if (!title) {
title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, FULL_VIEW_WIDTH * koef, TITLE_HEIGTH * koef)];
[title setNumberOfLines:2];
[title setTextColor:[UIColor whiteColor]];
[title setFont:[UIFont fontWithName:#"Helvetica" size:9 * koef]];
[title setTextAlignment:UITextAlignmentCenter];
[title setBackgroundColor:[UIColor clearColor]];
[self addSubview:title];
}
if (!image) {
image = [[UIImageView alloc] initWithFrame:CGRectMake(0, TITLE_HEIGTH * koef, FULL_VIEW_WIDTH * koef, IMAGE_HEIGTH * koef)];
[image setBackgroundColor:[UIColor clearColor]];
[self addSubview:image ];
}
if (!button) {
button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, FULL_VIEW_WIDTH * koef, FULL_VIEW_HEIGTH * koef)];
[button addTarget:self action:#selector(click) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button ];
}
}
-(void) addCatalogeInView:(CatalogeDbo*) newCataloge{
self.cataloge = newCataloge;
[title setText:cataloge.realName];
[image setImage:[DownloadImage getImageWithName:[NSString stringWithFormat:#"%#.png", cataloge.image]]];
}
-(void) setPosition:(CGPoint) position{
NSInteger koef = 1;
if (IPADAPP) {
koef = 2;
}
[self setFrame:CGRectMake(position.x, position.y, FULL_VIEW_WIDTH * koef, FULL_VIEW_HEIGTH * koef)];
}
-(void) click{
if(cataloge){
[delegate clGoInCataloge:cataloge];
}
}
#end
Your cell height was not matching with the subviews contentsize you are adding in cellForRowAtIndexPath method.
Also you should use unique Identifier for each row. Otherwise the already created cell with the same Identifier "landscape-cell" was re-used and not created again .
Use the Identifier something like
[NSString stringWithformat: "cell_%d",indexpath.row];
Hope you achieve the target.
Reading all this, my assumption is that you're adding CatalogeView multiple times and this causes the labels, buttons and images to overlap (the last two you just don't see overlapping) everytime a cell is dequeued. Instead, make a function that changes the values for the objects in CatalogeView and set them if it's already been added.
You're creating new ui elements dynamically every time that the cell's will be generated. Why don't you just create a custom cell (or two, landscape and portrait) inside a new nib file. This way you can access the elements you want and the labels won't overlap because you just can set them to the position you want, inside the InterfaceBuilder. And you just would need to call them like :
[cell.label1 setText
[cell.label2 setText....
And keep in mind, adding additional SubViews to UITableViewCells might cause a problem. You should keep the number of subviews as low as possible so the UITableView doesn't get to slow. There is a good explanation in a WWDC Stream:
iOS App Performance: Graphics and Animations
You might be calculating incorrectly your frames. For Landscape or portrait mode
if You are using a custum cell then you have to define height for row,and if you are using addsubview of cell then you have to provide correct positions of all subviews.
Seems that heightForRowAtIndexPath(or xib setting) returns different height than your CatalogueView which causes such overlapping. Also why not use UICollectionView(or PSTCollectionView in case you need to support iOS 5.x)?
! Вовка в Простоквашино и Дюймовочка блудного попугая - можно новые мультфильмы снимать. :)
(Some talking about Russian cartoons caused by overlapping names)
write below if you still face problem
cell=nil; // use this to create new cell
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:
}