无法在iOS7上将UITextField添加到UIAlertView中...在iOS6中可以正常工作

64
下面的代码可以在iOS6(及之前版本)上工作,但UITextField在iOS7中无法显示......有什么办法可以让一个UITextField在iOS7的UIAlterView中显示出来吗?
UIAlertView* dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:@"Enter ESC Score"];
[dialog setMessage:@" "];
[dialog addButtonWithTitle:@"Cancel"];
[dialog addButtonWithTitle:@"OK"];
dialog.tag = 5;

nameField = [[UITextField alloc] initWithFrame:CGRectMake(20.0, 45.0, 245.0, 25.0)];
[nameField setKeyboardType:UIKeyboardTypeNumberPad];
[nameField becomeFirstResponder];
[nameField setBackgroundColor:[UIColor whiteColor]];
[dialog addSubview:nameField];
CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0.0, 0.0);
[dialog setTransform: moveUp];
[dialog show];
[dialog release];

[nameField release];

iOS6下运行的代码显示如下:

enter image description here

iOS7中相同的代码显示为这样(请注意UITextField缺失和没有键盘):

enter image description here


1
iOS7仍处于_beta_阶段,你到底期望什么? - holex
31
如果苹果公司计划在九月中旬发布iOS7的话,我希望能够与一群才华横溢、聪明并且志同道合的开发者共同合作,这样我们的应用程序就不会无法使用了。看起来有些傻,苹果不指望任何人谈论如何积极地让他们的用户感到满意。所以我们要假装iOS7不存在直到它正式发布吗?非揭秘协议很重要,但这似乎有些愚蠢...而且更愚蠢的是有人花时间去查找IOS7问题并打分。仅此而已。 - iTrout
2
苹果提供了一个讨论iOS7的论坛,其中可以讨论受限API。在这里讨论未发布的、可能不起作用的软件对他人来说并没有太大的用处,除非非常明确地标记版本号。 - marko
1
令人难以置信,为了iOS 7还不得不安装全新的OSX,真是令人难以置信! - colin lamarre
14
猜猜这个问题已经进入了iOS 7的公开版本,我们的应用在这方面也出现了故障。任何使用了这种技术的应用程序(实际上并不罕见)都会出现故障。很抱歉,但回答“受NDA保护,对其他人没有用处”是完全错误的方法来维护一个应该互相帮助解决实际问题的富有成效的社区,而这个问题绝对是实际存在的。无论是测试版还是正式版,这些问题都存在 - 所以请积极建设性地解决问题,而不是轻描淡写地不为问题增添任何价值。 - Marchy
显示剩余3条评论
7个回答

178

在iOS 7中,您无法轻易改变UIAlertView的视图层次结构。(也不应该这样做;文档明确告诉您不要这么做。)请访问开发者论坛以查看有关此问题的长期讨论。

在您的情况下,一种替代方案是设置alert.alertViewStyle = UIAlertViewStylePlainTextInput;。这将为您添加一个文本字段。您可以通过使用UITextField *textField = [alertView textFieldAtIndex:0];在UIAlertView委托回调中访问它。


2
这对于单个文本字段很好用。如果我想要在UIAlertview中添加两个文本字段,那么解决方案是什么? - loganathan
9
如果您不想遮挡第二个文本框,可以设置[alertView textFieldAtIndex:1].secureTextEntry = NO。如果需要更复杂的功能,请创建自己的视图。@loganathan 的内容需要翻译为:UIAlertViewStyleLoginAndPasswordInput。 - Aaron Brager
@AaronBrager,但它会通过苹果的应用审核吗? - Roy K
3个文本框怎么样?我们用它来实现密码重置功能:“当前密码,新密码,再次输入新密码”。 - Marchy
@Marchy 不好意思,你需要自己制作视图或使用第三方替代品。https://github.com/wimagguc/ios-custom-alertview和https://github.com/mindbrix/TSAlertView是我所知道的最好的两个选项,可以满足你的需求。 - Aaron Brager

17

