iOS switching between UIWebViews causing memory warning - ios

Hi i have created a custom tab bar that hides and shows certain web views depending on which tab your on i'm currently loading all three web views on an operation queue then making them visable and invisable depending on the selected tab. problem is its so slow to load and scroll and i'm getting a recieved memory warning
heres what i have done so far
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *subviews = [cell subviews];
for(UIView *subview in subviews) if([subview tag] == 4) [subview removeFromSuperview];
UIView *loadingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 800)];
UIView *sendingMessage = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
UIActivityIndicatorView *sendingSpinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(25, 15, 50, 50)];
UILabel *sendingLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 65, 100, 20)];
int sendingViewLeft = (loadingView.frame.size.width/2) - (sendingMessage.frame.size.width/2);
int sendingViewTop = 160 - (sendingMessage.frame.size.height/2);
loadingView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
sendingMessage.frame = CGRectMake(sendingViewLeft, sendingViewTop, sendingMessage.frame.size.width, sendingMessage.frame.size.height);
sendingMessage.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
sendingMessage.layer.cornerRadius = 10;
sendingSpinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
sendingLabel.textColor = [UIColor whiteColor];
sendingLabel.backgroundColor = [UIColor clearColor];
sendingLabel.text = #"Loading...";
sendingLabel.textAlignment = UITextAlignmentCenter;
sendingLabel.font = [UIFont boldSystemFontOfSize:12];
sendingLabel.shadowColor = [UIColor blackColor];
sendingLabel.shadowOffset = CGSizeMake(0, -1);
[sendingSpinner startAnimating];
[sendingMessage addSubview:sendingLabel];
[sendingMessage addSubview:sendingSpinner];
[loadingView addSubview:sendingMessage];
[loadingView setTag:4];
cell.textLabel.text = #"";
if([self.webViewStatus isEqualToString:#"FALSE"]){
[cell addSubview:loadingView];
self.tableView.userInteractionEnabled = NO;
} else {
[cell addSubview:self.fixturesWebView];
[cell addSubview:self.resultsWebView];
[cell addSubview:self.tablesWebView];
self.tableView.userInteractionEnabled = YES;
}
if(self.selectedTabNumber == 1){
self.fixturesWebView.alpha = 1;
self.resultsWebView.alpha = 0;
self.tablesWebView.alpha = 0;
}
if(self.selectedTabNumber == 2){
self.fixturesWebView.alpha = 0;
self.resultsWebView.alpha = 1;
self.tablesWebView.alpha = 0;
}
if(self.selectedTabNumber == 3){
self.fixturesWebView.alpha = 0;
self.resultsWebView.alpha = 0;
self.tablesWebView.alpha = 1;
}
return cell;
}

First off, you should consider creating a custom cell rather than creating it at the tableview datasource. Second, when you are getting the webview content, consider using Asynchronous calls to avoid lock ups. This could be done in a block too. If you write delegate methods on the custom cell, you can let the tableview know when things are loaded or not etc.
But it looks like you are making it do too much work when the tableview needs to draw a cell.

Related

uitableviewcell disappears after rotating iOS device

