2014-02-20 6 views
1

Мое приложение слушает некоторые звуковые водяные знаки, и оно отлично работает. Теперь я хотел сделать это приложение очень красивым, используя скрытый вид, в который я помещал ярлык и кнопку. Я рисую вид в Storyboard, затем я помещаю это представление в верхнюю часть контроллера (точно в положение x = 0 и y = -200). Теперь мне нужно показать это представление, когда телефон слышит водяной знак (чтобы распознать водяные знаки, которые я использовал Pitch detector). Я написал следующий код, чтобы распознавать частоту сигнала:Показать скрытый вид в iOS

- (void)frequencyChangedWithValue:(float)newFrequency { 
    frequencyRecived = newFrequency; 
    watermarkReceived = YES; 

    NSLog(@"%f", frequencyRecived); 

    if (frequencyRecived > 18000) { 
     if (frequencyRecived >= 18000 && frequencyRecived <= 18140 && !water1) { 
      [self performSelectorInBackground:@selector(setTextInLabel:) withObject:@"1"]; 
      water2 = water3 = water4 = NO; 
      water1 = YES; 
     } 
     if (frequencyRecived >= 18150 && frequencyRecived <= 18290 && !water2) { 
      [self performSelectorInBackground:@selector(setTextInLabel:) withObject:@"2"]; 
      water1 = water3 = water4 = NO; 
      water2 = YES; 
     } 
     if (frequencyRecived >= 18300 && frequencyRecived <= 18440 && !water3) { 
      [self performSelectorInBackground:@selector(setTextInLabel:) withObject:@"3"]; 
      water1 = water2 = water4 = NO; 
      water3 = YES; 
     } 
     if (frequencyRecived >= 18450 && !water4) { 
      [self performSelectorInBackground:@selector(setTextInLabel:) withObject:@"4"]; 
      water1 = water2 = water3 = NO; 
      water4 = YES; 
     } 
    } else { 
     [self performSelectorInBackground:@selector(redLed) withObject:nil]; 
    } 
} 

и выбирает, являются следующие:

- (void)redLed { 
    [self.imageLed setImage:[UIImage imageNamed:@"image_led_red.png"]]; 
    self.labelPosition.font=[UIFont fontWithName:@"DBLCDTempBlack" size:20.0]; 
} 

- (void)setTextInLabel:(NSString*)position { 
    self.labelPosition.font=[UIFont fontWithName:@"DBLCDTempBlack" size:20.0]; 
    self.labelPosition.text = position; 
    self.labelPositionHiddenView.text = position; 
    NSString *textForToast = [NSString stringWithFormat:@"Postazione %@", position]; 
    [self.view makeToast:textForToast duration:3.0 position:@"bottom"]; 
    [self.imageLed setImage:[UIImage imageNamed:@"image_led_green.png"]]; 
} 

Селектор setTextInLabel вызывается, когда устройство распознает частоту, так что я обновил селектор так:

- (void)setTextInLabel:(NSString*)position { 
    self.labelPosition.font=[UIFont fontWithName:@"DBLCDTempBlack" size:20.0]; 
    self.labelPosition.text = position; 
    self.labelPositionHiddenView.text = position; 
    // Instructions to recall my hide view 
    [UIView transitionWithView:self.view 
         duration:0.5 
         options:UIViewAnimationOptionAllowAnimatedContent 
        animations:^{ 
         [self.viewHidden setFrame:CGRectOffset(self.viewHidden.frame, 0, 340)]; 
        } 
        completion:nil]; 
    //----------------------------- 
    NSString *textForToast = [NSString stringWithFormat:@"Postazione %@", position]; 
    [self.view makeToast:textForToast duration:3.0 position:@"bottom"]; 
    [self.imageLed setImage:[UIImage imageNamed:@"image_led_green.png"]]; 
} 

Когда я пытаюсь запустить приложение и устройство слышит водяной знак его распознать его, он вызывает селектор setTextInLabel, но он не выполняет код для вызова вида. Я не понимаю, почему это так, надеюсь, вы поможете мне решить эту проблему.

ответ

2

Проблема в том, что вы вызываете performSelectorInBackground:, а те методы, которые вы вызываете в фоновом режиме, вносят изменения в элементы UIKit. Все изменения в элементах UIKit должны выполняться в основном потоке. Таким образом, как redLed, так и setTextInLabel: необходимо выполнить на основной нити, а не на фоновом потоке.

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

+0

Я не могу выполнить в основном потоке, потому что, если я выполню этот код в основном потоке, он заблокирует телефон, и приложение сработает ... – lucgian841

+0

@ lucgian841 Вам нужно, чтобы ваш метод 'frequencyChangedWithValue:' выполнялся в фоновом режиме потоком и выполнить обновления своего пользовательского интерфейса в основном потоке. Обновления пользовательского интерфейса не должны задерживаться так долго, что они блокируются. – Gavin

+0

@ lucgian841 Какой поток 'frequencyChangedWithValue:' работает прямо сейчас? – Gavin

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