2013-03-24 2 views
1

Я уже давно работаю над этой проблемой и не могу найти решение, которое работает. Я создаю игру, где каждому игроку присваивается случайное имя. В конце игры, если у одного или нескольких игроков есть баллы, которые квалифицируют их для всех лидеров времени, я хочу пройти через всех игроков, отобразить UIAlertView, где они могут ввести свое настоящее имя, а затем сохранить это имя обратно в мой объект игрока. Тем не менее, я не могу заставить цикл остановиться, показать вид предупреждения, дождаться ответа и продолжить. Кто-нибудь может мне помочь?IOS: Как использовать UIAlertView внутри цикла

Heres мой цикл:

for (int i = 0; i < [leaderboard count]; i++) { 
    NSDictionary *player = [[NSDictionary alloc] initWithDictionary:[leaderboard objectAtIndex:i]]; 
    if ([[player valueForKey:@"isCurrentPlayer"] isEqualToString:@"YES"]){ 
     // getRealPlayerName takes in a name parameter and displays an alertview 
     [self performSelectorOnMainThread:@selector(getRealPlayerName:) withObject:[player valueForKey:@"playerName"] waitUntilDone:YES]; 
     // nameFromAlertView is a local variable that is set when the user enters a name in the alertview. 
     [player setValue:[self nameFromAlertView] forKey:@"playerName"]; 
     [player setValue:@"" forKey:@"isCurrentPlayer"]; 
    } 
} 
+0

Правильно ли я понимаю, что некоторые игроки будут использовать одно устройство? – vikingosegundo

+0

@vikingosegundo, Да, игроки будут использовать те же устройства. – Weston

+0

Вы _can_ делаете это в цикле (с помощью семафора и фоновой очереди), только вы не хотите, поверьте мне. Вы пытаетесь бороться с каркасом, пусть он вам поможет. – magma

ответ

2

вы не можете сделать это в цикле.

вместо сохранения пользователей и точек в массиве вызовите метод, отображающий UIAlertView. получить информацию о первых пользователях из массива и удалить информацию из массива. установите делегат для просмотра предупреждений. один раз, первая информация вводится, вызываются методы делегата UIAlertView (alertView:didDismissWithButtonIndex:). там у обработки введенной информации, чем проверка, если есть еще что-то в массиве, и если да, вызовите первый метод снова


-(void)promptForInput 
{ 
    self.currentUserInfo = userArray[0]; //userarray is mutable, self.currentUserInfo is a property for the current user 
    [userArray removeObject:self.currentUserInfo]; 
    //configure UIAlertView 
    alertView.delegate = self; 

} 


//once the user hit a altertview button, this delegate method gets called 
-(void)alertView:(UIAlertView)alertView didDismissWithButtonIndex:(NSUInteger)idx 
{ 
    //save/process entered data, self.currentUserInfo hold the current user. 

    if([userArray count]> 0){ 
     [self promptForInput]; 
    } 
} 

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

Одним из таких дополнений: Mugunth Kumar — Block Based UIAlertView and UIActionSheet

+1

+1 для кода (я думаю, у нас была примерно такая же идея).Я бы удалил объект в функции делегата, чтобы вы знали текущего пользователя, для которого вызван делегат, но это всего лишь незначительный вопрос вкуса. –

+0

Это основная логика, которую я использовал, и она отлично работала. Очевидно, мне пришлось сделать несколько твиков, которые позволили мне сохранить данные, введенные пользователем. – Weston

1

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

[self performSelectorOnMainThread:@selector(getRealPlayerName:) withObject:[player valueForKey:@"playerName"] waitUntilDone:YES]; 

блокирует отображение вида предупреждения вообще.

Что вы можете сделать, это:

  • Начать уведомление ракурс для первого игрока.
  • В функции делегата alertView:didDismissWithButtonIndex: запишите данные и запустите новое представление предупреждения для следующего игрока (если это не последний игрок).

Вам необходимо будет сохранить текущий индекс игрока в свойстве вашего класса. В качестве альтернативы вы можете присвоить текущему индексу myAlertView.tag.

+0

спасибо за ответ. Я смущен тем, как мне нужно начинать предупреждение для каждого игрока, не используя цикл. – Weston

+0

@Weston: Вы не можете сделать это в цикле. Вы начинаете просмотр предупреждения для первого игрока. Когда это будет завершено (вызывается 'didDismissWithButtonIndex'), вы запускаете представление предупреждения для следующего игрока. –

+0

+1 для того же подхода в ту же минуту. – vikingosegundo

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