I am facing problem for UITableViewCell
What I am doing,
Having three table views on 3 different views of same view controller of iPad.
Among which,
on 1st tableview I have cell with content view button and text.
Text+button is showing well when the app loads first time.
But as soon as I rotate the device the button+text disappears.
What I am doing wrong.
Thanks in advance.
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
if (tableView.tag == 1005)
{
if (indexPath.row == 0)
{
circle = [CAShapeLayer layer];
// Make a circular shape
circularPath=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 35, 35) cornerRadius:MAX(35, 35)];
circle.path = circularPath.CGPath;
// Configure the apperence of the circle
circle.fillColor = [UIColor blackColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 0;
UIButton* cameraBtn = [[UIButton alloc] initWithFrame:CGRectMake(0,0, 35,35)];
cameraBtn.backgroundcolor = [UIColor redColor];
[cell.contentView addSubview: cameraBtn];
cameraBtn.layer.mask=circle;
UILabel *photoLbl = [[UILabel alloc]initWithFrame:CGRectMake(50, 0, 150, 30)];
photoLbl.backgroundColor = [UIColor clearColor];
photoLbl.font = [UIFont fontWithName:#"OpenSans" size:16];
photoLbl.text = #"Take photo";
[cell.contentView addSubview:photoLbl];
[photoLbl release];
[cameraBtn release];
cell.contentView.frame = cell.bounds;
cell.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
return cell;
}
I searched for all links on SO, but didn't get suitable solution.
Try upgrading your simulator , I had the same problem and it worked fine when I tested it in a real device.

UITableViewCell with subviews is not working properly

I have UITableView in my iOS app and I want to add some subviews to cell. I do it by using
[cell.contentView addSubview:someView];
and it works well, but... When I scroll down, subviews are starting to hide from cells that are on top and when I scroll back to top, they wont appear again... What I'm doing wrong? Is there some solution please?
EDIT
Mainly, I'm talking about "detailtext" label, but I have those problems in more cases...
Here is whole code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
switch (indexPath.row) {
case 0:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
break;
default:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
break;
}
UIView *separatorLine = [[UIView alloc] init];
separatorLine.frame = CGRectMake(15.0f, 60 - 0.5f, cell.frame.size.width-15.0f, 0.5f);
separatorLine.tag = 4;
separatorLine.backgroundColor = [UIColor lightGrayColor];
cell.layer.masksToBounds = NO;
tableView.backgroundColor = [UIColor colorWithRed:33.0 / 255.0 green:157.0 / 255.0 blue:147.0 / 255.0 alpha:1.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *row2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
UIView *profileBorder = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-50, 50, 102, 102)];
profileBorder.layer.borderColor = [UIColor whiteColor].CGColor;
profileBorder.layer.borderWidth = 5; //2
profileBorder.layer.cornerRadius = 50;
NZCircularImageView *profileImage = [[NZCircularImageView alloc] initWithFrame:CGRectMake(1,1, 100, 100)];
profileImage.image = profilePhoto;
profileImage.contentMode = UIViewContentModeScaleAspectFill;
UITapGestureRecognizer *showBigProfilePhoto = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showImage:)];
profileImage.userInteractionEnabled = YES;
[profileImage addGestureRecognizer:showBigProfilePhoto];
[profileBorder addSubview:profileImage];
UILabel *numberFeelings = [[UILabel alloc] initWithFrame:CGRectMake(10, 100-25, 100, 50)];
numberFeelings.text = [NSString stringWithFormat:#"%#\nFeelings", feelings];
numberFeelings.font = [UIFont boldSystemFontOfSize:16];
numberFeelings.textAlignment = NSTextAlignmentCenter;
numberFeelings.textColor = [UIColor whiteColor];
numberFeelings.numberOfLines = 0;
UILabel *numberFriends = [[UILabel alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2+60, 100-25, 100, 50)];
numberFriends.text = [NSString stringWithFormat:#"%#\nFollowers", friends];
numberFriends.font = [UIFont boldSystemFontOfSize:16];
numberFriends.textColor = [UIColor whiteColor];
numberFriends.numberOfLines = 0;
numberFriends.textAlignment = NSTextAlignmentCenter;
[row2 addSubview:profileBorder];
[row2 addSubview:numberFriends];
[row2 addSubview:numberFeelings];
int rectButtons = cell.frame.size.width-246;
UIImageView *graph = [[UIImageView alloc] initWithFrame:CGRectMake(rectButtons/2, -20, 82, 82)];
UIImageView *badgets = [[UIImageView alloc] initWithFrame:CGRectMake(rectButtons/2+82, -20, 82, 82)];
UIImageView *photos = [[UIImageView alloc] initWithFrame:CGRectMake(rectButtons/2+164, -20, 82, 82)];
graph.image = [UIImage imageNamed:#"graph.jpg"];
badgets.image = [UIImage imageNamed:#"badgets.jpg"];
photos.image = [UIImage imageNamed:#"photos.jpg"];
graph.userInteractionEnabled = YES;
badgets.userInteractionEnabled = YES;
photos.userInteractionEnabled = YES;
UITapGestureRecognizer *graphTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showGraph:)];
[graph addGestureRecognizer:graphTap];
NSArray *jmenoCasti = [name componentsSeparatedByString:#" "];
krestni = [jmenoCasti objectAtIndex:0];
int indexOfPost = indexPath.row-3;
NSMutableAttributedString *str;
int countFeeling;
int countString;
int countBeforeFeeling;
if (indexPath.row >=3) {
str = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"%# was %#", krestni, [naladyHim objectAtIndex:[[[posts objectAtIndex:indexOfPost] objectForKey:#"_feel"] integerValue]]]];
countFeeling = [[naladyHim objectAtIndex:[[[posts objectAtIndex:indexOfPost] objectForKey:#"_feel"] integerValue]] length];
countString = krestni.length+5+countFeeling;
countBeforeFeeling = countString-countFeeling+1;
int rangeStart = countBeforeFeeling-1;
int rangeStop = str.length-rangeStart;
NSLog(#"%i ... %i", countBeforeFeeling-1, countString-1);
[str addAttribute:NSFontAttributeName value: [UIFont fontWithName:#"Helvetica-Bold" size:16.0f] range:NSMakeRange(rangeStart, rangeStop)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:32.0 / 255.0 green:147.0 / 255.0 blue:138.0 / 255.0 alpha:1.0] range:NSMakeRange(rangeStart, rangeStop)];
}
UILabel *mainText = [[UILabel alloc] initWithFrame:CGRectMake(15, 70, cell.frame.size.width-10, 20)];
mainText.attributedText = str;
UILabel *detailText;
if (!detailText) {
detailText = [[UILabel alloc] initWithFrame:CGRectMake(15, 90, cell.frame.size.width-10, 30)];
}
detailText.textColor = [UIColor grayColor];
detailText.font = [UIFont systemFontOfSize:13];
switch (indexPath.row) {
case 0:
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.text = name;
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont systemFontOfSize:20];
cell.backgroundColor = [UIColor clearColor];
break;
case 1:
[cell.contentView addSubview:row2];
cell.backgroundColor = [UIColor clearColor];
break;
case 2:
cell.backgroundColor = [UIColor colorWithRed:236.0 / 255.0 green:235.0 / 255.0 blue:210.0 / 255.0 alpha:1.0];
[cell.contentView addSubview:graph];
[cell.contentView addSubview:badgets];
[cell.contentView addSubview:photos];
break;
default:
detailText.text = [[posts objectAtIndex:indexPath.row-3] objectForKey:#"_text"];
[cell.contentView addSubview:detailText];
cell.textLabel.attributedText = str;
cell.backgroundColor = [UIColor colorWithRed:236.0 / 255.0 green:235.0 / 255.0 blue:210.0 / 255.0 alpha:1.0];
break;
}
return cell; }
This is an easy way thats works for me:
for(UIView *subview in cell.contentView.subviews)
{
if([subview isKindOfClass: [UIView class]])
{
[subview removeFromSuperview];
}
}
You can use it at the begin of
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
In your tableView:cellForRowAtIndexPath:, you hide the info when you don't want it to be shown, but you don't explicitly unhide it for cells where it should be shown.
Look at the first two lines in that method: What you are - correctly - doing is reusing your cells, so when cells are scrolled out of view, they are removed from the UITableView and put into the reuse queue. Then, when cells should become visible, the TableView gets cells from that queue - or creates new ones if none are available.
This all goes very well, but after a while, cells with hidden info buttons are put on the queue. And then, some time later, those cells are reused - and sometimes for rows in which there should be info visible.
There are two solutions to this: You could either explicitly unhide the information for those rows where you want it to be shown, or you could use two different kinds of cell, one with hidden info, and one with visible info. You then give each of those cells a different identifier, and based on what row the cells are in, set the identifier before dequeuing/creating cells.
You should create a subclass of UITableViewCell for each different cell and add all your view related code that doesn't change depending on the data into an initialization method. Then create a method in each cell called something like configureWithData and pass in the data relevant to the cell. The creation of your attributed string and modification of label frames can occur in this configuration method.
It will dramatically reduce the clutter in your UITableViewController and is much better design wise. There is no real need for your view controller to know what your table cells look like.
Here is an example of what I am talking about:
-(void)awakeFromNib
{
if( self.accessoryType == UITableViewCellAccessoryDisclosureIndicator )
{
DTCustomColoredAccessory *accessory = [DTCustomColoredAccessory accessoryWithColor:[UIColor whiteColor]];
accessory.highlightedColor = [UIColor blackColor];
self.accessoryView = accessory;
}
}
-(void)configureCellWithObject:(id)inObject
{
TableDataModel *dataObject = (TableDataModel *)inObject;
self.titleLabel.text = dataObject.titleString;
self.subtitleLabel.text = dataObject.subtitleString;
self.accessibilityIdentifier = dataObject.accessIdString;
if( dataObject.imageUrlString != nil )
{
UIImage *iconImage = [UIImage imageNamed:dataObject.imageUrlString];
if( iconImage != nil )
{
NSInteger yOffset = [StaticTools centerYOffset:self.frame.size objectFrameSize:iconImage.size];
self.iconImageView.image = iconImage;
CGRect frame = self.iconImageView.frame;
frame.origin.y = yOffset;
frame.size = iconImage.size;
[self.iconImageView setFrame:frame];
}
else
{
[self.iconImageView loadImageFromUrl:dataObject.imageUrlString];
}
}
}

UITableview Cell Height is not calculated properly and cells overlap

I need to create and populate custom cells. These cells height are huge about 300-400.
So I have a populateCellView function , I call that function on heightForRowAtIndexPath to calculate height and in cellForRowAtIndexPath to add that view to cell content view, but somehow sometimes cells overlap.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self populateCellView:indexPath.row].frame.size.height;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIView *populateCell= nil;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
populateCell=[[UIView alloc] initWithFrame:CGRectZero];
[[populateCell layer] setBorderWidth:2.0f];
populateCell= [self populateCellView:indexPath.row];
[[cell contentView] addSubview:populateCell];
}
if (!populateCell){
populateCell = (UIView*)[cell viewWithTag:1];
populateCell= [self populateCellView:indexPath.row];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
populate view function:
-(UIView *)populateCellView:(int)forCase
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width,500)];
[view setBackgroundColor:[UIColor colorWithRed:40/255.0 green:150/255.0 blue:213/255.0 alpha:1.0]];
view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
if ([view subviews]){
for (UIView *subview in [view subviews]) {
[subview removeFromSuperview];
}
}
UILabel *caseNumberLabel;
UILabel *caseNameLabel;
UILabel *caseSummaryLabel;
UILabel *caseAncLabel;
UILabel *caseNumberText;
UILabel *caseNameText;
UILabel *caseSummaryText;
UILabel *caseAncText;
//static label for case number
caseNumberLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,10,250, 50)];
caseNumberLabel.textColor = [UIColor whiteColor];
caseNumberLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:24.0f];
caseNumberLabel.text =#"Case Number:";
caseNumberLabel.backgroundColor = [UIColor clearColor];
caseNumberLabel.numberOfLines=0;
caseNumberLabel.adjustsFontSizeToFitWidth = NO;
caseNumberLabel.tag=forCase;
caseNumberLabel.frame=[self calculateLabelFrame:caseNumberLabel];
//case number from plist
caseNumberText = [[UILabel alloc] initWithFrame:CGRectMake(caseNumberLabel.frame.size.width+50,caseNumberLabel.frame.origin.y,self.view.frame.size.width-caseNumberLabel.frame.size.width-50, 50)];
caseNumberText.textColor = [UIColor whiteColor];
caseNumberText.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:24.0f];
caseNumberText.text =[[self agenda] getCaseNumber:forCase];
caseNumberText.backgroundColor = [UIColor clearColor];
caseNumberText.numberOfLines=0;
caseNumberText.adjustsFontSizeToFitWidth = NO;
caseNumberText.tag=forCase;
//[caseNumberLabel sizeToFit];
caseNumberText.frame=[self calculateLabelFrame:caseNumberText];
//static label for case name
caseNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,caseNumberText.frame.origin.y + caseNumberText.bounds.size.height+5,250, 50)];
caseNameLabel.textColor =[UIColor whiteColor];
caseNameLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:24.0f];
caseNameLabel.text =#"Case Name:";
caseNameLabel.backgroundColor = [UIColor clearColor];
caseNameLabel.numberOfLines=0;
caseNameLabel.adjustsFontSizeToFitWidth = NO;
caseNameLabel.tag=forCase;
//[caseNumberLabel sizeToFit];
caseNameLabel.frame=[self calculateLabelFrame:caseNameLabel];
//case name from plist
caseNameText = [[UILabel alloc] initWithFrame:CGRectMake(caseNameLabel.frame.size.width+50,caseNameLabel.frame.origin.y,self.view.frame.size.width-caseNameLabel.frame.size.width-50, 50)];
caseNameText.textColor = [UIColor whiteColor];
caseNameText.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:24.0f];
caseNameText.text =[[self agenda] getCaseName:forCase];
caseNameText.backgroundColor = [UIColor clearColor];
caseNameText.numberOfLines=0;
//caseNameText.adjustsFontSizeToFitWidth = NO;
caseNameText.tag=forCase;
[caseNameText sizeToFit];
//caseNameText.lineBreakMode = NSLineBreakByWordWrapping;
caseNameText.frame=[self calCellLabelFrame:caseNameText previousLabel:caseNameLabel];
//static label for case summary
caseSummaryLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,caseNameText.frame.origin.y + caseNameText.bounds.size.height+20,250, 50)];
caseSummaryLabel.textColor = [UIColor whiteColor];
caseSummaryLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:24.0f];
caseSummaryLabel.text =#"Case Summary:";
caseSummaryLabel.backgroundColor = [UIColor clearColor];
caseSummaryLabel.numberOfLines=0;
caseSummaryLabel.adjustsFontSizeToFitWidth = NO;
caseSummaryLabel.tag=forCase;
//[caseSummaryLabel sizeToFit];
caseSummaryLabel.frame=[self calculateLabelFrame:caseSummaryLabel];
//case name from plist
caseSummaryText = [[UILabel alloc] initWithFrame:CGRectMake(caseSummaryLabel.frame.size.width+50,caseSummaryLabel.frame.origin.y,self.view.frame.size.width-caseSummaryLabel.frame.size.width-100, 50)];
caseSummaryText.textColor = [UIColor whiteColor];
caseSummaryText.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:24.0f];
caseSummaryText.text =[[self agenda] getCaseSummary:forCase];
caseSummaryText.backgroundColor = [UIColor clearColor];
caseSummaryText.numberOfLines=0;
//caseSummaryText.adjustsFontSizeToFitWidth = NO;
caseSummaryText.tag=forCase;
[caseSummaryText sizeToFit];
//caseSummaryText.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
caseSummaryText.frame=[self calCellLabelFrame:caseSummaryText previousLabel:caseSummaryLabel];
//static label for anc
caseAncLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,caseSummaryText.frame.origin.y + caseSummaryText.bounds.size.height+15,250, 50)];
caseAncLabel.textColor = [UIColor whiteColor];
caseAncLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:24.0f];
caseAncLabel.text =#"ANC:";
caseAncLabel.backgroundColor = [UIColor clearColor];
caseAncLabel.numberOfLines=0;
caseAncLabel.adjustsFontSizeToFitWidth = NO;
caseAncLabel.tag=forCase;
//[ccaseAncLabel sizeToFit];
caseAncLabel.frame=[self calculateLabelFrame:caseAncLabel];
//case name from plist
caseAncText = [[UILabel alloc] initWithFrame:CGRectMake(caseAncLabel.frame.size.width+50,caseAncLabel.frame.origin.y,self.view.frame.size.width-caseAncLabel.frame.size.width-50, 50)];
caseAncText.textColor = [UIColor whiteColor];
caseAncText.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:24.0f];
caseAncText.text =[[self agenda] getCaseAnc:forCase];
caseAncText.backgroundColor = [UIColor clearColor];
caseAncText.numberOfLines=0;
//caseAncText.adjustsFontSizeToFitWidth = NO;
caseAncText.tag=forCase;
[caseAncText sizeToFit];
//caseSummaryText.lineBreakMode = NSLineBreakByWordWrapping;
caseAncText.frame=[self calCellLabelFrame:caseAncText previousLabel:caseAncLabel];
//add button
UIButton *acceptButton=[UIButton buttonWithType:UIButtonTypeCustom];
[acceptButton setTag:forCase];
acceptButton.titleLabel.tag=1;
[acceptButton setFrame:CGRectMake(caseAncLabel.frame.size.width+50,caseAncText.frame.origin.y + caseAncText.bounds.size.height+20,181,39)];
NSString *radioButtonImage=#"view_attachment.png";
UIImage *acceptbuttonImage = [UIImage imageNamed:radioButtonImage];
[acceptButton setBackgroundImage:acceptbuttonImage forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(showAttachements:) forControlEvents:UIControlEventTouchUpInside];
//whie line
UIView *anotherline = [[UIView alloc] initWithFrame:CGRectMake(0, acceptButton.frame.origin.y + acceptButton.bounds.size.height+15, self.view.frame.size.width, 1)];
anotherline.backgroundColor=[UIColor whiteColor];
anotherline.tag=forCase;
[view addSubview:acceptButton];
[view addSubview: caseNumberLabel];
[view addSubview:caseNumberText];
[view addSubview:caseNameLabel];
[view addSubview:caseNameText];
[view addSubview:caseSummaryLabel];
[view addSubview:caseSummaryText];
[view addSubview:caseAncText];
[view addSubview:caseAncLabel];
[view addSubview:anotherline];
view.frame = CGRectMake(0,0, self.view.frame.size.width,anotherline.frame.origin.y + anotherline.bounds.size.height+5);
CGFloat redLevel = rand() / (float) RAND_MAX;
CGFloat greenLevel = rand() / (float) RAND_MAX;
CGFloat blueLevel = rand() / (float) RAND_MAX;
view.backgroundColor = [UIColor colorWithRed: redLevel
green: greenLevel
blue: blueLevel
alpha: 1.0];
return view;
}
I call reload data like this
dispatch_async(dispatch_get_main_queue(), ^{
[_agenda loadFromPlist];
[[self tableView] reloadData];
});
Any idea why cells overlaps?
Its your UITableview cellforIndexPath causing overlap
try this
if (!populateCell){
populateCell = (UIView*)[cell viewWithTag:1];
populateCell= [self populateCellView:indexPath.row];
if ([[cell contentView] subviews]){
for (UIView *subview in [[cell contentView] subviews]) {
[subview removeFromSuperview];
}
}
[[cell contentView] addSubview:populateCell];
}
cell.backgroundColor=[UIColor clearColor];
At the end of the UITableViewDataSource method, tableView:cellForRowAtIndexPath:, you have to call [[cell contentView] addSubView:populateCell]. If the table dequeued a cell successfully, you have to retrieve the appropriate populateCell and add it to the contentView.
If you use storyboards, and set a different height for the cells, and the rows in the tableview, the height will usually overlap. The other answers are also highly valid, but usually when I've encountered this problem, the bug lies in a different value on row height and cell height in the tableview object in your storyboard...

UICollectionView poor scrolling performance

The problem I encounter is that whenever a row goes out of view, the scroll has a very fast and short lag.
This is my code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)_collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
Saints *note = nil;
int aX=0;
int aY=0;
note = [self.fetchedResultsController objectAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews) {
if([view isKindOfClass:[UIImageView class]])
{
[view removeFromSuperview];
}
else if([view isKindOfClass:[UILabel class]])
{
[view removeFromSuperview];
}}
cell.backgroundColor = [UIColor clearColor];
UIImage *imgbackground = [UIImage imageNamed:#"today-left-side-images-bg.png"];
NSArray *messages = [[NSArray alloc] initWithObjects: #"random-saint-text-bg-brown.png",#"random-saint-text-bg-brightblue.png",#"random-saint-text-bg-green.png",#"random-saint-text-bg-grey.png",#"random-saint-text-bg-lightblue.png",#"random-saint-text-bg-lime.png",#"random-saint-text-bg-purple.png",#"random-saint-text-bg-red.png",#"random-saint-text-bg-teal.png",nil];
int randNum = arc4random() % [messages count];
NSString *returnValue = [messages objectAtIndex:randNum];
NSString *rndBGImg= returnValue;
UIImage *imgbackgroundlower = [UIImage imageNamed:rndBGImg];
UIImageView *imgViewlower = [[UIImageView alloc] initWithImage:imgbackgroundlower];
//imgViewlower.frame=CGRectMake(aX, aY+140, 140,73);
imgViewlower.frame=CGRectMake(aX+4, aY+114, 119,43);
UIImageView *imgView = [[UIImageView alloc] initWithImage:imgbackground];
imgView.frame=CGRectMake(aX, aY, 127,162);
UIImageView *imgSaintPic = [[UIImageView alloc]init];
imgSaintPic.tag=1;
imgSaintPic.frame=CGRectMake(aX+6, aY+6, 114,145);
//NSString *imgname = [aDic objectForKey:#"saint_image"];
NSString *imgname = note.saint_imagethumbnail;
UIImage *tempimg= [UIImage imageNamed:imgname];
[imgSaintPic setImage:tempimg];
UILabel *lblNamelocal=[[UILabel alloc]init];
NSString *strSaintName=note.saint_name;
//lblNamelocal.text=strSaintName;
if([note.saint_title length]>1)
lblNamelocal.text=[NSString stringWithFormat:#"%# %#",note.saint_title,strSaintName];
else
lblNamelocal.text=[NSString stringWithFormat:#"%#",strSaintName];
//lblNamelocal.frame = CGRectMake(aX+6, aY+109, 116,30);
[lblNamelocal sizeToFit];
lblNamelocal.frame = CGRectMake(aX+5, aY+115, 118,26);
lblNamelocal.lineBreakMode = UILineBreakModeWordWrap;
lblNamelocal.numberOfLines = 0;
lblNamelocal.backgroundColor = [UIColor clearColor];
lblNamelocal.textColor = [UIColor whiteColor];
lblNamelocal.font = [UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:11 ];
// lblNamelocal.textAlignment=UITextAlignmentLeft;
lblNamelocal.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
lblNamelocal.shadowColor = [UIColor darkGrayColor];
lblNamelocal.shadowOffset = CGSizeMake(0,0.5);
lblNamelocal.textAlignment = UITextAlignmentCenter;
UILabel *lblsubtitle=[[UILabel alloc]init];
//NSString *strSaintSubtitle=[aDic objectForKey:#"saint_title"];
lblsubtitle.text=note.saint_subtitle;
//lblsubtitle.frame = CGRectMake(aX+6, aY+132, 116, 25);
lblsubtitle.frame = CGRectMake(aX+5, aY+140, 113, 20);
lblsubtitle.lineBreakMode = UILineBreakModeWordWrap;
lblsubtitle.numberOfLines = 2;
lblsubtitle.backgroundColor = [UIColor clearColor];
lblsubtitle.textColor = [UIColor whiteColor];
lblsubtitle.font = [UIFont fontWithName:#"HelveticaNeue" size:10];
// Removed CJamesRun lblsubtitle.textAlignment=UITextAlignmentLeft;
lblsubtitle.shadowColor = [UIColor darkGrayColor];
lblsubtitle.shadowOffset = CGSizeMake(0,0.5);
lblsubtitle.textAlignment = UITextAlignmentCenter;
imgViewlower.tag=3;
lblNamelocal.tag=2;
lblsubtitle.tag=4;
[cell.contentView addSubview:imgView];
[cell.contentView addSubview:imgSaintPic];
[cell.contentView addSubview:imgViewlower];
[cell.contentView addSubview:lblNamelocal];
[cell.contentView addSubview:lblsubtitle];
// cell.layer.masksToBounds = NO;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
What I've tired is to rasterize the cell layer, and also to remove the views from the SuperView upon creating a new cell.
Any other suggestions?
I would recommend setting up your cells' subviews just once, and then only updating the contents inside collectionView:cellForItemAtIndexPath:. E.g. you're loading some images in each cell, but those are the same for every cell, so loading them every time the cell is reused is unnecessary.

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