@Aaron Brager 的解决方案正确。此外,我在他的建议后添加了一行代码来设置数字键盘的默认值。

UIAlertView* dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:@"Enter ESC Score"];
[dialog setMessage:@" "];
[dialog addButtonWithTitle:@"Cancel"];
[dialog addButtonWithTitle:@"OK"];
dialog.tag = 5;

dialog.alertViewStyle = UIAlertViewStylePlainTextInput;
[dialog textFieldAtIndex:0].keyboardType = UIKeyboardTypeNumberPad;

CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0.0, 0.0);
[dialog setTransform: moveUp];
[dialog show];
[dialog release];

1
遵循@Aaron Brager的建议并改变警报配置方式......就像iTrout所做的那样,这对我起了作用!感谢你们两个!!! - Marc Watson

6
UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:@"Credit Card Number"
                                  message:@"Please enter your credit card number:"
                                  delegate:self
                                  cancelButtonTitle:@"Cancel"
                                  otherButtonTitles:@"Ok", nil];
        [alertView setAlertViewStyle:UIAlertViewStylePlainTextInput];
        /* Display a numerical keypad for this text field */
        UITextField *textField = [alertView textFieldAtIndex:0];
        textField.keyboardType = UIKeyboardTypeNumberPad;

[alertView show];

1

工作得非常好

在所有版本的iOS中为UIAlertView添加两个UITextField

-(IBAction) showAlertView {

    UIAlertView *alert;  
    UITextField *callForwardNumber;
    UItextField *callForwardCondition;

    alert = [[UIAlertView alloc] initWithTitle:@"Enter Phone Number & Rule"
                                   message:@""
                                  delegate:self
                         cancelButtonTitle:@"Cancel"
                         otherButtonTitles:@"Save", nil];

    //alert.transform = CGAffineTransformMakeTranslation(0, 110);

    callForwardNumber = [[UITextField alloc] init];
    callForwardNumber.keyboardType = UIKeyboardTypeNumberPad;
    callForwardNumber.text = [R.prefs objectForKey:@"fwd_number"];
    callForwardNumber.borderStyle = UITextBorderStyleRoundedRect;
    callForwardNumber.delegate = self;
    callForwardNumber.tag = 1;

    callForwardCondition = [[UITextField alloc] init];
    callForwardCondition.text = callCondition;
    callForwardCondition.borderStyle = UITextBorderStyleRoundedRect;
    callForwardCondition.delegate = self;
    callForwardCondition.tag = 2;
    [callForwardCondition setKeyboardType:UIKeyboardTypeNumberPad];

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
    UIView* customAccessory = 
                   [[UIView alloc] initWithFrame:CGRectMake(0, 0, 250, 55)];
    callForwardNumber.frame = CGRectMake(0, 0, 245.0, 25.0);
    callForwardCondition.frame = CGRectMake(0, 30.0, 245.0, 25.0);
    [customAccessory addSubview:callForwardNumber];
    [customAccessory addSubview:callForwardCondition];
    [alert setValue:customAccessory forKey:@"accessoryView"];
    [alert show];
} else {
    alert.message = @"\n\n\n";
    [alert show];
    callForwardNumber.frame = CGRectMake(20.0, 45.0, 245.0, 25.0);
    callForwardCondition.frame = CGRectMake(20.0, 75.0, 245.0, 25.0);
    [alert addSubview:callForwardNumber];
    [alert addSubview:callForwardCondition];
}

}

0

我也遇到了同样的问题,在浏览网页时找到了答案,它对我有用。希望它对你也有用。

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Folder Name?" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
alertView.tag = 2;
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
[alertView show];

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex    {
    UITextField * alertTextField = [alertView textFieldAtIndex:0];
    NSLog(@"alerttextfiled - %@",alertTextField.text);
}

0

1) 在方法 - (id)initWithAlertTitle:(NSString *)title checkForPassword:(NSString *)password
中,您应该添加

self.alertViewStyle = UIAlertViewStylePlainTextInput;

示例:

