iOS how to add UIView to tableview cell effectively - ios

I have a table going where each cell has a UIView in it that is fed from an XMLParser feed. If I leave it how it is, each time I refresh the views build upon each other because they are not getting released/removed, which makes total sense. How would I go about writing my code to avoid that problem, and not having to rebuild the view's each time I refresh. I am stuck in the logic of it and also the actual syntax. Thanks.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
JointCAD *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row];
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"texture.png"]];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UIView *selectionView = [[UIView alloc] initWithFrame:CGRectMake(10, 7, 200, 65)];
[selectionView setBackgroundColor: [UIColor clearColor]];
cell.selectedBackgroundView = selectionView;
}
// Display content in each cell
cellSeparator = [[UIView alloc] initWithFrame:CGRectMake(10, 7, 300, 65)];
[cellSeparator setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleWidth];
[cellSeparator setContentMode:UIViewContentModeTopLeft];
[cellSeparator setBackgroundColor: [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0]];
cellSeparator.layer.borderWidth = 1.0;
cellSeparator.layer.borderColor = [UIColor blackColor].CGColor;
[cell addSubview:cellSeparator];
callTypeLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 2, 190, 21)];
callTypeLabel.text = [currentCall currentCallType];
callTypeLabel.backgroundColor = [UIColor clearColor];
callTypeLabel.font = [UIFont boldSystemFontOfSize:12.0];
[cellSeparator addSubview:callTypeLabel];
locationLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 17 , 190, 15)];
locationLabel.text = [currentCall location];
locationLabel.backgroundColor = [UIColor clearColor];
locationLabel.font = [UIFont systemFontOfSize:10.0];
[cellSeparator addSubview:locationLabel];
unitsLabel = [[UILabel alloc]initWithFrame:CGRectMake(4, 43, 190, 21)];
unitsLabel.text = [currentCall units];
unitsLabel.backgroundColor = [UIColor clearColor];
unitsLabel.font = [UIFont italicSystemFontOfSize:10.0];
[cellSeparator addSubview:unitsLabel];
stationLabel = [[UILabel alloc]initWithFrame:CGRectMake(195 , 25, 75, 20)];
NSString *station = [#"Station: " stringByAppendingString:currentCall.station];
stationLabel.text = station;
stationLabel.backgroundColor = [UIColor clearColor];
stationLabel.font = [UIFont boldSystemFontOfSize:11.0];
[cellSeparator addSubview:stationLabel];
if ([currentCall.county isEqualToString:#"W"]) {
UIImage *countyImage = [UIImage imageNamed:#"blue.png"];
CGRect countyImageFrame = CGRectMake(275, 10, 18, 18);
UIImageView *countyImageLabel = [[UIImageView alloc] initWithFrame:countyImageFrame];
countyImageLabel.image = countyImage;
[cellSeparator addSubview:countyImageLabel];
} else {
UIImage *countyImage = [UIImage imageNamed:#"green.png"];
CGRect countyImageFrame = CGRectMake(275, 10, 18, 18);
UIImageView *countyImageLabel = [[UIImageView alloc] initWithFrame:countyImageFrame];
countyImageLabel.image = countyImage;
[cellSeparator addSubview:countyImageLabel];
}
if ([currentCall.callType isEqualToString:#"F"]) {
UIImage *callTypeImage = [UIImage imageNamed:#"red.png"];
CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
UIImageView *callTypeImageLabel = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageLabel.image = callTypeImage;
[cellSeparator addSubview:callTypeImageLabel];
} else {
UIImage *callTypeImage = [UIImage imageNamed:#"yellow.png"];
CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
UIImageView *callTypeImageLabel = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageLabel.image = callTypeImage;
[cellSeparator addSubview:callTypeImageLabel];
}
return cell;
}

If I understand your question correctly, I think the solution you want is to subclass UITableViewCell, set up your subviews (UIImageViews and all that) and make them properties on your subclass. Then you can
if (!cell.imageView) {
cell.imageView = [[UIImageView alloc] initWithFrame:myFrame];
}
then just set the image. That way you're sure to not stack image views on top of one another and the correct image will get set when the cell is dequeued.
EDIT:
Make a class called MyTableViewCell (or whatever you want to call it but make sure it's a subclass of UITableViewCell)
Add #property (strong, nonatomic) UIImageView *imageView;
Then use MyTableViewCell instead of UITableViewCell in you cellForRowAtIndexPath and you can access the image property of your custom table view cell, check if it exists, if not create it (which is what the above code does) and then set the image. I would give you code but I'm on my phone. Google subclassing UITableviewCell. You should find a ton of examples.

Related

IOS, How to set Auto Layout in your UITableViewCell that contains different Subviews

I have a layout issue, i have a UIView that contains an UIImageView and three other UILabels. The part that needs to set the layout dynamically is the main UIView thats added to the cell and a UILabel that will contain text of any length lets say for this example.
What i have done i created a custom UITableViewCell and added the SubViews to the custom UITableViewCell, like here:
-(void)setupView:(PostInfo*)postInfo{
CGRect screenRect = [[UIScreen mainScreen] bounds];
viewPostMessage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, screenRect.size.width - 20, 100)];
viewPostMessage.backgroundColor = [UIColor colorWithRed:193.0f/255 green:193.0f/255 blue:193.0f/255 alpha:1.0f];
viewPostMessage.layer.borderColor = [UIColor blackColor].CGColor;
viewPostMessage.layer.borderWidth = 0.5f;
if(postInfo.userImage.length > 0){
userImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
UIImage *imageUser = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:#"http://www.hugt.co.uk/userimage/%d/userImage.jpg", postInfo.userId]]]];
userImage.image = imageUser;
[viewPostMessage addSubview:userImage];
}else{
UIView *viewImage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
viewImage.backgroundColor = [UIColor colorWithRed:132.0f/255 green:132.0f/255 blue:132.0f/255 alpha:1.0f];
[viewPostMessage addSubview:viewImage];
userImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
UIImage *imageUser = [UIImage imageNamed:#"defaultuser.jpg"];
userImage.image = imageUser;
[viewImage addSubview:userImage];
}
labelUserName = [[UILabel alloc] initWithFrame:CGRectMake(50, 8, 200, 16)];
labelUserName.textColor = [UIColor colorWithRed:56.0f/255 green:56.0f/255 blue:57.0f/255 alpha:1.0f];
labelUserName.text = [NSString stringWithFormat:#"%# %# posted...", postInfo.firstName,postInfo.lastName];
//labelFirstName.textAlignment = NSTextAlignmentCenter;
labelUserName.font = [UIFont fontWithName:#"Helvetica" size:12];
labelUserName.userInteractionEnabled = YES;
[viewPostMessage addSubview:labelUserName];
labelCreated = [[UILabel alloc] initWithFrame:CGRectMake(50, 24, 200, 16)];
labelCreated.textColor = [UIColor colorWithRed:86.0f/255 green:152.0f/255 blue:179.0f/255 alpha:1.0f];
labelCreated.text = [NSDateFormatter localizedStringFromDate:postInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:#"AM" withString:#""];
labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:#"PM" withString:#""];
//labelFirstName.textAlignment = NSTextAlignmentCenter;
labelCreated.font = [UIFont fontWithName:#"Helvetica" size:12];
labelCreated.userInteractionEnabled = YES;
[viewPostMessage addSubview:labelCreated];
labelMessage = [[UILabel alloc] initWithFrame:CGRectMake(50, 43, 210, 50)];
labelMessage.textColor = [UIColor colorWithRed:141.0f/255 green:142.0f/255 blue:142.0f/255 alpha:1.0f];
labelMessage.text = postInfo.message;
labelMessage.numberOfLines = 3;
//labelFirstName.textAlignment = NSTextAlignmentCenter;
labelMessage.font = [UIFont fontWithName:#"Helvetica" size:12];
labelMessage.userInteractionEnabled = YES;
[labelMessage sizeToFit];
[viewPostMessage addSubview:labelMessage];
[self.contentView addSubview:viewPostMessage];
}
When i create this custom UITableViewCell i pass in an object that sets the text on the UILabels, like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cell";
if(tableViewThreads == tableView){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
ThreadInfo *threadInfo = (ThreadInfo*)[self.threadsArray objectAtIndex:indexPath.row];
[cell.contentView addSubview:[self setupThreadItem:threadInfo]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
if(tableViewPosts == tableView){
PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
PostInfo *postInfo = (PostInfo*)[self.postsArray objectAtIndex:indexPath.row];
[cell setupView:postInfo];
//[cell addSubview:[self setupPostItem:postInfo]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
//[cell.contentView addSubview:[self setupThreadItem:threadInfo]];
}
return nil;
}
I have searched the web and also here to find out how to Auto Layout the Subviews in the cell but can't seem to understand what needs to go next. I read that you need a Prototype Cell so i created a custom UITableViewCell and thats how far I've got.
Any help would be appreciated, thanks.
So far i have got the cells to resize with Auto Layout but i have removed the UIView that sits inside the cell, so now i have three UILabels and an UIImageView which are the UIImageView (userImage), UILabel (labelUsername), UILabel (labelCreated) and UILabel (labelMessage). So the dimensions and coordinates are the same just that the UIView has been removed:
First i set up NSLayoutContsraints in my Custom Cell, code bellow:
Set numberOFLines = 0 and remove sizeToFit on the UILabel thats going to AutoLayout.
-(void)setupView:(PostInfo*)postInfo{
CGRect screenRect = [[UIScreen mainScreen] bounds];
viewPostMessage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, screenRect.size.width - 20, 100)];
viewPostMessage.backgroundColor = [UIColor colorWithRed:193.0f/255 green:193.0f/255 blue:193.0f/255 alpha:1.0f];
viewPostMessage.layer.borderColor = [UIColor blackColor].CGColor;
viewPostMessage.layer.borderWidth = 0.5f;
if(postInfo.userImage.length > 0){
userImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
UIImage *imageUser = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:#"http://www.hugt.co.uk/userimage/%d/userImage.jpg", postInfo.userId]]]];
userImage.image = imageUser;
[self.contentView addSubview:userImage];
}else{
UIView *viewImage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
viewImage.backgroundColor = [UIColor colorWithRed:132.0f/255 green:132.0f/255 blue:132.0f/255 alpha:1.0f];
[self.contentView addSubview:viewImage];
userImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
UIImage *imageUser = [UIImage imageNamed:#"defaultuser.jpg"];
userImage.image = imageUser;
[viewImage addSubview:userImage];
}
labelUserName = [[UILabel alloc] initWithFrame:CGRectMake(50, 8, 200, 16)];
labelUserName.textColor = [UIColor colorWithRed:56.0f/255 green:56.0f/255 blue:57.0f/255 alpha:1.0f];
labelUserName.text = [NSString stringWithFormat:#"%# %# posted...", postInfo.firstName,postInfo.lastName];
//labelFirstName.textAlignment = NSTextAlignmentCenter;
labelUserName.font = [UIFont fontWithName:#"Helvetica" size:12];
labelUserName.userInteractionEnabled = YES;
[self.contentView addSubview:labelUserName];
labelCreated = [[UILabel alloc] initWithFrame:CGRectMake(50, 24, 200, 16)];
labelCreated.textColor = [UIColor colorWithRed:86.0f/255 green:152.0f/255 blue:179.0f/255 alpha:1.0f];
labelCreated.text = [NSDateFormatter localizedStringFromDate:postInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:#"AM" withString:#""];
labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:#"PM" withString:#""];
//labelFirstName.textAlignment = NSTextAlignmentCenter;
labelCreated.font = [UIFont fontWithName:#"Helvetica" size:12];
labelCreated.userInteractionEnabled = YES;
[self.contentView addSubview:labelCreated];
labelMessage = [[UILabel alloc] initWithFrame:CGRectMake(50, 43, 210, 50)];
labelMessage.textColor = [UIColor colorWithRed:141.0f/255 green:142.0f/255 blue:142.0f/255 alpha:1.0f];
labelMessage.text = postInfo.message;
labelMessage.numberOfLines = 0;
//labelFirstName.textAlignment = NSTextAlignmentCenter;
labelMessage.font = [UIFont fontWithName:#"Helvetica" size:12];
labelMessage.userInteractionEnabled = YES;
labelMessage.lineBreakMode = NSLineBreakByWordWrapping;
//[labelMessage sizeToFit];
[self.contentView addSubview:labelMessage];
labelMessage.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-10-[bodyLabel]-19-|" options:0 metrics:nil views:#{ #"bodyLabel": labelMessage }]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-43-[bodyLabel]-6-|" options:0 metrics:nil views:#{ #"bodyLabel": labelMessage }]];
//[self.contentView addSubview:viewPostMessage];
}
Then in my ViewController that contains the UITableVIew, i modified this bit of code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"cell";
if(tableViewThreads == tableView){
return 122;
}
if(tableViewPosts == tableView){
PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
PostInfo *postInfo = (PostInfo*)[self.postsArray objectAtIndex:indexPath.row];
[cell setupView:postInfo];
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGFloat h = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return h + 1;
}
return 0;
}
The Cells do now resize and the UILabel resizes automatically now but my other problem is that the UITableView scroll is not smooth so ill have to fix that, and when i scroll in the UITableView the Cell data from the UILabel (labelMessage) seems to print it self in other cells, don't know why this is
BUT the Cells resize and the other issues ill ask another question on here.
Sorry forgot to add this bit of code that sits in the PostTableViewCell:
- (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.
labelMessage.preferredMaxLayoutWidth = CGRectGetWidth(labelMessage.frame);
}

Adjusting Cell fields - Objective C

I have a dynamically set table view controller that is used to populate a news type feed. I am having trouble connecting one class to the other for setting the text, image, etc... of that current cell.
Here is the gist:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"timelineCell";
FBGTimelineCell *cell = (FBGTimelineCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.text = [self.googlePlacesArrayFromAFNetworking[indexPath.row] objectForKey:#"message"]; <!-- here is where I want to for example, set the title to the message within this array.
if (!cell)
{
cell = [[FBGTimelineCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell initTimelineCell];
}
UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:#"%d.jpg", indexPath.row]];
cell.photoView.image = img;
return cell;
}
Here is the FBH... init function:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
cellContentView = [[UIView alloc] initWithFrame:CGRectMake(10, 5, 300, 440)];
cellContentView.backgroundColor = [UIColor whiteColor];
photoView = [[FBGTimelinePhotoView alloc] initWithFrame:CGRectMake(5, 102, 310, 310)];
photoView.backgroundColor = [UIColor darkGrayColor];
[photoView setUserInteractionEnabled:YES];
UIView *profilePic = [[UIView alloc] initWithFrame:CGRectMake(9, 9, 30, 30)];
profilePic.backgroundColor = [UIColor darkGrayColor];
UILabel *usernameLabel = [[UILabel alloc] initWithFrame:CGRectMake(45, 9, 222, 18)];
usernameLabel.font = [UIFont systemFontOfSize:14.0];
usernameLabel.text = #"Username";
UILabel *timestampLabel = [[UILabel alloc] initWithFrame:CGRectMake(45, 25, 222, 17)];
timestampLabel.font = [UIFont systemFontOfSize:12.0];
timestampLabel.text = #"3 hours ago";
timestampLabel.textColor = [UIColor lightGrayColor];
UILabel *statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(9, 50, 283, 41)];
statusLabel.font = [UIFont systemFontOfSize:15.0];
statusLabel.text = #"Status..status..status..status..status..status..status..status..status..status..status..status..status..status..status..";
statusLabel.numberOfLines = 2;
statusLabel.lineBreakMode = NSLineBreakByWordWrapping;
UILabel *likeLabel = [[UILabel alloc] initWithFrame:CGRectMake(9, 413, 32, 21)];
likeLabel.font = [UIFont systemFontOfSize:13.0];
likeLabel.text = #"Like";
UILabel *commentLabel = [[UILabel alloc] initWithFrame:CGRectMake(113, 413, 74, 21)];
commentLabel.font = [UIFont systemFontOfSize:13.0];
commentLabel.text = #"Comment";
UILabel *shareLabel = [[UILabel alloc] initWithFrame:CGRectMake(246, 413, 46, 21)];
shareLabel.font = [UIFont systemFontOfSize:13.0];
shareLabel.text = #"Share";
[self addSubview:cellContentView];
[self addSubview:photoView];
[cellContentView addSubview:profilePic];
[cellContentView addSubview:usernameLabel];
[cellContentView addSubview:timestampLabel];
[cellContentView addSubview:statusLabel];
[cellContentView addSubview:likeLabel];
[cellContentView addSubview:commentLabel];
[cellContentView addSubview:shareLabel];
}
return self;
}
So I need to be able to set the cell text and different views within the cell within the cellForRowAtIndexPath if possible for each cell that is set up in the FB..init function.
Suggestions, thoughts?
You should create properties (in the FBGTimelineCell class) for each of the UI elements that you need to access in cellFroRowAtIndexPath, then you can access them with cell.propertyName.
You can create properties for all the dynamic values which are expected to be changed with each cell. Those properties you can set in your cellForRowAtIndexPath method.
eg. cell.statusText = [NSString stringWithFormat:#"%# is rocking!!", indexPath.row];
Public properties like statusText you can add all the UIElements expecting to be dynamically added.
Hope it helps.
Cheers.

Header image not resizable in expandable table

I am pretty new to Xcode and this simple problem has been driving me mad! I have created an expandable table that works fine. This is some of the code on a UIView subclass for the section that expands when you tap on a cell:
- (id)initWithFrame:(CGRect)frame WithTitle: (NSString *) title Section:(NSInteger)sectionNumber delegate: (id <SectionView>) Delegate
{
self = [super initWithFrame:frame];
if (self) {
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(discButtonPressed:)];
[self addGestureRecognizer:tapGesture];
self.userInteractionEnabled = YES;
self.section = sectionNumber;
self.delegate = Delegate;
CGRect LabelFrame = CGRectMake(100, 100, 100, 100);
LabelFrame.size.width -= 100;
CGRectInset(LabelFrame, 1.0, 1.0);
//BUTTON
CGRect buttonFrame = CGRectMake(LabelFrame.size.width, 0, 100, LabelFrame.size.height);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = buttonFrame;
//[button setImage:[UIImage imageNamed:#"carat.png"] forState:UIControlStateNormal];
//[button setImage:[UIImage imageNamed:#"carat-open.png"] forState:UIControlStateSelected];
[button addTarget:self action:#selector(discButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
self.discButton = button;
//My IMAGE
NSString *imageName = #"gradient1.png";
UIImage *myImage = [UIImage imageNamed:imageName];
UIImageView *sectionHeaderView = [[UIImageView alloc] initWithImage:myImage];
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
imageView.frame = CGRectMake(20,50,100,100);
[self addSubview:sectionHeaderView];
self.headerBG = sectionHeaderView;
//HEADER LABEL
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(22, 12, sectionHeaderView.frame.size.width, 35.0)];
label.textAlignment = NSTextAlignmentLeft;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.shadowColor = [UIColor darkGrayColor];
label.shadowOffset = CGSizeMake(0.0, -1.0);
label.text = title;
label.font = [UIFont fontWithName:#"AvenirNext-Bold" size:20.0];
sectionHeaderView.backgroundColor = [UIColor clearColor];
//label.textAlignment = UITextAlignmentLeft;
[self addSubview:label];
self.sectionTitle = label;
}
return self;
}
I have a custom image on the cell #"gradient1.png" but I don't seem to be able to resize it? Here is the header code in the UITableViewController:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection: (NSInteger)section
{
SectionInfo *array = [self.sectionInfoArray objectAtIndex:section];
if (!array.sectionView)
{
NSString *title = array.category.name;
array.sectionView = [[SectionView alloc] initWithFrame:CGRectMake(0, 10, self.tableView.bounds.size.width, 0) WithTitle:title Section:section delegate:self];
}
return array.sectionView;
}
Sorry if this is a trivial question, your help is greatly appreciated!
I don't see where you are trying to resize the image so I can't offer any help in why it is not resizing, but I found this confusing:
//My IMAGE
NSString *imageName = #"gradient1.png";
UIImage *myImage = [UIImage imageNamed:imageName];
UIImageView *sectionHeaderView = [[UIImageView alloc] initWithImage:myImage];
UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
imageView.frame = CGRectMake(20,50,100,100);
[self addSubview:sectionHeaderView];
self.headerBG = sectionHeaderView;
In this part of code you create two imageviews, then you resize one and add the other to the cell (I'm assuming cell) subviews. Is it possible that you are trying to resize the view that you never added as a subview of the cell?
Also, resizing should happen inside - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.
Make sure that you are resizing the proper view, ten make sure you are resizing it in the proper place.

iOS tableview section header won't stay on top of view

As the title implies, the section header I have in my table, when scrolling won't stay on top. It was working before but for some reason, it stopped. I can't figure out why for the life of me. Any help would be awesome. thanks.
Code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [xmlParser.calls count] * 2 + 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return headerHeight;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2 == 0)
return 7;
return 65;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 20)];
headerView.backgroundColor = [UIColor colorWithRed:(51/255.0) green:(54/255.0) blue:(57/255.0) alpha:1.0];
CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0.0f, 44.0f, self.tableView.bounds.size.width, 1.0f);
bottomBorder.backgroundColor = [UIColor colorWithRed:(130/255.0) green:(130/255.0) blue:(130/255.0) alpha:1.0].CGColor;
[headerView.layer addSublayer:bottomBorder];
CALayer *topBorder = [CALayer layer];
topBorder.frame = CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 1.0f);
topBorder.backgroundColor = [UIColor colorWithRed:(130/255.0) green:(130/255.0) blue:(130/255.0) alpha:1.0].CGColor;
[headerView.layer addSublayer:topBorder];
CALayer *imageBorder = [CALayer layer];
imageBorder.frame = CGRectMake(0.0f, 45, self.tableView.bounds.size.width, 7);
imageBorder.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"texture3.png"]].CGColor;
[headerView.layer addSublayer:imageBorder];
UILabel *countyLabel = [[UILabel alloc] initWithFrame:CGRectMake(136, 0, 75, 20)];
countyLabel.text = #"LEGEND";
countyLabel.backgroundColor = [UIColor clearColor];
countyLabel.font = [UIFont boldSystemFontOfSize:11];
countyLabel.textColor = [UIColor whiteColor];
[headerView addSubview:countyLabel];
UILabel *county = [[UILabel alloc] initWithFrame:CGRectMake(37, 20, 75, 20)];
county.text = #"WA. COUNTY";
county.backgroundColor = [UIColor clearColor];
county.font = [UIFont systemFontOfSize:10];
county.textColor = [UIColor whiteColor];
[headerView addSubview:county];
UIImageView *waCountyImage = [[UIImageView alloc] initWithFrame:CGRectMake(15, 20, 18, 18)];
waCountyImage.image = [UIImage imageNamed:#"blue.png"];
[headerView addSubview:waCountyImage];
UILabel *county1 = [[UILabel alloc] initWithFrame:CGRectMake(128, 20, 75, 20)];
county1.text = #"CLA. COUNTY";
county1.backgroundColor = [UIColor clearColor];
county1.font = [UIFont systemFontOfSize:10];
county1.textColor = [UIColor whiteColor];
[headerView addSubview:county1];
UIImageView *caCountyImage = [[UIImageView alloc] initWithFrame:CGRectMake(107, 20, 18, 18)];
caCountyImage.image = [UIImage imageNamed:#"green.png"];
[headerView addSubview:caCountyImage];
UILabel *callType = [[UILabel alloc] initWithFrame:CGRectMake(227, 20, 75, 20)];
callType.text = #"FIRE";
callType.backgroundColor = [UIColor clearColor];
callType.font = [UIFont systemFontOfSize:10];
callType.textColor = [UIColor whiteColor];
[headerView addSubview:callType];
UIImageView *fireImage = [[UIImageView alloc] initWithFrame:CGRectMake(205, 20, 18, 18)];
fireImage.image = [UIImage imageNamed:#"red.png"];
[headerView addSubview:fireImage];
UILabel *callType1 = [[UILabel alloc] initWithFrame:CGRectMake(280, 20, 75, 20)];
callType1.text = #"EMS";
callType1.backgroundColor = [UIColor clearColor];
callType1.font = [UIFont systemFontOfSize:10];
callType1.textColor = [UIColor whiteColor];
[headerView addSubview:callType1];
UIImageView *emsImage = [[UIImageView alloc] initWithFrame:CGRectMake(258, 20, 18, 18)];
emsImage.image = [UIImage imageNamed:#"yellow.png"];
[headerView addSubview:emsImage];
return headerView;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellidentifier1 = #"cell1";
static NSString *cellidentifier2 = #"cell2";
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"texture3.png"]];
self.tableView.separatorColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"texture3.png"]];
if (indexPath.row % 2 == 0)
{
UITableViewCell * cell2 = [tableView dequeueReusableCellWithIdentifier:cellidentifier2];
if (cell2 == nil)
{
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier2];
[cell2.contentView setAlpha:0];
[cell2 setUserInteractionEnabled:NO];
[cell2 setBackgroundColor:[UIColor clearColor]];
}
return cell2;
}
JointCAD *currentCall = [[xmlParser calls] objectAtIndex:((indexPath.row - 1 ) / 2)];
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellidentifier1];
if (cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier1];
}
cell.callTypeLabel.text = currentCall.currentCallType;
cell.locationLabel.text = currentCall.location;
cell.unitsLabel.text = currentCall.units;
cell.stationLabel.text = [#"Station: " stringByAppendingString:currentCall.station];
if ([currentCall.county isEqualToString:#"W"]) {
cell.countyImageView.image = [UIImage imageNamed:#"blue.png"];
}
else {
cell.countyImageView.image = [UIImage imageNamed:#"green.png"];
}
if ([currentCall.callType isEqualToString:#"F"]) {
cell.callTypeImageView.image = [UIImage imageNamed:#"red.png"];
}
else {
cell.callTypeImageView.image = [UIImage imageNamed:#"yellow.png"];
}
return cell;
}

iOS GCD use for a UITableView

I have a pretty intensive UITableView that needs to be optimized a little. The question is, how to use grand central station to do it effectively. Each cell has a UIView with a couple labels and two images. I have subclassed the TableViewCell and the view's are being reused though it is still a little laggy when the table gets bigger. How would I go about using GCD to optimize the table? OR is there a better way around it? I am not very strong in thread management and looking for some advice.
Here is the code to my tableview:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
JointCAD *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row];
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"texture3.png"]];
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.callTypeLabel.text = currentCall.currentCallType;
cell.locationLabel.text = currentCall.location;
cell.unitsLabel.text = currentCall.units;
cell.stationLabel.text = [#"Station: " stringByAppendingString:currentCall.station];
cell.selectedBackgroundView = cell.selectionView;
if ([currentCall.callType isEqualToString:#"F"]) {
cell.imageType = Fire;
}
else {
cell.imageType = EMS;
}
if ([currentCall.county isEqualToString:#"W"]) {
cell.imageType1 = Washington;
}
else {
cell.imageType1 = Clackamas;
}
return cell;
}
Here is the subclassed tableviewcell:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
callView = [[UIView alloc] initWithFrame:CGRectMake(7.5, 7, 305, 65)];
[callView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleWidth];
[callView setContentMode:UIViewContentModeTopLeft];
[callView setBackgroundColor: [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0]];
callView.layer.borderWidth = 1.0;
callView.layer.borderColor = [UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:1.0].CGColor;
[self.contentView addSubview:callView];
callTypeLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 2, 190, 21)];
callTypeLabel.font = [UIFont boldSystemFontOfSize:12.0];
callTypeLabel.textColor = [UIColor blackColor];
callTypeLabel.backgroundColor = [UIColor clearColor];
callTypeLabel.highlightedTextColor = [UIColor whiteColor];
callTypeLabel.adjustsFontSizeToFitWidth = YES;
[callView addSubview:callTypeLabel];
locationLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 17 , 190, 15)];
locationLabel.font = [UIFont systemFontOfSize:10.0];
locationLabel.textColor = [UIColor blackColor];
locationLabel.backgroundColor = [UIColor clearColor];
locationLabel.highlightedTextColor = [UIColor whiteColor];
locationLabel.adjustsFontSizeToFitWidth = YES;
[callView addSubview:locationLabel];
unitsLabel = [[UILabel alloc]initWithFrame:CGRectMake(4, 43, 190, 21)];
unitsLabel.font = [UIFont systemFontOfSize:10.0];
unitsLabel.textColor = [UIColor blackColor];
unitsLabel.backgroundColor = [UIColor clearColor];
unitsLabel.highlightedTextColor = [UIColor whiteColor];
unitsLabel.adjustsFontSizeToFitWidth = NO;
[callView addSubview:unitsLabel];
stationLabel = [[UILabel alloc]initWithFrame:CGRectMake(195 , 25, 75, 20)];
stationLabel.font = [UIFont systemFontOfSize:12.0];
stationLabel.textColor = [UIColor blackColor];
stationLabel.backgroundColor = [UIColor clearColor];
stationLabel.highlightedTextColor = [UIColor whiteColor];
stationLabel.adjustsFontSizeToFitWidth = YES;
[callView addSubview:stationLabel];
CGRect countyImageFrame = CGRectMake(275, 10, 18, 18);
UIImageView *countyImageView = [[UIImageView alloc] initWithFrame:countyImageFrame];
countyImageView.image = countyImage;
[callView addSubview:countyImageView];
CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageView.image = callTypeImage;
[callView addSubview:callTypeImageView];
selectionView = [[UIView alloc] initWithFrame:CGRectMake(10, 7, 200, 65)];
[selectionView setBackgroundColor: [UIColor clearColor]];
}
return self;
}
- (void)setImageType:(CallType)newImageType {
imageType = newImageType;
if (imageType == Fire) {
CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageView.image = [UIImage imageNamed:#"red.png"];
[callView addSubview:callTypeImageView];
}
else if (imageType == EMS) {
CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageView.image = [UIImage imageNamed:#"yellow.png"];
[callView addSubview:callTypeImageView];
}
}
- (void)setImageType1:(County)newImageType1 {
imageType1 = newImageType1;
if (imageType1 == Washington) {
CGRect callTypeImageFrame = CGRectMake(275, 10, 18, 18);
UIImageView *countyImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
countyImageView.image = [UIImage imageNamed:#"blue.png"];
[callView addSubview:countyImageView];
}
else if (imageType1 == Clackamas) {
CGRect callTypeImageFrame = CGRectMake(275, 10, 18, 18);
UIImageView *countyImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
countyImageView.image = [UIImage imageNamed:#"green.png"];
[callView addSubview:countyImageView];
}
}
This is a little subtle, but the main area your code will hang on is in the setImageType: method.
You're adding a programmatically created Image View into your view hierarchy here:
UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageView.image = [UIImage imageNamed:#"red.png"];
[callView addSubview:callTypeImageView];
But you never actually remove the old image view. A better way to do this might be to cache the created image view in a property of the cell, then when you set the image type, send the message -[UIView removeFromSuperview] to the old image view before creating a new one.
As your code stands now, every time a cell is dequeued, a new image view is added to it, so every time the user scrolls up and down the table view, a new image view is created and added to the cell. It won't take long for there to be dozens of image views in each cell. I suspect this is causing many times more drawRect calls into image views than is actually necessary to achieve your purpose.
A better way of doing this would be to have both types of image views as properties that you create in the cell's init method, which are only configured in the setType methods. That way you only create one image view per type, and simply set configure its image in the appropriate setType method. Doing it this way, do bear in mind that removeFromSuperview will release the imageview, so you'll have to declare it as a strong property (assuming you're using ARC).
I appreciate neither of these solutions has anything to do with Grand Central Dispatch, but hopefully that should solve your problem without using a sledgehammer to crack a nut :).

Resources