Поваренная книга для разработчиков iPhone: ModalAlert Frozen - PullRequest
0 голосов
/ 01 марта 2010

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

+(NSString *) textQueryWith: (NSString *)question prompt: (NSString *)prompt button1: (NSString *)button1 button2:(NSString *) button2
{
    // Create alert
    CFRunLoopRef currentLoop = CFRunLoopGetCurrent();
    ModalAlertDelegate *madelegate = [[ModalAlertDelegate alloc] initWithRunLoop:currentLoop];
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:question message:@"\n" delegate:madelegate cancelButtonTitle:button1 otherButtonTitles:button2, nil];

    // Build text field
    UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 260.0f, 30.0f)];
    tf.borderStyle = UITextBorderStyleRoundedRect;
    tf.tag = TEXT_FIELD_TAG;
    tf.placeholder = prompt;
    tf.clearButtonMode = UITextFieldViewModeWhileEditing;
    tf.keyboardType = UIKeyboardTypeAlphabet;
    tf.keyboardAppearance = UIKeyboardAppearanceAlert;
    tf.autocapitalizationType = UITextAutocapitalizationTypeWords;
    tf.autocorrectionType = UITextAutocorrectionTypeNo;
    tf.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

    // Show alert and wait for it to finish displaying
    [alertView show];
    while (CGRectEqualToRect(alertView.bounds, CGRectZero));

    // Find the center for the text field and add it
    CGRect bounds = alertView.bounds;
    tf.center = CGPointMake(bounds.size.width / 2.0f, bounds.size.height / 2.0f - 10.0f);
    [alertView addSubview:tf];
    [tf release];

    // Set the field to first responder and move it into place
    [madelegate performSelector:@selector(moveAlert:) withObject:alertView afterDelay: 0.7f];

    // Start the run loop
    CFRunLoopRun();

    // Retrieve the user choices
    NSUInteger index = madelegate.index;
    NSString *answer = [[madelegate.text copy] autorelease];
    if (index == 0) answer = nil; // assumes cancel in position 0

    [alertView release];
    [madelegate release];
    return answer;
}

Спасибо! * * 1004

Ответы [ 3 ]

0 голосов
/ 08 декабря 2010
// Put the modal alert inside a new thread.  This happened to me before, and this is how i fixed it.

- (void)SomeMethod {
[NSThread detachNewThreadSelector:@selector(CheckCurrentPuzzle) toTarget:self withObject:nil]; }

-(void) CheckCurrentPuzzle {

NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];

// code that should be run in the new thread goes here


if ([gameBoard AreAllCellsFilled]) {

    if ([gameBoard FilledWithoutWin]) {

        //only show this message once per puzzle
        if (![currentPuzzle showedRemovalMessage]) {

            NSArray *buttons = [NSArray arrayWithObject:@"Yes"];

            if ([ModalAlert ask:@"blah blah blah" withTitle:@"Incomplete Puzzle" withCancel:@"No" withButtons:buttons] == 1) {
                NSLog(@"Remove The Incorrect Cells");

                [gameBoard RemoveIncorrect];

            } else {
                [gameSounds.bloop2 play];
            }               
        }

    } else {

        if ([gameBoard IsBoardComplete]) {
            [self performSelectorOnMainThread:@selector(WINNER) withObject:nil waitUntilDone:false]; 
        }
    }

}

    [pool2 release]; 
}

-(void) WINNER {

    //ladies and gentleman we have a winner

}
0 голосов
/ 23 ноября 2011

У меня была проблема, подобная этой в моей образовательной игре QPlus. Меня это беспокоило, потому что у меня был «один и тот же» код в двух связанных приложениях, а у них не было ошибки. Оказалось, что ошибка была в том, что метод селектора не был объявлен в заголовочном файле. Я работаю в Xcode 4.2.

Подробности ниже:

В .м:

tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(emailLabelPressed)];
tapRecognizer.numberOfTapsRequired = 1;
[aLabel addGestureRecognizer:tapRecognizer];
[aLabel setUserInteractionEnabled:YES];

А потом в .m:

  • (void) emailLabelPressed { //подробности }

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

Затем добавьте это в файл .h:

  • (пустот) emailLabelPressed;

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

Исходя из этого, вы можете убедиться, что ваш метод селектора moveAlert: объявлен в вашем заголовочном файле.

Наслаждайтесь

Дэмиен

0 голосов
/ 01 марта 2010

Вам, вероятно, следует проверить, имеет ли свойство UITextField userInteractionEnabled значение по умолчанию YES или NO.

...