2012-03-04 181 views
3

我有一個IPhone應用程序,它有10個NSTimer函數,用於檢查滾動視圖上的每個.5秒。每個計時器有3個標籤,1個文本字段和1個UIImageView。需要滾動所有30個標籤,10個文本字段和10個UIImageViews
問題1是視圖不滾動平滑。我在這裏看到了一些建議,然後試圖沒有成功。當你開始滾動時,它需要一秒開始,然後它跳躍大約150像素,然後開始滾動。
問題2是當它滾動時,文本字段和標籤不會被NSTimer更新。當您停止滾動時,字段跳轉到正確的時間。這僅僅是爲了iPhone的處理還是有我缺少的東西?UIScrollView不滾動平滑?

我添加了一些「粗魯」的代碼。這只是一個每0.5秒檢查一次的NSTimer。我也將所有的指針釋放並在viewDidUnload中設置爲零。日期是不同的,他們將有假日信息和可能的更多信息在日後添加到數組中。

更新:我已經在我的iPhone 4上運行這個應用程序,它是不是光滑。它在iPhone模擬器中卻可以流暢地運行。

-(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

您是否嘗試對設備上的應用程序進行分析? – dasblinkenlight 2012-03-04 16:43:50

+0

發表一些代碼。 – jcm 2012-03-04 17:09:28

+0

你有兩個問題。發佈兩個問題會更好。你的第二個問題是一個確切的重複http://stackoverflow.com/questions/605027/uiscrollview-pauses-nstimer-until-scrolling-finishes – 2012-03-04 18:09:59

回答

1

好,可能是它可能是更好只使用1個定時器和管理它裏面的所有滾動,但更好方式(取決於你試圖做什麼)可能只是用animateWithDuration使用UIView動畫塊:動畫:和l等待所有的辛勤工作。 你在用UIViews做什麼樣的動畫?

0

我認爲第一個問題是由於在主線程上執行了太多操作(檢查)而造成的。由於所有UI操作(在你的情況下,滾動)也在主線程上處理,所以只有在其他檢查完成時纔會調用它們。這可能是您注意到初始口吃的原因。 第二個問題可能是由於NSTimers的工作方式 - 它們不是實時的。即使定時器的觸發時間已過,只有在負責定時器的線程空閒時纔會調用它。所以只有當視圖停止滾動時纔會檢查定時器。

您可以嘗試在不同的線程中添加檢查,並且只在必要時調用主線程來更新UI元素。

+0

這不是第二個問題的原因。 'UIScrollView'明確地禁用了當滾動視圖正在跟蹤時沒有設置爲觸發的定時器。 http://stackoverflow.com/a/9091524/77567 – 2012-03-04 18:21:57