iPhone NSTimer работает по одному методу - PullRequest
0 голосов
/ 21 января 2012

Я новичок в программировании для iPhone, и у меня возникла проблема с этой функцией

-(IBAction)changeX {
    [self timere:field1];
    [self timere:field2];
}

это кнопка для перемещения объекта поля uitextfield по экрану.Проблема в том, что я хочу запустить этот метод в первом поле, заполнить его и перейти ко второму.Функция timere использует NSTimer для непрерывного перемещения объекта, пока он не достигнет определенной точки, в которой он заканчивается.У меня есть две другие функции, показанные ниже.Реальная программа, которую я делаю, намного длиннее, но цель та же, а этот код слишком длинный.Проблема заключается в запуске первой функции, а затем второй.Спасибо за помощь.

-(void)timere:(UITextField*)f1 {

    UITextField*fielder1=f1;
    NSInvocation*timerInvocation = [NSInvocation invocationWithMethodSignature:
                                [self methodSignatureForSelector:@selector(moveP:)]];


    [timerInvocation setSelector:@selector(moveP:)];
    [timerInvocation setTarget:self];
    [timerInvocation setArgument:&fielder1 atIndex:2];   

    timer1 = [NSTimer scheduledTimerWithTimeInterval:0.03 invocation:timerInvocation repeats:YES];
}


-(void) moveP:(UITextField*)f1 {

    UITextField*fielder1=f1;
    fielder1.center = CGPointMake(fielder1.center.x+4, fielder1.center.y);
    if (fielder1.center.x>237) {
        [timer1 invalidate];
    }

}

1 Ответ

1 голос
/ 21 января 2012

Стандартизированный метод анимации объектов UIView заключается в использовании следующих методов:

+ animateWithDuration: задержка: параметры: анимации: завершение:

синтаксисэти методы могут быть немного пугающими, если вы не знакомы с Objective-C Blocks .Вот пример использования, который перемещает первое поле, а затем второе поле.

[UIView animateWithDuration:0.3 animations:^{
  [field1 setCenter:CGPointMake(FINAL_CENTER_X1, FINAL_CENTER_Y1)];
} completion:^(BOOL finished) {
  [UIView animateWithDuration:0.3 animations:^{
    [field2 setCenter:CGPointMake(FINAL_CENTER_X2, FINAL_CENTER_Y2)];
  }];
}];

РЕДАКТИРОВАТЬ: Для общего решения вашей конкретной проблемы, я бы сделал следующие изменения:

-(IBAction)changeX {
    [self timere:field1];
}

-(void) moveP:(UITextField*)f1 {

    UITextField*fielder1=f1;
    fielder1.center = CGPointMake(fielder1.center.x+4, fielder1.center.y);
    if (fielder1.center.x>237) {
        [timer1 invalidate];
        // I'm really not sure about the scope of field1 and field2, but
        // you can figure out the encapsulation issues
        if (f1 == field1) {
            [self timere:field2];
        }
    }

}

Более общим и действительно низкоуровневым решением было бы иметь переменную состояния.Возможно, у вас есть что-то вроде NSArray *fields из UITextField * и int state = 0.Там, где я добавил условное выражение в moveP выше, вы наберете state++ и позвоните [self timere:[fields objectAtIndex:state]], если state < [fields count].В любом случае, ваш код аннулирования таймера правильный.

...