(id)initWithAlertTitle:(NSString *)title
        checkForPassword:(NSString *)password{
     if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
     {
    self.alertViewStyle = UIAlertViewStylePlainTextInput;
    }
    self = [super initWithTitle:title
                        message:@"" // password field will go here
                       delegate:self
              cancelButtonTitle:@"Cancel"
              otherButtonTitles:@"Enter", nil];
    if (self) {
        self.password = password;
        self.hashTechnique = HashTechniqueNone; // use no hashing by default
        secondMessage = @"Please Enter New Password";
        thirdMessage = @"Please Re-Enter Password";
        secondMessageNew = @"Please Enter Password";
    }

NSLog(@" _password_ %@",_password);
NSLog(@"_old_password_ %@",[[NSUserDefaults standardUserDefaults] objectForKey:kPassword]);

return self;
}

在方法show中添加next。
(void)show {

    if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
     {

       UITextField *passwordField = [self textFieldAtIndex:0];
       passwordField.delegate = self;
      self.passwordField = passwordField;
    }
   else
   {
               UITextField *passwordField = [[UITextField alloc] initWithFrame:CGRectMake(14, 45, 256, 25)];
               passwordField.secureTextEntry = YES;
               passwordField.placeholder = @"";
               passwordField.backgroundColor = [UIColor whiteColor];



               // Pad out the left side of the view to properly inset the text
               UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 6, 19)];
                passwordField.leftView = paddingView;
                passwordField.leftViewMode = UITextFieldViewModeAlways;

           //    // Set delegate
           self.passwordField.delegate = self;

           // Set as property

            self.passwordField = passwordField;
           // Add to subview
           [self addSubview:_passwordField];
     }

    // Show alert
   [super show];

}

还要在 click 方法中进行更改

#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {


    if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
    {
        UITextField *passwordField = [self textFieldAtIndex:0];
        self.passwordField = passwordField;
    }

    if (buttonIndex == alertView.firstOtherButtonIndex) {

        if ([self enteredTextIsCorrect] || [self.title isEqualToString:secondMessage] || [self.title isEqualToString:secondMessageNew]) {

            if (([self.title isEqualToString:secondMessage] || [self.title isEqualToString:secondMessageNew]) && (self.passwordField.text.length > 0)) {
                self.password = self.passwordField.text;
                self.title = thirdMessage;
                self.passwordField.text = @"";

                if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
                {
                    if ([self.passwordDelegate respondsToSelector:@selector(notifyParent::)]) {
                        [self.passwordDelegate notifyParent:thirdMessage:self.password];
                    }
               }
            }else
            {
                if ([self.title isEqualToString:thirdMessage]) {
                    [[NSUserDefaults standardUserDefaults] setObject:self.password forKey:kPassword];
                    [[NSUserDefaults standardUserDefaults] synchronize];

                    if (self.passwordDelegate) {
                        if ([self.passwordDelegate respondsToSelector:@selector(notifyParentWithState:)]) {
                            [self.passwordDelegate notifyParentWithState:YES];
                        }
                    }
                }else{
                    if ([self.title isEqualToString:secondMessageNew]) {
                        self.title = secondMessageNew;
                    }
                    else{
                        self.title = secondMessage;
                    }

                     self.passwordField.text = @"";
                     if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
                     {
                         if ([self.passwordDelegate respondsToSelector:@selector(notifyParent::)]) {
                             [self.passwordDelegate notifyParent:self.title:self.password];
                        }
                    }
                }
            }
        }

        // If incorrect then animate
        else {
            [self animateIncorrectPassword];
        }
    }
}

我的解决方案适用于iOS 5及以上版本(您只在iOS 7及以上版本上使用它)。除非您要支持iOS 4,否则没有必要进行这种黑客行为。此外,无论您从哪个应用程序复制了此代码,将密码保存在NSUserDefaults中都是一个糟糕的想法。 - Aaron Brager

0

您也可以在cocoacontrols.com上查看自定义控件。请查看 MLAertView(类似于iOS 7的UI)和 TSAlertView(类似于iOS 6的UI)。它们也可以被旋转。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接