我有一个iPhone应用程序,它有10个NSTimer
个函数,可以在滚动的视图上每隔0.5秒检查一次。每个计时器有3个标签,1个文本字段和1个UIImageView
。所有30个标签,10个文本字段和10个UIImageViews
都需要滚动
问题1 是视图滚动不流畅。我在这里看到了一些建议,然后尝试了没有成功。当你开始滚动时,它需要一瞬间开始,然后它跳跃大约150个像素然后它开始滚动。
问题2 是在滚动时,NSTimer不会更新文本字段和标签。当您停止滚动时,字段会跳转到正确的时间。这对于iPhone来说还是要处理的还是我缺少的东西?
我添加了一些“粗鲁”的代码。这只是一个每0.5秒检查一次的NSTimer。我也发布了所有指针,并在viewDidUnload中设置为nil。日期不同,他们将在假日信息中添加假日信息,并在以后的数组中添加更多信息。
更新:我在iPhone 4上运行了这个应用程序,它不顺利。然而,在iPhone模拟器中 IS 平滑。
-(void)updateUSDTimer {
NSMutableArray *usdMarketHours = [[NSMutableArray alloc] init];
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"2", @"29", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:0];// open WED
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"2", @"29", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:1];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"1", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:2];// open THU
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"1", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:3];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"2", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:4];// open FRI
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"2", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:5];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"5", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:6];// open MON
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"5", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:7];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"6", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:8];// open TUE
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"6", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:9];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"7", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:10];// open WED
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"7", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:11];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"8", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:12];// open THU
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"8", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:13];// close
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"9", @"8", @"00", @"00", @"EST", @"Holiday list", nil ] atIndex:14];// open FRI
[usdMarketHours insertObject:[NSArray arrayWithObjects:@"2012", @"3", @"9", @"17", @"00", @"00", @"EST", @"", nil ] atIndex:15];// close
int USDarrayLength = [usdMarketHours count];
int index0USD = 0;
int index1USD = 1;
int index2USD = 2;
int u = 0;
// ---------------------------------------------- START FOR LOOP ---------------------------------------------------------->
for (u=0; u<USDarrayLength; u++) {
NSDate *USDnow = [NSDate date];
// ------------------------------------------------------->
// Convert to timeA
NSString *USDyear = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:0];
NSString *USDmonth = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:1];
NSString *USDday = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:2];
NSString *USDhour = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:3];
NSString *USDminute = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:4];
NSString *USDsecond = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:5];
NSString *USDtimeZone = [[usdMarketHours objectAtIndex:index0USD] objectAtIndex:6];
NSDateComponents *USDcompA = [[NSDateComponents alloc] init];
[USDcompA setYear:[USDyear intValue]];
[USDcompA setMonth:[USDmonth intValue]];
[USDcompA setDay:[USDday intValue]];
[USDcompA setHour:[USDhour intValue]];
[USDcompA setMinute:[USDminute intValue]];
[USDcompA setSecond:[USDsecond intValue]];
[USDcompA setTimeZone:[NSTimeZone timeZoneWithAbbreviation:[NSString stringWithFormat:@"%@", USDtimeZone]]];
USDcal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
USDtimeADate = [USDcal dateFromComponents:USDcompA];
// Using NSDateFormatter pointers, set format for array[]/GMT/Local times.
// timeAFormatter for array date
[USDtimeAFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeAFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:USDtimeZone]]; // Array Time Zone
[USDtimeAFormatterGMT setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeAFormatterGMT setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; // String "GMT"
[USDtimeAFormatterLocal setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeAFormatterLocal setTimeZone:[NSTimeZone localTimeZone]]; // Local time
// ------------------------------------------------------->
// Convert to timeB
NSString *USDyearb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:0];
NSString *USDmonthb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:1];
NSString *USDdayb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:2];
NSString *USDhourb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:3];
NSString *USDminuteb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:4];
NSString *USDsecondb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:5];
NSString *USDtimeZoneb = [[usdMarketHours objectAtIndex:index1USD] objectAtIndex:6];
NSDateComponents *USDcompB = [[NSDateComponents alloc] init];
[USDcompB setYear:[USDyearb intValue]];
[USDcompB setMonth:[USDmonthb intValue]];
[USDcompB setDay:[USDdayb intValue]];
[USDcompB setHour:[USDhourb intValue]];
[USDcompB setMinute:[USDminuteb intValue]];
[USDcompB setSecond:[USDsecondb intValue]];
[USDcompB setTimeZone:[NSTimeZone timeZoneWithAbbreviation:[NSString stringWithFormat:@"%@", USDtimeZoneb]]];
USDcalb = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
USDtimeBDate = [USDcalb dateFromComponents:USDcompB];
[USDtimeBFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeBFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:USDtimeZoneb]]; // Array Time Zone
[USDtimeBFormatterGMT setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeBFormatterGMT setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; // String "GMT"
[USDtimeBFormatterLocal setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeBFormatterLocal setTimeZone:[NSTimeZone localTimeZone]]; // String "GMT"
// ----------------------------------------------------------------------------------->
// Convert to timeC
NSString *USDyearc = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:0];
NSString *USDmonthc = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:1];
NSString *USDdayc = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:2];
NSString *USDhourc = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:3];
NSString *USDminutec = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:4];
NSString *USDsecondc = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:5];
NSString *USDtimeZonec = [[usdMarketHours objectAtIndex:index2USD] objectAtIndex:6];
NSDateComponents *USDcompC = [[NSDateComponents alloc] init];
[USDcompC setYear:[USDyearc intValue]];
[USDcompC setMonth:[USDmonthc intValue]];
[USDcompC setDay:[USDdayc intValue]];
[USDcompC setHour:[USDhourc intValue]];
[USDcompC setMinute:[USDminutec intValue]];
[USDcompC setSecond:[USDsecondc intValue]];
[USDcompC setTimeZone:[NSTimeZone timeZoneWithAbbreviation:[NSString stringWithFormat:@"%@", USDtimeZonec]]];
USDcalc = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
USDtimeCDate = [USDcalb dateFromComponents:USDcompC];
[USDtimeCFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeCFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:USDtimeZonec]]; // Array Time Zone
[USDtimeCFormatterGMT setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeCFormatterGMT setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; // String "GMT"
[USDtimeCFormatterLocal setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
[USDtimeCFormatterLocal setTimeZone:[NSTimeZone localTimeZone]]; // String "GMT"
// ------------------------------------------------------------------------------------>
// create doubles, from timeIntervalSince1970. ex: 12345678945613.13489
double timeAInterval = [USDtimeADate timeIntervalSince1970];
double timeNowInterval = [USDnow timeIntervalSince1970];
double timeBInterval = [USDtimeBDate timeIntervalSince1970];
//double timeCInterval = [timeCDate timeIntervalSince1970];
// mathA = this is how long the market is open/closed. the before time.
// timeAInterval = array date before present time
// timeNowInterval = date of present time
// timeBInterval = array date of after present time
// timeCInterval = array date of 2nd after present time
// ------------------------------------------------------------------------------------>
// if statement to find the correct array dates
if((timeAInterval < timeNowInterval) && (timeBInterval > timeNowInterval))
{
// ------------------------------------------------------------------------------------>
// Even index(i) are OPEN times, Odd index are CLOSED times.
NSString *USDindex0Prefix = @"";
NSString *USDindex1Prefix = @"";
if(index0USD % 2 ==0)
{
// Market is presently -------------------> OPEN
// NSLog(@"%i is even number", index0);
//NSLog(@"MARKET IS OPEN");
USDindex0Prefix = @"Closes : ";
USDindex1Prefix = @"Opens : ";
USDremainPrefix = @"Closes in: ";
UIImage *image = [UIImage imageNamed:@"USD_flag.png"];
[USDlightOpenOrClose setImage:image];
}else{
// Market is presently -------------------> CLOSED
//NSLog(@"%i is odd number", index0);
//NSLog(@"MARKET IS CLOSED");
USDindex1Prefix = @"Closes : ";
USDindex0Prefix = @"Opens : ";
USDremainPrefix = @"Opens in: ";
UIImage *image = [UIImage imageNamed:@"USD_flag_BW.png"];
[USDlightOpenOrClose setImage:image];
}
// ------------------------------------------------------------------------------------>
// Math to seperate hour, minutes, seconds
NSTimeInterval elapsedTime = [USDtimeBDate timeIntervalSinceNow];
div_t h = div(elapsedTime, 3600);
int hours = h.quot;
div_t m = div(h.rem, 60);
int minutes = m.quot;
int seconds = m.rem;
// Remove negative sign if neg number. If not, do nothing: hours, minutes, seconds are int
if(hours<0){
hours = hours * -1;
}
if(minutes<0){
minutes = minutes * -1;
}
if(seconds<0){
seconds = seconds * -1;
}
// Formats the UITextField remaining time.
if(hours <= 0){// hours less than or equal to 0
USDRemainTime.text = [NSString stringWithFormat:@"%@ %.2dm %.2ds", USDremainPrefix,minutes, seconds];
USDRemainTime.textColor = [UIColor blackColor];
USDRemainTime.font = [UIFont systemFontOfSize:14];
}
if(hours > 0){// hours more than 0
USDRemainTime.text = [NSString stringWithFormat:@"%@ %dh %.2dm ", USDremainPrefix,hours, minutes];
USDRemainTime.textColor = [UIColor blackColor];
USDRemainTime.font = [UIFont systemFontOfSize:14];
}
if((hours >= 1) && (hours < 10)){// hours between 1hr and 10hr
USDRemainTime.text = [NSString stringWithFormat:@"%@ %.1dh %.2dm", USDremainPrefix ,hours, minutes];
USDRemainTime.textColor = [UIColor blackColor];
USDRemainTime.font = [UIFont systemFontOfSize:14];
}
if((hours <= 0) && (minutes < 5)){// less than 5 min
// Less than 5 min, turn text red.
USDRemainTime.text = [NSString stringWithFormat:@"%@ %.2dm %.2ds", USDremainPrefix, minutes, seconds];
USDRemainTime.textColor = [UIColor redColor];
USDRemainTime.font = [UIFont boldSystemFontOfSize:16];
}
// ------------------------------------------------------------------------------------>
// Format timeA and timeB with NSDateFormatter. Use in text fields and labels
NSDateFormatter *USDtimeAFormatted = [[NSDateFormatter alloc] init];
[USDtimeAFormatted setDateFormat:@"EEE. MMM. dd, yyyy HH:mm:ss z"];
NSDateFormatter *USDtimeNoSeconds = [[NSDateFormatter alloc] init];
[USDtimeNoSeconds setDateFormat:@"EEE. MMM. dd, yyyy HH:mm z"];
// This sets the Open/Close labels to Country time(array time), GMT time, or local time
// 0 = Country timezone (array timezone)
// 1 = GMT timezone
// 2 = local timezone
int desiredFormat = 0;
if(desiredFormat == 0){
[USDtimeAFormatted setTimeZone:[NSTimeZone timeZoneWithAbbreviation:USDtimeZoneb]];
NSString *USDfinalRemainb = [USDtimeAFormatted stringFromDate:USDtimeBDate];
USDStartTime.text = [NSString stringWithFormat:@"%@ %@", USDindex0Prefix, USDfinalRemainb];
[USDtimeAFormatted setTimeZone:[NSTimeZone timeZoneWithAbbreviation:USDtimeZonec]];
NSString *USDfinalRemainc = [USDtimeAFormatted stringFromDate:USDtimeCDate];
USDCloseTime.text = [NSString stringWithFormat:@"%@ %@", USDindex1Prefix, USDfinalRemainc];
//[USDtimeNoSeconds setTimeZone:[NSTimeZone localTimeZone]];
[USDtimeNoSeconds setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EST"]];
NSString *USDNowTime = [USDtimeNoSeconds stringFromDate:USDnow];
USDPresentTime.text = [NSString stringWithFormat:@"Present Time: %@", USDNowTime];
}
if(desiredFormat == 1){
[USDtimeAFormatted setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
NSString *USDfinalRemainb = [USDtimeAFormatted stringFromDate:USDtimeBDate];
USDStartTime.text = [NSString stringWithFormat:@"%@ %@", USDindex0Prefix, USDfinalRemainb];
[USDtimeAFormatted setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
NSString *USDfinalRemainc = [USDtimeAFormatted stringFromDate:USDtimeCDate];
USDCloseTime.text = [NSString stringWithFormat:@"%@ %@", USDindex1Prefix, USDfinalRemainc];
[USDtimeAFormatted setTimeZone:[NSTimeZone localTimeZone]];
NSString *USDNowTime = [USDtimeAFormatted stringFromDate:USDnow];
USDPresentTime.text = [NSString stringWithFormat:@"Present Time: %@", USDNowTime];
}
if(desiredFormat == 2){
[USDtimeAFormatted setTimeZone:[NSTimeZone localTimeZone]];
NSString *USDfinalRemainb = [USDtimeAFormatted stringFromDate:USDtimeBDate];
USDStartTime.text = [NSString stringWithFormat:@"%@ %@", USDindex0Prefix, USDfinalRemainb];
[USDtimeAFormatted setTimeZone:[NSTimeZone localTimeZone]];
NSString *USDfinalRemainc = [USDtimeAFormatted stringFromDate:USDtimeCDate];
USDCloseTime.text = [NSString stringWithFormat:@"%@ %@", USDindex1Prefix, USDfinalRemainc];
[USDtimeAFormatted setTimeZone:[NSTimeZone localTimeZone]];
NSString *USDNowTime = [USDtimeAFormatted stringFromDate:USDnow];
USDPresentTime.text = [NSString stringWithFormat:@"Present Time: %@", USDNowTime];
}
// ------------------------------------------------------------------------------------>
// disables the textField from a user interaction
USDRemainTime.enabled = NO;
[USDRemainTime setUserInteractionEnabled:NO];
}else{
index0USD++;
index1USD++;
index2USD++;
// if incremented that means that we must check the next array to see if the present date is between two arrays
}
}
}
- (void)viewDidLoad
{
forexTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateForexTimer) userInfo:nil repeats:YES];
USDTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateUSDTimer) userInfo:nil repeats:YES];
[self.scrollView addSubview:self.contentView];
self.scrollView.contentSize = self.contentView.bounds.size;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
答案 0 :(得分:1)
答案 1 :(得分:0)
我认为第一个问题是由主线程上的操作(检查)过多引起的。由于所有UI操作(在您的情况下,滚动)也在主线程上处理,因此只有在其他检查完成时才会调用它们。这可能是您注意到的最初口吃的原因。 第二个问题可能是由于NSTimers的工作方式 - 它们不是实时的。即使定时器的触发时间已经过去,只有在负责定时器的线程空闲时才会调用它。因此,只有在视图停止滚动后才会检查计时器。
您可以尝试在不同的线程中添加检查,并且只在必要时调用主线程来更新UI元素。