I have TableViewController and ViewController. In ViewController I save time and in TableViewController I want to show image in table cell if time more then 1:00. But my code doesn’t work… Help me please.
Code in TableViewController
_timeElapsed.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"time0"];
if (self.timeElapsed.text >= #"1:00") {
UIImageView *imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(28.5, 23, 25, 25)];
imageView2.backgroundColor = [UIColor clearColor];
[imageView2.layer setMasksToBounds:YES];
imageView2.tag = 3;
[cell.contentView addSubview:imageView2];
UIImageView *imgView2 = (UIImageView *)[cell.contentView viewWithTag:3];
imgView2.image = [UIImage imageNamed:#"accessory.png"];
}
#seto nugroho
Now my _timeElapsed.text = 2:57 but image doesn’t show
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: [NSString stringWithFormat:#"Cell%d", indexPath.row] forIndexPath:indexPath];
_timeElapsed.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"time0"];
NSString *stringFromInput = self.timeElapsed.text;
NSString *stringToCompare = #"1:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"m:ss";
NSDate *timeFromInput = [dateFormatter dateFromString:stringFromInput];
NSDate *timeToCompare = [dateFormatter dateFromString:stringToCompare];
if ([timeFromInput compare:timeToCompare] == NSOrderedDescending) {
//actual time is greater
UIImageView *imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(28.5, 23, 25, 25)];
imageView2.backgroundColor = [UIColor clearColor];
[imageView2.layer setMasksToBounds:YES];
imageView2.tag = 3;
[cell.contentView addSubview:imageView2];
UIImageView *imgView2 = (UIImageView *)[cell.contentView viewWithTag:3];
imgView2.image = [UIImage imageNamed:#"accessory.png"];
} else {
//not greater than 1 minutes
}
[tableView setSeparatorInset:UIEdgeInsetsMake(0, 70, 0, 1)];
return cell;
}
#iOS Geek
If timeString = #"0:05" and if (timeInSeconds > 1) image doesn’t show but in this case I see image.
NSString *timeString = #"0:05";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"mm:ss";
NSDate *timeDate = [formatter dateFromString:timeString];
formatter.dateFormat = #"mm";
int minutes = [[formatter stringFromDate:timeDate] intValue];
formatter.dateFormat = #"ss";
int seconds = [[formatter stringFromDate:timeDate] intValue];
int timeInSeconds = seconds + minutes * 60;
if (timeInSeconds > 1) {
UIImageView *imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(28.5, 23, 25, 25)];
imageView2.backgroundColor = [UIColor clearColor];
[imageView2.layer setMasksToBounds:YES];
imageView2.tag = 3;
[cell.contentView addSubview:imageView2];
UIImageView *imgView2 = (UIImageView *)[cell.contentView viewWithTag:3];
imgView2.image = [UIImage imageNamed:#"accessory.png"];
}
You can not compare string values, unless you want to see if they are equal character by character(in which case you use "isEqualToString:").
Convert you time to integer values and then compare.
Update
You can use NSDateFormatter to get seconds and minutes from the time string:
NSString *timeString = #"3:31";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"mm:ss";
NSDate *timeDate = [formatter dateFromString:timeString];
formatter.dateFormat = #"mm";
int minutes = [[formatter stringFromDate:timeDate] intValue];
formatter.dateFormat = #"ss";
int seconds = [[formatter stringFromDate:timeDate] intValue];
int timeInSeconds = seconds + minutes * 60;
Your code doesn't work because you are comparing String, which obviously is not what you want.
You should convert your string to date and then compare it.
NSString *stringFromInput = self.timeElapsed.text;
NSString *stringToCompare = #"1:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"m:ss";
NSDate *timeFromInput = [dateFormatter dateFromString:stringFromInput];
NSDate *timeToCompare = [dateFormatter dateFromString:stringToCompare];
if ([timeFromInput compare:timeToCompare] == NSOrderedDescending) {
//actual time is greater
} else {
//not greater than 1 minutes
}
Turn warnings on. The compiler will warn you that you are comparing pointers with the >= operator, which is often undefined behaviour, and often nonsense, as in your case.
self.timeElapsed.text >= #"1:00"
compares two pointers. It compares a pointer to the location where the object self.timeElapsed.text is stored, and a pointer to the location where the object #"1:00" is stored. Which is obviously nonsense and completely unrelated to the actual values of the objects.
It's bad to compare time like this:
self.timeElapsed.text >= #"1:00"
Please convert it to NSDate or Int(not so good but easy). Like this:
[[self.timeElapsed.text componentsSeparatedByString:#":"] firstObject].intValue > 1
Related
I am working on a chat application where i am using alex barinov's chat bubble example. I am able to send/receive messages. I want to add some labels and views on each chat bubble like time, date, delivered image, etc.
I tried to add some labels over the chat bubble's contentView in UIBubbleTableViewCell.m class in method named -(void)setupInternalData, but the label (date label) gets repeated for every bubble , and it overwrites the previous label, and it contains both the labels.
Here is the address from where i downloaded the project -https://github.com/AlexBarinov/UIBubbleTableView
Below is my code for adding labels to chat bubble view -
-(void)setupInternalData{
_fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.origin.x, self.frame.size.height-28, 100, 14)];
_fromLabel.numberOfLines = 1;
_fromLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
_fromLabel.clipsToBounds = YES;
_fromLabel.layer.cornerRadius=5;
[_fromLabel setFont:[UIFont systemFontOfSize:5]];
[self.customView addSubview:_fromLabel];
//display msg sent time
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *currentTime = [dateFormatter stringFromDate:today];
_lblMsgTime.text=currentTime;
_lblMsgTime.frame=CGRectMake(12,0, 85, 14);
_lblMsgTime.text=[NSString stringWithFormat:#"%#",currentTime];
_lblMsgTime.textAlignment = NSTextAlignmentRight;
_lblMsgTime.textColor = [UIColor blackColor];
[_fromLabel addSubview:_lblMsgTime];
[_lblMsgTime setAdjustsFontSizeToFitWidth:YES];
//date formater
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"d.M.yyyy";
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *string = [formatter stringFromDate:date];
_lblMsgdate.text=string;
_lblMsgdate.frame=CGRectMake(60 ,0, 85, 14);
_lblMsgdate.text=[NSString stringWithFormat:#"%#",string];
_lblMsgdate.textAlignment = NSTextAlignmentRight;
_lblMsgdate.textColor = [UIColor blackColor];
[_fromLabel addSubview:_lblMsgdate];
[_lblMsgdate setAdjustsFontSizeToFitWidth:YES];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ic__typ__txt.png"]];
backgroundView.frame=CGRectMake(self.frame.origin.x+1, self.frame.size.height-24, 10, 10);
[self.customView addSubview:backgroundView];
[self.customView bringSubviewToFront:_fromLabel];
[self.customView bringSubviewToFront:backgroundView];
[self.contentView addSubview:self.customView];
}
Can anyone please tell me what wrong am i doing here, and what should i be doing. Any help is appreciated. Waiting for your valuable answers.
hey i think you have to create a view and pass it.
create a view in NSBubbleData file's
- (id)initWithText:(NSString *)text date:(NSDate *)date type:(NSBubbleType)type
{
UIFont *font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize size = [(text ? text : #"") sizeWithFont:font constrainedToSize:CGSizeMake(220, 9999) lineBreakMode:NSLineBreakByWordWrapping];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = (text ? text : #"");
label.font = font;
label.backgroundColor = [UIColor clearColor];
#if !__has_feature(objc_arc)
[label autorelease];
#endif
UIEdgeInsets insets = (type == BubbleTypeMine ? textInsetsMine : textInsetsSomeone);
return [self initWithView:label date:date type:type insets:insets];
}
in this you have to create a view, in this view add uilable,uiimage which you want replace UILabel *label with custom view.
I am attempting to create an autosizing cell using PureLayout, however even though all the JSON loads and is correctly assigned to the UITableViewCell objects no data is displayed.
Here is how I am attempting to setup the cell in my Custom TableViewCell Class:
self.backgroundColor = [UIColor whiteColor];
self.accessoryType = UITableViewCellAccessoryNone;
self.accessoryView = nil;
self.selectionStyle = UITableViewCellSelectionStyleNone;
// Fix for contentView constraint warning
[self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
// Create ProfileImageView
self.profilePicture = [[UIImageView alloc] initWithFrame:CGRectZero];
self.profilePicture.translatesAutoresizingMaskIntoConstraints = NO;
self.profilePicture.contentMode = UIViewContentModeScaleAspectFill;
self.profilePicture.backgroundColor = [UIColor whiteColor];
[self.contentView addSubview:self.profilePicture];
// Name label
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.nameLabel.font = [UIFont fontWithName:#"HelveticaNeue-Medium" size:16];
self.nameLabel.textColor = [UIColor blackColor];
self.nameLabel.numberOfLines = 1;
[self.contentView addSubview:self.nameLabel];
// Username label
self.usernameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.usernameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.usernameLabel.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:14];
self.usernameLabel.textColor = [UIColor darkGrayColor];
self.usernameLabel.numberOfLines = 1;
[self.contentView addSubview:self.usernameLabel];
// Tweet label
self.tweetLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.tweetLabel.userInteractionEnabled = YES;
self.tweetLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.tweetLabel.numberOfLines = 0; // Must be set for multi-line label to work
self.tweetLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.tweetLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
self.tweetLabel.textColor = [UIColor darkGrayColor];
[self.contentView addSubview:self.tweetLabel];
// Favorite Button
self.favoriteButton = [[DOFavoriteButton alloc] initWithFrame:CGRectZero image:[UIImage imageNamed:#"star.png"] imageFrame:CGRectMake(0, 0, 15, 15)];
[self.contentView addSubview:self.favoriteButton];
// Retweet Button
self.retweetButton = [[DOFavoriteButton alloc] initWithFrame:CGRectZero image:[UIImage imageNamed:#"retweet.png"] imageFrame:CGRectMake(0, 0, 15, 15)];
self.retweetButton.circleColor = [UIColor colorWithRed:0.04 green:0.83 blue:0.04 alpha:1.0];
self.retweetButton.lineColor = [UIColor colorWithRed:0.08 green:0.93 blue:0.08 alpha:1.0];
self.retweetButton.imageColorOn = [UIColor colorWithRed:0.26 green:0.96 blue:0.26 alpha:1.0];
[self.contentView addSubview:self.retweetButton];
// Reply Button
self.replyButton = [[DOFavoriteButton alloc] initWithFrame:CGRectZero];
[self.replyButton setBackgroundImage:[UIImage imageNamed:#"reply.png"] forState:UIControlStateNormal];
[self.contentView addSubview:self.replyButton];
//
// CONSTRAIN
//
// Name Label
[self.nameLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:60];
[self.nameLabel autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:35];
[self.nameLabel autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:12];
[self.nameLabel autoAlignAxis:ALAxisVertical toSameAxisOfView:self.contentView];
// Username Label
[self.usernameLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.nameLabel withOffset:0.0];
[self.usernameLabel autoSetDimension:ALDimensionHeight toSize:16.5];
[self.usernameLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:58.0];
// Profile Picture
[self.profilePicture autoPinEdge:ALEdgeRight toEdge:ALEdgeLeft ofView:self.nameLabel withOffset:-10.0];
[self.profilePicture autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:12];
[self.profilePicture autoSetDimension:ALDimensionHeight toSize:35];
[self.profilePicture autoSetDimension:ALDimensionWidth toSize:35];
// Tweet Label
[self.tweetLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.usernameLabel withOffset:8.0];
[self.tweetLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:5.0];
Here is how I initiate the cell in my UITableViewController:
TwitterCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"TwitterCell"];
// Add Tap Listeners
UITapGestureRecognizer *nameLabelTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleCellNameTap:)];
[cell.nameLabel addGestureRecognizer:nameLabelTap];
UITapGestureRecognizer *profileImageTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleCellProfileImageTap:)];
[cell.profilePicture addGestureRecognizer:profileImageTap];
if (cell == nil) {
cell = [[TwitterCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TwitterCell"];
}
NSDictionary *data = tweets[indexPath.row];
// NSDate
NSString *nameString = data[#"user"][#"name"];
NSString *screenName = data[#"user"][#"screen_name"];
NSString *tweetString = data[#"text"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setLocale:usLocale];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat: #"EEE MMM dd HH:mm:ss Z yyyy"];
NSDate *date = [dateFormatter dateFromString:[data objectForKey:#"created_at"]];
NSDate *currentDateNTime = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
NSDateComponents *twitcomponents = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:date];
NSInteger twithour = [twitcomponents hour];
NSInteger twitminute = [twitcomponents minute];
NSInteger twitsecond = [twitcomponents second];
NSDateComponents *realcomponents = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:currentDateNTime];
NSInteger realhour = [realcomponents hour];
NSInteger realminute = [realcomponents minute];
NSInteger realsecond = [realcomponents second];
NSInteger hour = realhour - twithour;
NSInteger minute = realminute - twitminute;
NSInteger second = realsecond - twitsecond;
NSLog(#"Formatted hour: %ld, Formatted minute: %ld, Formatted second: %ld",(long)hour, (long)minute, (long)second);
int adjustedSeconds = ((int)minute * 60) - abs((int)second);
int adjustedMinutes = adjustedSeconds / 60;
if (hour==1 > minute > 0) {
int negmin = ((int)hour * 60) - abs((int)minute);
int posmin = abs(negmin);
NSString *strInt = [NSString stringWithFormat:#"%dm",posmin];
cell.timeAgo.text = strInt;
}else if (hour>0){
NSString *strInt = [NSString stringWithFormat:#"%ldh",(long)hour];
cell.timeAgo.text = strInt;
}else if (hour==1){
NSString *strInt = [NSString stringWithFormat:#"%ldh",(long)hour];
cell.timeAgo.text = strInt;
}else if(minute == 1 > second){
NSString *strInt = [NSString stringWithFormat:#"%lds",(long)second];
cell.timeAgo.text = strInt;
}else{
NSString *strFromInt = [NSString stringWithFormat:#"%dm",adjustedMinutes];
cell.timeAgo.text = strFromInt;
}
[cell.favoriteButton addTarget:self action:#selector(favoriteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell.retweetButton addTarget:self action:#selector(retweetButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
// Set Values
[cell.nameLabel setText:nameString];
cell.nameLabel.userInteractionEnabled = YES;
cell.profilePicture.userInteractionEnabled = YES;
cell.tweetLabel.text = tweetString;
cell.usernameLabel.text = [NSString stringWithFormat:#"#%#",screenName];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *imageUrl = [[data objectForKey:#"user"] objectForKey:#"profile_image_url"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
dispatch_async(dispatch_get_main_queue(), ^{
cell.profilePicture.image = [UIImage imageWithData:data];
CALayer *imageLayer = cell.profilePicture.layer;
[imageLayer setCornerRadius:18];
[imageLayer setMasksToBounds:YES];
});
});
Is the tableview's delegate and datasource all set? You can do that by setting:
self.tableView.delegate = self;
self.tableView.dataSource = self;
in your viewDidLoad method.
And are you running the numberOfSectionsInTableView: and the numberOfRowsInSection: methods also?
I assume you are initializing the cell in the cellForRowAtIndexPath:, and do you remember to return the cells in there?
In My app I have a UITextField. When a user enters text such as 123456 it should appear something like 123,456.00 in the textfield.
The following code is used:
UITextField *txt = [[UITextField alloc]initWithFrame:CGRectMake(300, 120+y*58, 280, 31)];
txt.keyboardType = UIKeyboardTypeDecimalPad;
txt.borderStyle = UITextBorderStyleRoundedRect;
txt.font = [UIFont systemFontOfSize:15];
txt.textAlignment = NSTextAlignmentLeft;
txt.returnKeyType = UIReturnKeyDefault;
txt.delegate = self;
[txt addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
-(void)textFieldDidChange:(UITextField *)theTextField
{
NSString *textFieldText = [theTextField.text stringByReplacingOccurrencesOfString:#"," withString:#""];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *number = [formatter numberFromString:textFieldText];
NSString *formattedOutput = [formatter stringFromNumber:number];
theTextField.text=formattedOutput;
}
Use below code
NSString *textFieldText = theTextField.text ;
float f = [theString floatValue];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
[formatter setLocale:[NSLocale currentLocale]];
NSLog(#"%#", [formatter stringFromNumber:#(f)]);
Set MinimumFractionDigits to 2 & MaximumFractionDigits to 2.Try above code in textFieldDidEndEditing delegate method of textfield.
You are almost close to your solution just few things need enhancement. First you must have to specify the maximum and minimum allowed fractions digits like this:
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
It will fix the *.00 problem, then there is another problem of updating it back to the UI. Since you are setting the textfield text:
theTextField.text=formattedOutput;
It will lose the current position of editing and hence you will lose the ground. e.g.,
You typed 1, the above code will update the textfield with 1.00 and the cursor will move to position 5:
1.00
^^^^^
If you will edit further you won't get the expected result (the text will try to append at the end).
To fix this either you should update the text field when you finish editing using the handler textFieldDidEndEditing or you should use some other control like UILabel to display the formatted result.
Sample Code: (for demo)
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITextField *txt = [[UITextField alloc]initWithFrame:CGRectMake(20, 120+(3)*58, 280, 31)];
txt.keyboardType = UIKeyboardTypeDecimalPad;
txt.borderStyle = UITextBorderStyleRoundedRect;
txt.font = [UIFont systemFontOfSize:15];
txt.textAlignment = NSTextAlignmentLeft;
txt.returnKeyType = UIReturnKeyDefault;
txt.delegate = self;
[self.view addSubview:txt];
[txt addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
lbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 160+(3)*58, 280, 31)];
[self.view addSubview:lbl];
}
-(void)textFieldDidChange:(UITextField *)theTextField
{
NSString *textFieldText = [theTextField.text stringByReplacingOccurrencesOfString:#"," withString:#""];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
NSNumber *number = [formatter numberFromString:textFieldText];
NSString *formattedOutput = [formatter stringFromNumber:number];
[lbl setText:formattedOutput];
}
You can set text like this to your textview.
theTextField.text = [NSString stringWithFormat:#"%.02f", floatVal];
Hope this helps.
If you add these two lines to the code snippet you posted:
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
right after the line in which you set the number formatter's style to NSNumberFormatterDecimalStyle, it should give you exactly what you want.
#"123456" would result in #"123,456.00"
and #"1" would result in #"1.00"
I'm currently showing a Date Picker of the kind UIDatePickerModeCountDownTimer that uses:
- (UIDatePicker *)datePicker {
if (!_datePicker) {
_datePicker = [[UIDatePicker alloc] init];
_datePicker.datePickerMode = UIDatePickerModeCountDownTimer;
_datePicker.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
}
return _datePicker;
}
- (void)setDuration:(NSTimeInterval)duration {
_duration = duration;
self.datePicker.countDownDuration = _duration;
}
... date picker, and shows (in a label) the time from current date to date chosen in future with:
- (void)update {
if (self.time) {
[self setImage:nil forState:UIControlStateNormal];
NSString *title;
NSTimeInterval timeInterval = [self.time doubleValue];
if (self.ticking) {
NSMutableString *dateFormat = [[NSMutableString alloc] init];
if (timeInterval < 0) {
[dateFormat appendString:#"-"];
}
if (fabsf(timeInterval) > 60 * 60) {
[dateFormat appendString:#"hh:"];
}
[dateFormat appendString:#"mm:ss"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = dateFormat;
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
title = [formatter stringFromDate:date];
if ([self.time integerValue] > 0) {
self.circleView.backgroundColor = [UIColor colorWithRed:0.373 green:0.702 blue:0.522 alpha:1];
} else {
self.circleView.backgroundColor = [UIColor colorWithRed:0.820 green:0.373 blue:0.424 alpha:1];
}
} else {
NSMutableString *text = [[NSMutableString alloc] init];
if (fabsf(timeInterval) < 60) {
// Show seconds
[text appendFormat:#"%.0fs", timeInterval];
} else if (fabsf(timeInterval) < 60 * 60) {
// Show minutes
[text appendFormat:#"%.0fm", floorf(timeInterval / 60)];
} else {
// Show hours
[text appendFormat:#"%.0fh", floorf(timeInterval / 60 / 60)];
}
title = text;
self.circleView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.2];
}
[self setTitle:title forState:UIControlStateNormal];
return;
}
[self setTitle:nil forState:UIControlStateNormal];
[self setImage:[UIImage imageNamed:#"plus"] forState:UIControlStateNormal];
self.circleView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.05];
}
... but I switched the DatePicker to UIDatePickerModeDateAndTime and need to figure out how to update my update method with it.
I need to show month/day in addition to hour/minute/second in the label.
If you want a method like delegate, then this can help you..
Add target to your date picker....
[myDatePicker addTarget:self action:#selector(onPickerValueChanged:) forControlEvents:UIControlEventValueChanged];
Remove target in dealloc. Otherwise if your picker is scrolling and viewController is popped, app will crash.
- (void dealloc
{
[myPicker removeTarget:self action:#selector(onPickerValueChanged:) forControlEvents:UIControlEventValueChanged];
[myPicker release];//FOR NON ARC
[super dealloc];//FOR NON ARC
}
Implement value Change like
- (IBAction)onPickerValueChanged:(id)sender
{
[self update];
}
I'm having some trouble with lag in my UITableview.
There aren't any problems on an iPhone 5 and after I started caching images in an NSDictionary, the iPhone 4 with iOS 6 became very responsive.
The problem remains on an iPhone 4 with iOS 7 however.
I've read trough some threads here with tips about making views opaque which I did but it didn't help. All my views except the labels are opaque (because if they are opaque they fill and that won't work for my purpose)
I do load a background image from the storyboard, do you guys know if this might be affecting performance? Is the storyboard inefficient when it comes to loading images?
Do you have any other tips for improving performance on a UITableView?
Thanks in advance!
Some code as requested,and these are the elements on the cell: http://imgur.com/Dcif6QE
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HomeListCell *cell;
if([self.eventList lastObject])
{
static NSString *CellIdentifier = #"HomeListCell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.userInteractionEnabled = YES;
cell.event = [self.eventList objectAtIndex:indexPath.row];
cell.parent = self;
if([cell.event.event.event_type count] != 0)
{
Event_Type *eventType = [cell.event.event.event_type firstObject];
NSString *imageName = #"HomeList_Type";
imageName = [imageName stringByAppendingString:eventType.name];
cell.eventTypeImage.image = [self.imageDict objectForKey:imageName];
}
//Laad de images hier uit de cache om scroll performance te verbeteren
int score = [cell.event.rating intValue];
[cell moveView:cell.ratingNumber duration:0.0 curve:UIViewAnimationCurveLinear x:0.0 y:0.0];
if(score > 0)
{
cell.ratingImage.image = [self.imageDict objectForKey:#"HomeList_plus"];
}
else if(score == 0)
{
cell.ratingImage.image = nil;
[cell moveView:cell.ratingNumber duration:0.0 curve:UIViewAnimationCurveLinear x:0.0 y:-10.0];
}
else
{
cell.ratingImage.image = [self.imageDict objectForKey:#"HomeList_min.png"];
score = -score;
}
cell.ratingNumber.text = [NSString stringWithFormat:#"%d", score];
[cell styleSelf];
}
And styleSelf has this code:
-(void) styleSelf {
LocationManager *locationManager = [LocationManager sharedInstance];
//Tekens die verandert moeten worden
NSCharacterSet *notAllowedY = [NSCharacterSet characterSetWithCharactersInString:#"ÿ"];
NSString *resultString = [[event.event.name componentsSeparatedByCharactersInSet:notAllowedY] componentsJoinedByString:#"y"];
//Afstand berekening
double eventLong = [self.event.location.address.gps_long doubleValue];
double eventLat = [self.event.location.address.gps_lat doubleValue];
CLLocation* locatie = [[CLLocation alloc]initWithLatitude:eventLat longitude:eventLong];
//Date + time
NSString *eventDate = event.opening;
eventDate = [eventDate stringByReplacingOccurrencesOfString:#"T" withString:#" "];
NSDate *theDate;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
if([eventDate hasSuffix:#"Z"])
{
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ssZ"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
theDate = [dateFormatter dateFromString:eventDate];
}
else
{
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
theDate = [dateFormatter dateFromString:eventDate];
}
[dateFormatter setDateFormat:#"HH:mm"];
self.timeNumberLabel.text = [dateFormatter stringFromDate:theDate];
self.timeNumberAfscheurLabel.text = [dateFormatter stringFromDate:theDate];
[dateFormatter setDateFormat:#"MM-dd"];
if ([[dateFormatter stringFromDate:theDate] isEqualToString:[dateFormatter stringFromDate:[NSDate date]]])
{
self.timeWhenLabel.text = NSLocalizedString(#"HomeList-Vandaag", nil);
self.timeWhenAfscheurLabel.text = NSLocalizedString(#"HomeList-Vandaag", nil);
}
else
{
[dateFormatter setDateFormat:#"MM"];
NSString *maand = [dateFormatter stringFromDate:theDate];
NSString *monthName = NSLocalizedString([#"Maand-" stringByAppendingString: maand], nil);
[dateFormatter setDateFormat:#"d"];
NSString *dag = [dateFormatter stringFromDate:theDate];
NSString *DatumString = [[dag stringByAppendingString:#" "]stringByAppendingString:monthName];
self.timeWhenLabel.text = [#" " stringByAppendingString:DatumString];
self.timeWhenAfscheurLabel.text = [#" " stringByAppendingString:DatumString];
}
//De cell vormen of de user gaat of niet
if([event.user_attends_event count] == 0)
{
[self moveView:self.nietAfgescheurdKnop duration:0 curve:UIViewAnimationCurveLinear x:0.0 y:0.0];
[self moveView:self.timeNumberAfscheurLabel duration:0 curve:UIViewAnimationCurveLinear x:0.0 y:0.0];
[self moveView:self.timeWhenAfscheurLabel duration:0 curve:UIViewAnimationCurveLinear x:0.0 y:0.0];
}
else
{
[self moveView:self.nietAfgescheurdKnop duration:0 curve:UIViewAnimationCurveLinear x:50.0 y:0.0];
[self moveView:self.timeNumberAfscheurLabel duration:0 curve:UIViewAnimationCurveLinear x:50.0 y:0.0];
[self moveView:self.timeWhenAfscheurLabel duration:0 curve:UIViewAnimationCurveLinear x:50.0 y:0.0];
}
self.event.userDistance = [locationManager getDistanceBetween:locatie];
if([self.event.userDistance isEqualToString:#"GPS error"])
{
self.distanceNumberLabel.text = NSLocalizedString(#"Extras-GPS", nil);
self.distanceTypeLabel.text = NSLocalizedString(#"Extras-UIT", nil);
self.distanceNumberLabel.textColor = [UIColor grayColor];
self.distanceTypeLabel.textColor = [UIColor grayColor];
}
else
{
NSString *placehold = self.event.userDistance;
placehold = [placehold stringByReplacingOccurrencesOfString:#"." withString:#","];
self.distanceNumberLabel.text = placehold;
self.distanceTypeLabel.text = NSLocalizedString(#"Extras-Km", nil);
self.distanceNumberLabel.textColor = [UIColor blackColor];
self.distanceTypeLabel.textColor = [UIColor blackColor];
}
// Configure the cell...
self.titleLabel.text = resultString;
self.tagsLabel.text = [event getMetadataString];
}
Your evil culprit is NSDateFormatter. This is a super-heavy object to create. You should create a single version of it somewhere and reuse it, setting the properties (formats, time zones, etc.) freely.
It's also a good idea to use Instruments -> Time Profiler to see exactly which methods are taking up time on the main thread.