2011-12-13 4 views
0

Я играю с простым тестовым приложением, которое просто проецирует 10 изображений и отображает каждый из них. Следующее изображение будет отображаться после нажатия пользователем кнопки. Проблема, с которой я столкнулась, - это представление никогда не появляется (изображение или кнопка). Когда я вынимаю кнопку пресса, код запускается и отображается последнее изображение. beginRunningScript изначально ДА.Только последнее изображение, отображаемое на iPhone

@interface ViewController : UIViewController <UIAlertViewDelegate> 
{ 
    BOOL continueRunningScript; 
    UIButton *wrongButton; 
    UIImageView *imageView; 
} 

// ... 

@end 

@implementation ViewController 

// ... 

- (void) xxx { 

    for (int i = 0; i<10; i++) { 

     while (continueRunningScript == NO) { 
      // Stay here until button is pressed. 
     } 

     UIImage *testImg = ... // code to load the image at index i 

     imageView = [[UIImageView alloc] initWithImage: testImg]; 

     [self.view addSubview:imageView]; 

     wrongButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     [wrongButton addTarget:self 
         action:@selector(incorrectResultButtonPress:) 
       forControlEvents:UIControlEventTouchUpInside]; 
     [wrongButton setTitle:@"Wrong Result?" forState:UIControlStateNormal]; 
     wrongButton.frame = CGRectMake(80.0, 310.0, 160.0, 40.0); 
     [self.view addSubview:wrongButton]; 

     continueRunningScript = NO; 

     [testImg release]; 
    } 
    [imageView release]; 
    [wrongButton release]; 
} 

// button press handling... 

// UIAlertViewDelegate 
- (void) alertView: (UIAlertView *)actionSheet clickedButtonAtIndex: (NSInteger)buttonIndex { 

    // The user clicked one of the Yes/No buttons 
    if (buttonIndex == 0) // Yes 
    { 
     UIAlertView *thankyouAlert = [[UIAlertView alloc] initWithTitle:@"Thank You" 
                   message:@"Thanks for the feedback!" 
                   delegate:self 
                 cancelButtonTitle:nil 
                 otherButtonTitles:nil]; 
     [thankyouAlert show]; 
     // Call performSelector delegate method of NSObject to call class method dismissAlertView 
     [self performSelector:@selector(dismissAlertView:) withObject:thankyouAlert afterDelay:2]; 
     [thankyouAlert release]; 
     [wrongButton removeFromSuperview]; 
     continueRunningScript = YES; 
    } 
} 

// ... 

@end 
+0

Это потому, что вы переназначаете одну и ту же ссылку «imageView» в цикле. Когда вы закончите цикл, он всегда укажет на последний объект. – Joe

+0

В будущем перед отправкой, пожалуйста, проверьте форматирование кода, я исправил его для вас сейчас. –

+0

Но почему на первой итерации цикла, когда i = 0, ничего не отображается на экране? –

ответ

1

Я исхожу из предположения, что вы не делаете этого на фоне нити или чего-то еще. Если да, то вы должны знать, что UIKit предназначен только для использования в основном потоке.

while (continueRunningScript == NO) { 
    // Stay here until button is pressed. 
} 

Это не будет работать так, как вы этого хотите. Он войдет в бесконечный цикл. Нить выполнения не будет проходить через этот момент, чтобы обрабатывать любые входные события, поэтому переменная никогда не получит возможность установить значение YES.

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

Если вы хотите, чтобы каждое изображение отображалось, каждый раз, когда пользователь нажимает кнопку, вы должны иметь переменную экземпляра, которая отслеживает, какое изображение является текущим, и написать метод для обновления этой переменной и показать следующее изображение. Почти во всех случаях цикл занятости, подобный приведенному выше, неверен.

Кроме того, вы должны знать, что вам не нужно добавлять новый UIImageView каждый раз, когда вы хотите отображать новое изображение. Вы можете просто обновить свойство image для просмотра существующего изображения, чтобы изменить отображаемое изображение.

+0

Спасибо, Джим. Мне, конечно, придется переосмыслить, как это сделать. Другой вопрос: почему даже когда я перехожу через код в отладчике на первой итерации цикла, когда он попадает в строки, которые добавляют изображение и кнопку в представление, ничего не появляется? –

+0

Поскольку iOS не будет обновлять дисплей до тех пор, пока ваша функция не вернется. – Jim

0

Я не думаю, что вам нужно освободить изображениеView или wrongButton. Вероятно, они хотят быть сохранены до тех пор, пока существует контроллер.

Помимо этого предположения, я бы предложил нам больше информации.

1

Используется ли метод «xxx» в основном потоке? Если да, то преступник:

while (continueRunningScript == NO) { 
     // Stay here until button is pressed. 
    } 

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

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

+0

Спасибо. Поэтому я понимаю, почему это было проблемой после первой итерации цикла. Но я до сих пор не понимаю, почему изображение и кнопка не отображаются на первой итерации при i = 0 (прежде чем она когда-либо застревает в цикле while). –

+0

Вид и кнопка не отображаются сразу же, когда вы вызываете 'addSubview'. Пользовательский интерфейс обновляется полностью после того, как метод 'xxx' возвращает (что никогда не будет) в какой-то момент следующей итерации цикла цикла. –

0

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

События также обнаруживаются/отправляются в основном цикле выполнения пользовательского интерфейса. Поскольку ваш код никогда не возвращается из первого обработчика кнопок, никакие последующие события кнопок не будут обнаружены.

+0

Спасибо. Что такое основной цикл запуска пользовательского интерфейса? viewDidLoad? –

+0

Возвратитесь из всего кода вашего приложения, и это то, что использует среда ОС, UIKit и Objective C для последующего вызова вашего приложения ... или ведения домашнего хозяйства, такого как отображение и ввод. например это то, что вызывает viewDidLoad. Вернитесь, чтобы вернуться к нему. – hotpaw2

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