【问题标题】:UITextField in UIAlertView on iPhone - how to make it responsive?iPhone上UIAlertView中的UITextField - 如何使其响应?
【发布时间】:2008-12-17 21:33:32
【问题描述】:

我在 UIAlertView 中放置了一个 UITextField 并将其向上移动,这样键盘就不会被以下代码覆盖:

[dialog setDelegate:self];
[dialog setTitle:@"Enter Name"];
[dialog addButtonWithTitle:@"Cancel"];
[dialog addButtonWithTitle:@"OK"];
UITextField * nameField = [[UITextField alloc] initWithFrame:CGRectMake(20.0, 45.0, 245.0, 25.0)];
[nameField setBackgroundColor:[UIColor whiteColor]];
[dialog addSubview:nameField];
CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0.0, 100.0);
[dialog setTransform: moveUp];
[dialog show];

我还有以下代码来处理警报视图:

- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex{    
    NSLog(@"%d", (int) buttonIndex);
    if (buttonIndex == 1) { // OK pushed
        NSLog([alert textField].text); // does not log anything
    } else {
        // Cancel pushed
}}

我还有一个 UIAlertViewExtended.h 文件,其中包含:

@class UITextField, UILabel;

@interface UIAlertView(Extended)

-(UITextField *)textField;

@end

我的问题是如何获取用户输入的文本以及如何关闭键盘?

谢谢, 本

【问题讨论】:

  • iPhone OS 4.0 似乎会自动进行转换,可能我们将不得不引入检查您的基础 SDK 是否为 4.0 并且您将支持的最低 SDK 为 3.0,以便仅执行 CGAffineTransform 代码如果本机操作系统是 3.0 或 3.1,对于 iPhone OS 4.0 跳过这部分代码!

标签: iphone cocoa-touch


【解决方案1】:

任何支持 iOS 5.0 及以上版本的 ARC 用户,都可以直接设置 alertViewStyle 属性:

-(void)showAlertWithTextField{
    UIAlertView* dialog = [[UIAlertView alloc] initWithTitle:@"Enter Name" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];    
    [dialog setAlertViewStyle:UIAlertViewStylePlainTextInput];

    // Change keyboard type
    [[dialog textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeNumberPad];
    [dialog show];
}

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

【讨论】:

  • 我们是时候找到一种方法来做到这一点了,它不涉及破解愚蠢的 alertView。 +1
  • @katzenhut 非常真实!您是否通过bugreports 提出功能请求?
【解决方案2】:

对于那些可能关心的人,这里有一个可行的解决方案:

UIAlertView* dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:@"Enter Name"];
[dialog setMessage:@" "];
[dialog addButtonWithTitle:@"Cancel"];
[dialog addButtonWithTitle:@"OK"];

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

确保你已经创建了 UITextField * nameField;在您的 .h 文件中,您可以通过以下方式获取用户输入的文本: inputText = [名称字段文本];

在 - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex 方法中。

重要提示:对于 iOS 4.0+,CGAffineTransform 是自动完成的,因此如果您只针对 4.0+,您可以忽略这一点。否则,您将需要检查您使用的操作系统并相应地进行处理。

【讨论】:

  • 好的,效果很好,但是如何让按钮向下移动以为文本字段腾出空间?在我的实现中(从你的复制/粘贴开始),我有 4 个按钮(取消、foo、bar、baz),文本字段覆盖取消按钮。
  • 嘿!为什么要保留变量dialog?你不是已经分配了吗?我可能错了,但您似乎正在以这种方式泄漏对象。经验法则是,如果你分配一个对象,那么你必须释放它,因为它的保留计数已经为 1。
  • @inkredibl 为了后代,我删除了导致内存泄漏的保留。
  • 在 iOS 4.2 中,这将在顶部创建一个 alertview。同时删除 CGAffineTransform 也不能解决问题。有人有解决方案吗?
  • @raaz 确保您的 setMessage 是“”而不是“”。它在 4.3 上对我有用
【解决方案3】:

【讨论】:

  • 很棒的代码。我建议将文本字段保存在实例变量中。然后,您不需要实现文本字段委托,您可以让它在alertView:willDismissWithButtonIndex: 中退出第一响应者以摆脱“wait_fences:无法接收回复:10004003”控制台消息。
  • 在模拟器 4.3 下损坏。它使应用程序崩溃。
【解决方案4】:

定位文本字段的一种简单方法是设置其标记,而不保留对其的显式引用:

nameField.tag = ALERTVIEW_NAMEFIELD;

确保它不同于 0 和您可能拥有的其他 UIView 对象标签,包括父对话框!

然后在 alertView:clickedButtonAtIndex: 处理程序中,您可以通过这种方式检索您的文本字段:

UITextField *nameField = (UITextField *)[alertView viewWithTag:ALERTVIEW_NAMEFIELD];

【讨论】:

    【解决方案5】:

    找到更清晰的解决方案。检查此代码 sn-p 输出:Username and Password UITextFields in UIAlertView prompt

    【讨论】:

      【解决方案6】:

      【讨论】:

        【解决方案7】:

        一个很好的方法是,您可以使用 UITextFieldDelegate 的委托方法仅在激活键盘时将对话框向上移动。见下文。

        - (void)textFieldDidBeginEditing:(UITextField *)textField {
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.5]; 
            [UIView setAnimationDelegate:self];
        
            CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0.0, -20);
            [dialog setTransform: moveUp];
        
            [UIView commitAnimations];
        }
        
        - (BOOL)textFieldShouldReturn:(UITextField *)textField {
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:0.5]; 
            [UIView setAnimationDelegate:self];
        
            CGAffineTransform moveDown = CGAffineTransformMakeTranslation(0.0, 0.0);
            [dialog setTransform: moveDown];
        
            [textField resignFirstResponder];
        
            return YES;
        }
        

        【讨论】:

          【解决方案8】:

          这适用于 iOS5 和 ARC。

          -(void)showAlert {
              UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"New Album" 
                  message:@"Enter a name for the album." 
                  delegate:self 
                  cancelButtonTitle:@"Cancel" 
                  otherButtonTitles:@"Save", nil];
              alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
          
              UITextField* textfield = [alertView textFieldAtIndex:0];
              textfield.placeholder = @"Title";
          
              [alertView show];
          }
          
          -(void)alertView:(UIAlertView *)alertView 
              didDismissWithButtonIndex:(NSInteger)buttonIndex 
          {
              if (buttonIndex != 1) {
                  NSLog(@"Cancel");
                  return;
              }
              UITextField* textfield = [alertView textFieldAtIndex:0];
              NSLog(@"Save. text: %@", textfield.text);
          }
          

          【讨论】:

            【解决方案9】:

            这实际上只是常规 UIAlertView 代码的多行代码。希望这会有所帮助!

                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"test" message:@"This is a alert with a textfield" delegate:self cancelButtonTitle:@"YAY" otherButtonTitles:nil];
                alert.alertViewStyle = UIAlertViewStylePlainTextInput;
                [alert show];
                [alert release];
            

            仅在 iOS 5 或更高版本上运行

            【讨论】:

              【解决方案10】:

              想对 iWasRobbed 的回答添加一个小调整:

              GenericAlertDialogs.m:

              + (void)displayInputDialog:(NSString*)title delegate:(id<UIAlertViewDelegate>)delegate textFiled:(UITextField*)txtField
              {
                  UIAlertView* dialog = [[UIAlertView alloc] init];
                  [dialog setDelegate:delegate];
                  [dialog setTitle:title];
                  [dialog setMessage:@" "];
                  [dialog addButtonWithTitle:@"Cancel"];
                  [dialog addButtonWithTitle:@"OK"];
              
                  if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
                  {
                      txtField.frame = CGRectMake(20.0, 45.0, 245.0, 25.0);
                  }
                  else 
                  {
                      txtField.frame = CGRectMake(20.0, 30.0, 245.0, 25.0);
                  }
              
                  [txtField becomeFirstResponder];
                  [txtField setBackgroundColor:[UIColor whiteColor]];
                  [dialog addSubview:txtField];
                  [dialog show];   
              }
              

              其他一些 .m 文件(实现 UIAlertViewDelegate)

               self->txtChangeName = [[UITextField alloc] init];
               [GenericAlertDialogs displayInputDialog:@"Some title...:" 
                                              delegate:self 
                                             textFiled:txtChangeName];
              

              UIAlertViewDelegate 协议处理:

              - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex 
              {
                  if(buttonIndex == 1)
                  {
                      if([txtChangeName.text length] > 0)
                      {
                          self->userInput = [txtChangeName text];
                       }
                   }
                   self->txtChangeName = nil;
              }
              

              兼容 iOS 4+。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多