2012-03-04 5 views
3

У меня есть приложение IPhone, которое имеет 10 NSTimer функций, которые проверяют каждые 0,5 секунды на просмотр, который прокручивается. Каждый таймер имеет 3 метки, 1 текстовое поле и 1 UIImageView. Все 30 меток, 10 текстовых полей и 10 UIImageViews необходимо прокрутить.
Проблема 1 вид не прокрутки гладкой. Я видел некоторые предложения здесь и попытался тогда без успеха. Когда вы начинаете прокручивать, для начала требуется секунда секунды, затем она скачет примерно на 150 пикселей, а затем начинает прокрутку.
Проблема 2 заключается в том, что при прокрутке текстовые поля и метки не обновляются NSTimer. Когда вы перестаете прокручивать поля, переходите в правильное время. это просто для iPhone для обработки или есть что-то, чего я не хватает?UIScrollView не прокручивается гладко?

Я добавил некоторые из моих «грубых» кодов. Это всего лишь один NSTimer, который проверяет каждые 0,5 секунды. У меня также есть все мои указатели, отпускающие и устанавливающие нуль в viewDidUnload. Даты разные, где у них будет информация о празднике и возможная дополнительная информация, добавленная в массив позже.

Обновление: Я запустил это приложение на своем iPhone 4, и это NOT плавный. Это IS гладкий, однако, в симуляторе 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

+0

Опубликовать код. – jcm

+0

У вас есть две проблемы. Лучше было бы задать два вопроса. Вторая проблема - это точный дубликат http://stackoverflow.com/questions/605027/uiscrollview-pauses-nstimer-until-scrolling-finishes –

ответ

1

хорошо, вероятно, может быть лучше использовать только один таймер и управлять прокруткой внутри него, но лучше (в зависимости от того, что вы пытаетесь сделать) может быть просто использование блока анимации UIView с анимациейWithDuration: анимация: и l и вся тяжелая работа. Какую анимацию вы делаете с UIViews?

0

Я считаю, что первая проблема вызвана выполнением слишком большого количества операций (проверок) в основном потоке. Поскольку все операции пользовательского интерфейса (в вашем случае, прокрутка) также обрабатываются в основном потоке, они вызываются только при завершении других проверок. Это может быть причиной начального заикания, который вы заметили. Вторая проблема, вероятно, связана с тем, как работают NSTimers - они не в режиме реального времени. Даже если время срабатывания таймера прошло, оно будет вызываться только в том случае, если поток, который отвечает за таймер, простаивает. Поэтому только после прекращения прокрутки просмотра будет проверяться таймер.

Вы можете попробовать добавить проверки в другой поток и только вызвать основной поток, чтобы обновить элементы интерфейса, если это необходимо.

+0

Это не является причиной второй проблемы. 'UIScrollView' явно отключает таймеры, которые не были настроены для запуска при отслеживании прокрутки. http://stackoverflow.com/a/9091524/77567 –

Смежные вопросы