带有多行 UITextField 的 iOS AlertController

Posted

技术标签:

【中文标题】带有多行 UITextField 的 iOS AlertController【英文标题】:iOS AlertController with multi-line UITextField 【发布时间】:2017-04-24 14:41:38 【问题描述】:

我正在开发一个应用程序,但它是一个相当旧的应用程序。客户不想花太多时间,所以我正在寻找一个简单快速的解决方案来解决这个问题。

用户必须为他们的个人资料写一个摘要,所以他们需要一个很大的空间来写。整个应用程序是用 AlertController 弹出窗口构建的,所以我想用更大的多行 UITextField 替换单行 UITextField .

我能做些什么来做到这一点? 我目前已经添加了以下代码:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:@"Enter your summary" preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) 
        textField.placeholder = @"Summary";
        textField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
        textField.text = _summaryLabel.text;

        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant: 110.0];
        [textField addConstraint:constraint];
        [textField layoutIfNeeded];
    ];

这意味着 UITextField 实际上更大,但它不是多行的,它也使文本垂直居中。我该怎么办?

【问题讨论】:

UITextField 仅适用于单行。如果要多行,则需要UITextViewUIAlertController 不支持。 使用类似于UIAlertController 的xib 制作自定义视图并不复杂,然后您可以在其中放入几乎任何您想要的东西。 【参考方案1】:

正如@rmaddy所说,UITextField仅用于单行,您可以使用UITextView

你可以这样做:

How to use UITextView in UIAlertController

UIAlertController *alert = [UIAlertController
                            alertControllerWithTitle:@"Enter your summary"
                            message:@"\n\n\n\n\n\n\n\n"
                            preferredStyle:UIAlertControllerStyleAlert];
alert.view.autoresizesSubviews = YES;

UITextView *textView = [[UITextView alloc] initWithFrame:CGRectZero];
textView.translatesAutoresizingMaskIntoConstraints = NO;

NSLayoutConstraint *leadConstraint = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:textView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:-8.0];
NSLayoutConstraint *trailConstraint = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:textView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:8.0];

NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:textView attribute:NSLayoutAttributeTop multiplier:1.0 constant:-64.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:textView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:64.0];
[alert.view addSubview:textView];
[NSLayoutConstraint activateConstraints:@[leadConstraint, trailConstraint, topConstraint, bottomConstraint]];

[alert addAction: [UIAlertAction actionWithTitle:@"Done"style:UIAlertActionStyleDefault handler:^(UIAlertAction*action) 
    NSLog(@"%@", textView.text);
]];

[self presentViewController:alert animated:YES completion:nil];

或者使用UIAlertView:

How to Insert the UITextView into UIAlertview in ios

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@""
                                                    message:@"Enter your summary"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:@"Done", nil];

UITextView *textView = [[UITextView alloc] initWithFrame:CGRectZero];
[alert setValue:textView forKey:@"accessoryView"];
[alert show];

或自定义您自己的警报,例如ios-custom-alertview

【讨论】:

第二个选项(UIAlertView 之一)不是使用私有 API 吗?我似乎也没有成功让第一个解决方案工作,因为它确实拉伸了 UIAlertController 但不知何故没有向我显示正确的 textView。编辑:我解决了,我没有在消息中看到换行符。感谢您的解决方案:) 向 UIAlertController 添加子视图是个坏主意,因为 Apple 明确告诉您不要这样做。您只是在询问未来 iOS 版本中的错误。 "The view hierarchy for this class is private and must not be modified."【参考方案2】:

您可以在 AlertController 中嵌入 ViewController。

-(void)showAlertWithTitle:(NSString *)title andBody:(NSString *)body andTextToEdit:(NSString*)text

    UIViewController *controller = [[UIViewController alloc]init];

    // Some size
    CGRect rect = CGRectMake(0, 0, 272, 250);
    [controller setPreferredContentSize:rect.size];

    // The text view to be used
    UITextView *textView = [[UITextView alloc]initWithFrame:rect];

    [textView setText:text]; // Original text is there to edit
    [controller.view addSubview:textView];  // Add the textField to the controller

    // I needed these when adding a UITableView, not sure if needed for UITextView
    [controller.view bringSubviewToFront:textView];
    [controller.view setUserInteractionEnabled:YES];

    alertWithText = [UIAlertController alertControllerWithTitle:title message:body preferredStyle:UIAlertControllerStyleAlert];
    [alertWithText setValue:controller forKey:@"contentViewController"];

    // create the actions handled by each button
    UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 

        NSLog(@"The Edited Text : %@", textView.text);
    ];

    UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) 

    ];


        // add the actions to our alert
    [alertWithText addAction:action1];
    [alertWithText addAction:action2];

    [self presentViewController:alertWithText animated:YES completion:^

    ];

【讨论】:

【参考方案3】:

如果有人需要上面的@tomfriwel 答案,但在 Swift 中:

    let alert = UIAlertController (title: "Enter your summary", message: "\n\n\n\n\n\n\n\n", preferredStyle: .alert)
    alert.view.autoresizesSubviews = true

    let textView = UITextView (frame: .zero)
    
    textView.translatesAutoresizingMaskIntoConstraints = false

    let leadConstraint = NSLayoutConstraint (item: alert.view, attribute: .leading, relatedBy: .equal, toItem: textView, attribute: .leading, multiplier: 1.0, constant: -8.0)

    let trailConstraint = NSLayoutConstraint (item: alert.view, attribute: .trailing, relatedBy: .equal, toItem: textView, attribute: .trailing, multiplier: 1.0, constant: 8.0)

    let topConstraint = NSLayoutConstraint (item: alert.view, attribute: .top, relatedBy: .equal, toItem: textView, attribute: .top, multiplier: 1.0, constant: -64.0)

    let bottomConstraint = NSLayoutConstraint (item: alert.view, attribute: .bottom, relatedBy: .equal, toItem: textView, attribute: .bottom, multiplier: 1.0, constant: 64.0)

    alert.view.addSubview(textView)
    
    NSLayoutConstraint.activate([leadConstraint, trailConstraint, topConstraint, bottomConstraint])

    let Done = UIAlertAction(title: "Done", style: .default)  (action:UIAlertAction) in
        NSLog("%@", textView.text)
    
    alert.addAction(Done)


    self.present(alert, animated: true, completion: nil)

【讨论】:

以上是关于带有多行 UITextField 的 iOS AlertController的主要内容,如果未能解决你的问题,请参考以下文章

iOS 13 - 带有占位符的 UITextField 让应用程序崩溃

带有 UITableViewCell 和 UITextField 的 iOS 8 自动布局

如何在 iOS 7 的 UITextField 中添加带有缩进的图像 UIImage?

iOS:带有 SecureEntry 的 UITextField 有时会用“强密码”文本突出显示黄色,然后键盘卡住

带有pickerview的UItextfield作为第一响应者ios

在带有secureTextEntry的iOS7 UITextField中破坏了其他文本字段中的布局