universal uitableview stretching issue - iphone

I am developing an universal(iphone/ipad) application. I am using uitableview in this application. table cell being draw using code. Now problem is that it can be fit either on iPad or iPhone from single code, If I put code only on single time.
To achieve this I need to put condition to check the device and then need to code 2 time, mean 1 for iphone and another for iPad to set its background images and frames of uilable etc..
This is looking rubbish and stupid job to me. Is there any way to achieve this goal by single code.
My code is as below. I am using xcode 4.2 ARC
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIFont *fontName=[UIFont fontWithName:#"HelveticaNeue LT 57 Cn" size:18.0f];
UIFont *fontTitle=[UIFont fontWithName:#"HelveticaNeue LT 57 Cn" size:12.0f];
UIFont *grayLight=[UIFont systemFontOfSize:12.0f];
//UIFont *fontBold=[UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSMutableDictionary *dic=[arrEmails objectAtIndex:indexPath.row];
//NSLog(#"%#",dic);
int tot=4;
NSString *imageName=[NSString stringWithFormat:#"inbox_list%d",(indexPath.row%tot)+1];
UIImageView *imgBg=[[UIImageView alloc] initWithFrame:CGRectMake(-30, 10, 303, 70)];
[imgBg setImage:[UIImage imageNamed:imageName]];
[cell.contentView addSubview:imgBg];
NSString *name=nameDisplayType==1 ? [[dic valueForKey:#"firstName"] stringByAppendingFormat:#" %#", [dic valueForKey:#"lastName"]] : [[dic valueForKey:#"lastName"] stringByAppendingFormat:#" %#", [dic valueForKey:#"firstName"]];
UILabel *lblFirstName=[[UILabel alloc] initWithFrame:CGRectMake(30 ,15,150,20)];
[lblFirstName setText:name];
[lblFirstName setBackgroundColor:[UIColor clearColor]];
[lblFirstName setTextColor:UIColorFromRedGreenBlue(162, 23, 25)];
[lblFirstName setTextAlignment:UITextAlignmentLeft];
[lblFirstName setFont:fontName];
[lblFirstName setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:lblFirstName];
UILabel *lblEmailId=[[UILabel alloc] initWithFrame:CGRectMake(30,28,200,20)];
[lblEmailId setText:[dic valueForKey:#"emailId"]];
[lblEmailId setBackgroundColor:[UIColor clearColor]];
[lblEmailId setTextAlignment:UITextAlignmentLeft];
[lblEmailId setFont:grayLight];
[lblEmailId setTextColor:[UIColor grayColor]];
[lblEmailId setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:lblEmailId];
NSDateFormatter *formatter=[[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date=[formatter dateFromString:[dic valueForKey:#"date"]];
[formatter setDateFormat:#"dd MMM, yyyy"];
NSString *formattedDate=[formatter stringFromDate:date];
//NSLog(#"%# formated:%#",[dic valueForKey:#"date"],formattedDate);
UILabel *lblDate=[[UILabel alloc] initWithFrame:CGRectMake(190,15,100,20)];
[lblDate setText:formattedDate];
[lblDate setBackgroundColor:[UIColor clearColor]];
[lblDate setTextAlignment:UITextAlignmentLeft];
[lblDate setFont:grayLight];
[lblDate setTextColor:[UIColor blackColor]];
[cell.contentView addSubview:lblDate];
UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(20,53,200,20)];
[lblTitle setText:[dic valueForKey:#"title"]];
[lblTitle setBackgroundColor:[UIColor clearColor]];
[lblTitle setTextAlignment:UITextAlignmentLeft];
[lblTitle setFont:fontTitle];
[lblTitle setTextColor:[UIColor blackColor]];
[cell.contentView addSubview:lblTitle];
UIButton *btnViewGift=[[UIButton alloc] initWithFrame:CGRectMake(235, 55, 20, 20)];
[btnViewGift addTarget:self action:#selector(btnViewGiftPressed:) forControlEvents:UIControlEventTouchUpInside];
[btnViewGift setTag:indexPath.row];
[cell.contentView addSubview:btnViewGift];
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
Please help and give me some ideas. Thanks in advance.

Instead of passing hardcoded agruments in frame, you can decide the frame dynamically using frame and bounds property of view. But you have to take care of each UI element.

Related

Setting the text on a UILabel is crashing my app

So I have setup my UILabel, but when I set the text in my game loop to a string that is the score (so the Text is reset every loop) my app crashes.
This is the error I get:
0x15560b0: cmpl (%eax), %ecx Thread 1
The Breakpoint says this:
EXC_BAD_ACCESS(code=1, address=0x67b30064
Here is how I am setting up my UILabel (in my init method) :
//SET UP THE SCORE LABEL HERE
scoreLabel = [[UILabel alloc] init];
scoreString = [NSString stringWithFormat:#"%d", score];
[scoreLabel setFont: [UIFont fontWithName: #"TimesNewRoman" size: 10.0f]];
[scoreLabel setFrame: CGRectMake(262, 250, 100, 40)];
[scoreLabel setBackgroundColor:[UIColor clearColor]];
[scoreLabel setTextColor: [UIColor clearColor]];
[scoreLabel setTextColor: [UIColor whiteColor]];
scoreLabel.transform = CGAffineTransformMakeRotation(89.53);
[self addSubview: scoreLabel];
//[scoreLabel setText: scoreString];
Thank You!
Are you doing your label update off the main queue? I had these crashes until I dispatched the update on the main queue.
dispatch_async(dispatch_get_main_queue(), ^{
self.lblSyncProgress.text = #"Some string";
});
//in your .h file
UILabel *scoreLabel;
NSString *scoreString;
//in your .m file
//SET UP THE SCORE LABEL HERE
scoreLabel = [[UILabel alloc] init];
[scoreLabel setFont: [UIFont fontWithName: #"TimesNewRoman" size: 10.0f]];
[scoreLabel setFrame: CGRectMake(262, 250, 100, 40)];
[scoreLabel setBackgroundColor:[UIColor clearColor]];
[scoreLabel setTextColor: [UIColor clearColor]];
[scoreLabel setTextColor: [UIColor whiteColor]];
scoreLabel.transform = CGAffineTransformMakeRotation(89.53);
[self addSubview: scoreLabel];
//In your update method
scoreString = [NSString stringWithFormat:#"%d", score];
scoreLabel.text = scoreString;
I noticed in your code that you had
scoreString = [NSString stringWithFormat:#"%d", score];
Make sure that "score" is a char. If it is not have a look at this

Reference counted object is used after being it is released

I am getting memory warning as "Reference counted object is used after being it is released"
For this i have tried autorelease also. but no use.
below is the code which gives my warning.what is the issue. pls let me know
UICustomSwitch *switchView = [[UICustomSwitch alloc] initWithFrame:CGRectZero];
[switchView initWithFrame:CGRectMake(180,5,260,30)];
[switchView setOn:YES];
mySearchType = 1;
[[switchView rightLabel] setFont:[UIFont fontWithName:#"Georgia" size:16.0f]];
[[switchView leftLabel] setFont:[UIFont fontWithName:#"Georgia" size:16.0f]];
[switchView addTarget:self action:#selector(switchToggled:)forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:switchView];
change the following code
UICustomSwitch *switchView = [[UICustomSwitch alloc] initWithFrame:CGRectZero];
[switchView initWithFrame:CGRectMake(180,5,260,30)];
into
UICustomSwitch *switchView = [[UICustomSwitch alloc] initWithFrame:CGRectMake(180,5,260,30)];

How to add multiple label into an imageview?

I am new to this iphone development .I am now stuck with a problem .In my application i require coverflow in which multiple labels should be shown.So for that i added an image as a sub view for view and then added the labels as a sub view for the image view.Every thing works fine for the first 7 elements But when i scroll it is showing the same elements again
I am using
https://github.com/nicklockwood/iCarousel
this to attain coverflow
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(ReflectionView *)view
{
UIImageView *imageView =nil;
UILabel *yourLabel=nil;
UILabel *yourLabel1=nil;
UILabel *yourLabel2=nil;
cardAvailableDataObject *singleCard=[self.cards objectAtIndex:index];
if (view == nil)
{
//set up reflection view
view = [[[ReflectionView alloc] initWithFrame:CGRectMake(0,0,200,self.view.frame.size.width/1.42)] autorelease];
imageView = [ [ UIImageView alloc ] initWithFrame:CGRectMake(0,0,200,self.view.frame.size.width/1.42)];
[view addSubview:imageView];
yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, -5, 200, 50)];
yourLabel.textAlignment = UITextAlignmentCenter;
[yourLabel setTextColor:[UIColor colorWithRed:(38/255.f) green:(171/255.f) blue:(226/255.f) alpha:1.0f]];
[yourLabel setBackgroundColor:[UIColor clearColor]];
[yourLabel setFont:[UIFont fontWithName: #"Trebuchet MS" size: 17.0f]];
[imageView addSubview:yourLabel];
yourLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(90, 40, 300, 20)];
[yourLabel1 setTextColor:[UIColor blackColor]];
[yourLabel1 setBackgroundColor:[UIColor clearColor]];
[yourLabel1 setFont:[UIFont fontWithName: #"Trebuchet MS" size: 12.0f]];
[imageView addSubview:yourLabel1];
yourLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(90, 61, 300, 20)];
[yourLabel2 setTextColor:[UIColor blackColor]];
[yourLabel2 setBackgroundColor:[UIColor clearColor]];
[yourLabel2 setFont:[UIFont fontWithName: #"Trebuchet MS" size: 12.0f]];
[imageView addSubview:yourLabel2];
}
else
{
imageView = [[view subviews] lastObject];
yourLabel = [[imageView subviews] lastObject];
yourLabel1 = [[imageView subviews] lastObject];
yourLabel2= [[imageView subviews] lastObject];
}
yourLabel.text=singleCard.name;
yourLabel2.text=singleCard.companyname;
yourLabel1.text=singleCard.designation;
imageView.image=[profile objectAtIndex:index];
return view;
}
This is my code .Can any one suggest how to solve this

UIScrollView paging selected in center

I have made a UIScrollView which holds four UILabels. I would like that the selected UILabel is not the one in the left of the screen but in the center. I have attached two images to illustrate what I mean. On the first image, the green label would be the selected one and on the next image the blue label would be the selected one.
Is there any way to do this?
This is my code:
[scrollView setContentSize:CGSizeMake(428, 65)];
[scrollView setDelegate:self];
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 107, 65)];
[label1 setBackgroundColor:[UIColor redColor]];
[label1 setTextAlignment:UITextAlignmentCenter];
[label1 setText:#"Wednesday"];
[scrollView addSubview:label1];
[label1 release];
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(107, 0, 107, 65)];
[label2 setBackgroundColor:[UIColor greenColor]];
[label2 setTextAlignment:UITextAlignmentCenter];
[label2 setText:#"Thursday"];
[scrollView addSubview:label2];
[label2 release];
UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(214, 0, 107, 65)];
[label3 setBackgroundColor:[UIColor blueColor]];
[label3 setTextAlignment:UITextAlignmentCenter];
[label3 setText:#"Friday"];
[scrollView addSubview:label3];
[label3 release];
UILabel *label4 = [[UILabel alloc] initWithFrame:CGRectMake(321, 0, 107, 65)];
[label4 setBackgroundColor:[UIColor orangeColor]];
[label4 setTextAlignment:UITextAlignmentCenter];
[label4 setText:#"Saturday"];
[scrollView addSubview:label4];
[label4 release];
It seems to be the easiest to rotate the UIPickerView. This can be done like this.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
arrayDays = [[NSMutableArray alloc] init];
[arrayDays addObject:#"ONSDAG"];
[arrayDays addObject:#"TORSDAG"];
[arrayDays addObject:#"FREDAG"];
[arrayDays addObject:#"LØRDAG"];
arrayDates = [[NSMutableArray alloc] init];
[arrayDates addObject:#"29. JUNI"];
[arrayDates addObject:#"30. JUNI"];
[arrayDates addObject:#"1. JULI"];
[arrayDates addObject:#"2. JULI"];
pickerViewDay = [[UIPickerView alloc] initWithFrame:CGRectZero];
[pickerViewDay setDelegate:self];
[pickerViewDay setShowsSelectionIndicator:NO];
CGAffineTransform rotate = CGAffineTransformMakeRotation(-M_PI/2);
rotate = CGAffineTransformScale(rotate, 0.25, 2.0);
[pickerViewDay setTransform:rotate];
[pickerViewDay setCenter:CGPointMake(self.view.frame.size.width/2, (pickerViewDay.frame.size.height/2)-3)];
[self.view addSubview:pickerViewDay];
// Adding selection indicator to pickerview
UIImage *selectorImage = [UIImage imageNamed:#"DayPickerView_SelectionIndicator.png"];
UIView *customSelector = [[UIImageView alloc] initWithImage:selectorImage];
[customSelector setFrame:CGRectMake(0, 0, 120, 74)];
[customSelector setCenter:CGPointMake(self.view.frame.size.width/2, customSelector.frame.size.height/2)];
[self.view addSubview:customSelector];
[customSelector release];
// Adding background to pickerview
UIImage *backgroundImage = [UIImage imageNamed:#"DayPickerView_Background.png"];
UIView *custombackground = [[UIImageView alloc] initWithImage:backgroundImage];
[custombackground setFrame:CGRectMake(0, 0, 320, 74)];
// [self.view addSubview:custombackground];
[custombackground release];
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UIView *viewRow = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 80)];
CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
rotate = CGAffineTransformScale(rotate, 0.25, 2.0);
// Date
CGRect rectDate = CGRectMake(30, 0, 150, 80);
UILabel *date = [[UILabel alloc]initWithFrame:rectDate];
[date setTransform:rotate];
[date setText:[arrayDates objectAtIndex:row]];
[date setFont:[UIFont fontWithName:#"Arial-BoldMT" size:37.0]];
[date setShadowColor:[UIColor whiteColor]];
[date setShadowOffset:CGSizeMake(0, -1)];
[date setTextAlignment:UITextAlignmentCenter];
[date setBackgroundColor:[UIColor clearColor]];
[date setClipsToBounds:YES];
[viewRow addSubview:date];
// Day
CGRect rectDay = CGRectMake(-30, 0, 150, 80);
UILabel *day = [[UILabel alloc]initWithFrame:rectDay];
[day setTransform:rotate];
[day setText:[arrayDays objectAtIndex:row]];
[day setFont:[UIFont fontWithName:#"Arial-BoldMT" size:21.0]];
[day setTextColor:[UIColor colorWithRed:0.35 green:0.35 blue:0.35 alpha:1]];
[day setTextAlignment:UITextAlignmentCenter];
[day setBackgroundColor:[UIColor clearColor]];
[day setClipsToBounds:YES];
[viewRow addSubview:day];
return viewRow;
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [arrayDays objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [arrayDays count];
}

tableview cell load all at once in iphone

I have implemented following code in my application.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:#"%#%i",searchQueryString,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
XML_SearchResult *t=[arrayResults objectAtIndex:indexPath.row];
cell=((indexPath.row%2)==0) ?
[self getCellContentView:CellIdentifier drillTitle:t.drill_title stroke_type:t.stroke_type exercise_type:t.exercise_type level_name:t.level_name age_range:t.age_range alterNate:NO] :
[self getCellContentView:CellIdentifier drillTitle:t.drill_title stroke_type:t.stroke_type exercise_type:t.exercise_type level_name:t.level_name age_range:t.age_range alterNate:YES] ;
CGRect a=[cell frame];
UIImageView *bImg=[[UIImageView alloc] initWithFrame:a];
bImg.image=[UIImage imageNamed:#"white-rect-tab-3.png"];
[bImg setContentMode:UIViewContentModeScaleToFill];
cell.selectedBackgroundView=bImg; [bImg release];
}
return cell;
}
-(UITableViewCell*)getCellContentView:(NSString*)cellIdentifier drillTitle:(NSString*)drillTitle stroke_type:(NSString*)stroke_type exercise_type:(NSString*)exercise_type level_name:(NSString*)level_name age_range:(NSString*)age_range alterNate:(BOOL)alterNate
{
CGRect label1Frame=CGRectMake(5, 20, 260, 32),label2Frame=CGRectMake(5, 62, 120, 30),label3Frame=CGRectMake(130, 62, 170, 30);//,BgFrame=CGRectMake(0, 0, 320, 60);
UITableViewCell *cell=[[[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, 312, 95) reuseIdentifier:cellIdentifier] autorelease];
UILabel *tmp; UIImageView *imgBg;
cell.backgroundColor=[UIColor clearColor];
// drill title label
tmp=[[UILabel alloc] initWithFrame:CGRectMake(5, 1, 260, 32)];
tmp.textColor=[UIColor colorWithRed:(9.0/255.0) green:(68.0/255) blue:(85.0/255) alpha:1.0];
[tmp setFont:[UIFont fontWithName:#"ArialRoundedMTBold" size:18]]; tmp.text=drillTitle; [tmp setShadowColor:[UIColor lightGrayColor]];
tmp.backgroundColor=[UIColor clearColor]; [cell.contentView addSubview:tmp]; [tmp release];
// title label - tip
tmp=[[UILabel alloc] initWithFrame:label1Frame];
tmp.textColor=[UIColor colorWithRed:(9.0/255.0) green:(68.0/255) blue:(85.0/255) alpha:1.0];
[tmp setFont:[UIFont fontWithName:#"ArialRoundedMTBold" size:18]]; tmp.text=stroke_type; [tmp setShadowColor:[UIColor lightGrayColor]];
tmp.backgroundColor=[UIColor clearColor]; [cell.contentView addSubview:tmp]; [tmp release];
// sub title - exercise type label - tip
tmp=[[UILabel alloc] initWithFrame:CGRectMake(5, 40 , 260, 32)];
tmp.textColor=[UIColor colorWithRed:(14.0/255.0) green:(105.0/255) blue:(128.0/255) alpha:1.0];
[tmp setFont:[UIFont fontWithName:#"ArialRoundedMTBold" size:15]]; tmp.text=exercise_type; [tmp setShadowColor:[UIColor lightGrayColor]];
tmp.backgroundColor=[UIColor clearColor]; [cell.contentView addSubview:tmp]; [tmp release];
// Age - Range
tmp=[[UILabel alloc] initWithFrame:label2Frame]; tmp.adjustsFontSizeToFitWidth=0; tmp.text=[NSString stringWithFormat:#"Age Range : %#",age_range];
tmp.textColor= [UIColor blackColor];//[UIColor colorWithRed:(14.0/255.0) green:(105.0/255) blue:(128.0/255) alpha:1.0];// : [UIColor blackColor] ;
[tmp setBackgroundColor:[UIColor clearColor]];
[tmp setFont:[UIFont fontWithName:#"ArialMT" size:14]]; [tmp setShadowOffset:CGSizeMake(1,1)]; [tmp setShadowColor:[UIColor lightGrayColor]];
[cell.contentView addSubview:tmp]; [tmp release];
// Difficulty leve - Range
tmp=[[UILabel alloc] initWithFrame:label3Frame]; tmp.adjustsFontSizeToFitWidth=0; tmp.text=[NSString stringWithFormat:#"| Diff. Level : %#",level_name];
tmp.textColor=[UIColor blackColor];//[UIColor colorWithRed:(14.0/255.0) green:(105.0/255) blue:(128.0/255) alpha:1.0];
[tmp setShadowColor:[UIColor lightGrayColor]];
[tmp setBackgroundColor:[UIColor clearColor]];
[tmp setFont:[UIFont fontWithName:#"ArialMT" size:14]]; [tmp setShadowOffset:CGSizeMake(1,1)];
[cell.contentView addSubview:tmp]; [tmp release];
// arrow
imgBg=[[UIImageView alloc] initWithFrame:CGRectMake(280, 35, 13, 13)]; imgBg.contentMode=UIViewContentModeScaleToFill;
imgBg.image=[UIImage imageNamed:#"arrow-2.png"];
[cell.contentView addSubview:imgBg]; [cell.contentView sendSubviewToBack:imgBg]; [imgBg release];
// line
imgBg=[[UIImageView alloc] initWithFrame:CGRectMake(-4, 94, 298, 2)]; imgBg.contentMode=UIViewContentModeScaleToFill;
imgBg.image=[UIImage imageNamed:#"line.png"];
[cell.contentView addSubview:imgBg]; [cell.contentView sendSubviewToBack:imgBg]; [imgBg release];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
return cell;
}
That's all about customizing cell dynamically.
But the problem is - first time only visible cells are created, then after - user tries to scroll down. other cells which are going to be visible is going to be created & then displayed. Due to this, there is some delay in scrolling tableview at first time.
What is the solution for this ?
When developing for mobile platforms, you need to be concerned about memory footprints. I feel that if you tried to load 400 cells with images all at once, you might be asking for trouble. It's not the recommended method and you will certainly introduce a huge delay in loading this.
Instead of hacking like this, work in improving the performance of your cellForIndexPath function to make it load quicker. Or asynchronously.
It is probably the image loading which takes all the time. Creating cells should not take very long, especially if you reuse old ones.
If the images are often the same, then you could cache those. Also scaling takes time and also if the images are not PNG they will take longer to load.
But the solution for me has been to not load the images when I create the cell, i.e. NOT in:
tableView:cellForRowAtIndexPath:
but instead implement:
scrollViewDidEndDecelerating
This is a delegate function which is called when the table stops scrolling. Then you can get a list of the visible cells (indexPathsForVisibleRows) and set the image on each of those.