UIScrollView не прокручивается плавно? - PullRequest
3 голосов
/ 04 марта 2012

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

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

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

}

Ответы [ 2 ]

1 голос
/ 04 марта 2012

ну, возможно, может быть лучше использовать всего 1 таймер и управлять всей прокруткой внутри него, но лучшим способом (в зависимости от того, что вы пытаетесь сделать) может быть просто использование блока анимации UIView с animateWithDuration: animations: ипусть вся тяжелая работа для этого.какие виды анимации вы делаете с вашими UIViews?

0 голосов
/ 04 марта 2012

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

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

...