UIAlertController – 获取消息和操作视图的方法?

UIAlertController – way to get views for message and actions?

我们需要使用 UITextView(即多行文本输入)来允许用户输入信息。 UITextView 不能很好地与自动调整大小一起使用,因此我们使用 UIAlertController 视图的边界设置约束。存在布局问题,具体取决于辅助功能设置。

例如,在较大的文本设置下,这个布局漂亮整洁:

但是使用相同的约束,这是使用默认文本设置的样子:

不好!我们不想陷入为每个模型和文本大小设置自定义代码的困境。是否有合法的方法来获取消息和操作的视图,以便我们可以改为与这些功能保持一致?

"Legal" 因为 UIAlertController 的官方文档指出(强调 我的):

Important

The UIAlertController class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

并确认当我们遍历 [[alertController view] subviews] 时,操作(CancelSubmit 按钮)似乎不可见,所以我们必须小心这里。

此外,对于所有 iPhone 模型,safeAreaInsets{0, 0, 0, 0},所以这对这里没有任何帮助。

我想大部分问题出在按钮的堆叠上,所以如果有一种方法可以检测该配置,那将解决大部分布局问题。

这是一个较旧的应用程序,因此我们在 Objective-C 中进行编码,但 Swift 解决方案也可以。

感谢@DonMag 和@rmaddy 的建议,但预算允许我们只修改现有的 UIAlertController 代码,而不是创建新的视图控制器。

我们审查了这个问题,发现只有三种情况需要我们担心,特别是 XLXXLXXXL 首选内容大小类别。我们直接处理了它们:

NSString *sizeCategory = UIScreen.mainScreen.traitCollection.preferredContentSizeCategory;
CGFloat top = -82.f;
CGFloat bottom = +52.0f;
if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraLarge])
{
    top = -90.0f;
    bottom = +98.0f;
}
else if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge])
{
    top = -118.0f;
    bottom = +98.0f;
}
else if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge])
{
    top = -160.0f;
    bottom = +98.0f;
}

然后是设置约束的代码。代码已经有 hard-coded 个常量,所以我们不会让情况变得更糟!

我们目前不处理 "Larger Accessibility Sizes" 下的额外文本大小。该应用程序通常需要最低视力水平。

我建议您使用 UiKit 中的正确方法,addTextFieldWithConfigurationHandler: 例如:

-(void)showAlert{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Defining by Words Only" message:@"Enter the words you want to use,separated by spaces." preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *action = [UIAlertAction actionWithTitle:@"Submit Words" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[self submitWordsMethods:alert.textFields.firstObject.text];}];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];

    //Doesn't allow to send a empty answer.
    [alert addAction: action];
    [action setEnabled:NO];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        //Text field activates el boton de enviar cuando tiene texto.
        [textField addTarget:self action:@selector(alertControllerTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    }];
    [alert addAction: cancel];
    [self presentViewController:alert animated:YES completion:nil];
}

这是结果: