简体   繁体   English

如何在 IOS 8 中设置 UIAlertController 的高度和宽度

[英]How to set height and width of a UIAlertController in IOS 8

I have a UIAlertController with an TextFile.我有一个带有 TextFile 的 UIAlertController。 The problem is that the default UIAlertController is a very small size.问题是默认的 UIAlertController 尺寸非常小。 It's text cannot be seen properly.它的文字无法正常显示。

So, I want to increase the height and width of the UIAlertController.所以,我想增加 UIAlertController 的高度和宽度。 In other words, I want to create a custom UIAlertController.换句话说,我想创建一个自定义的 UIAlertController。 What would be the way to do that?这样做的方法是什么?

You can control UIAlertController via constraints.您可以通过约束控制 UIAlertController。

Lets say we want this alert to be wider:假设我们希望此警报更广泛:

大内容提醒

If you take a look at view hierarchy, you'll see that UIKit restricts UIAlertController width to 270:如果您查看视图层次结构,您会看到 UIKit 将 UIAlertController 宽度限制为 270:

查看层次结构

Checking this view children, you can find that its first child also has this constraint with priority 998.查看这个view children,可以发现它的第一个child也有这个约束,优先级为998。

Knowing that we can update this constraints before we present alert controller.知道我们可以在呈现警报控制器之前更新此约束。 Something like this:像这样的东西:

    let alert = UIAlertController(title: "Some gorgeous very big big big title with many words", message: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam a augue eget magna maximus posuere. Donec pellentesque lacus ut tellus mollis, eget congue nulla dapibus. Sed pharetra porta lorem, ac faucibus risus scelerisque vitae. Aenean lacinia lobortis quam quis finibus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed odio nisl, pretium a turpis in, pulvinar bibendum augue. Proin id ligula elementum, pulvinar lorem et, suscipit turpis. Duis in tortor arcu. Donec in dapibus ex.\n\nDuis sit amet lacus nec mauris blandit dignissim. Sed efficitur vestibulum sapien ut condimentum. Donec a lorem sit amet augue imperdiet dictum sed eu sapien. Donec in congue quam, vitae luctus augue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vivamus felis ipsum, malesuada eu dictum non, imperdiet ut urna. Vivamus tempus ante sit amet quam interdum feugiat. Ut at nulla nibh.", preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "Hide this", style: .default, handler: nil))
    // Filtering width constraints of alert base view width
    let widthConstraints = alert.view.constraints.filter({ return $0.firstAttribute == .width })
    alert.view.removeConstraints(widthConstraints)
    // Here you can enter any width that you want
    let newWidth = UIScreen.main.bounds.width * 0.90
    // Adding constraint for alert base view
    let widthConstraint = NSLayoutConstraint(item: alert.view,
                                             attribute: .width,
                                             relatedBy: .equal,
                                             toItem: nil,
                                             attribute: .notAnAttribute,
                                             multiplier: 1,
                                             constant: newWidth)
    alert.view.addConstraint(widthConstraint)
    let firstContainer = alert.view.subviews[0]
    // Finding first child width constraint
    let constraint = firstContainer.constraints.filter({ return $0.firstAttribute == .width && $0.secondItem == nil })
    firstContainer.removeConstraints(constraint)
    // And replacing with new constraint equal to alert.view width constraint that we setup earlier
    alert.view.addConstraint(NSLayoutConstraint(item: firstContainer,
                                                attribute: .width,
                                                relatedBy: .equal,
                                                toItem: alert.view,
                                                attribute: .width,
                                                multiplier: 1.0,
                                                constant: 0))
    // Same for the second child with width constraint with 998 priority
    let innerBackground = firstContainer.subviews[0]
    let innerConstraints = innerBackground.constraints.filter({ return $0.firstAttribute == .width && $0.secondItem == nil })
    innerBackground.removeConstraints(innerConstraints)
    firstContainer.addConstraint(NSLayoutConstraint(item: innerBackground,
                                                    attribute: .width,
                                                    relatedBy: .equal,
                                                    toItem: firstContainer,
                                                    attribute: .width,
                                                    multiplier: 1.0,
                                                    constant: 0))

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

Now your alert will take 90% of your screen:现在您的警报将占据您屏幕的 90%:

90% 宽屏警报

Right now I find only this solution.现在我只找到这个解决方案。 There may be more elegant variant and secure solution, but I think you get the idea.可能有更优雅的变体和安全的解决方案,但我认为您明白了。

I know this is closed but I found you can add constraints to the alertviewcotnroller.view like this我知道这已关闭,但我发现您可以像这样向 alertviewcotnroller.view 添加约束

var height:NSLayoutConstraint = NSLayoutConstraint(item: alertController.view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.view.frame.height * 0.80)
    alertController.view.addConstraint(height);

I do not think you can set the size.我不认为你可以设置大小。 Bad workaround is, to set \\n on the message.不好的解决方法是在消息上设置\\n UIAlertView also has same limitation. UIAlertView 也有同样的限制。

I will suggest to use UIPopoverController and implement your own dismiss button, since UIAlertController's purpose is more to display alert messages to the user (short message) per Apple Documentation.我建议使用 UIPopoverController 并实现您自己的dismiss按钮,因为 UIAlertController 的目的更多是根据 Apple 文档向用户显示警报消息(短消息)。 I do not think wall of message can be considered as alert message.我不认为消息墙可以被视为警报消息。

Generally, I think this limitation is set by Apple as a reminder this view is to display short message to users as part of their UX.一般来说,我认为这个限制是由 Apple 设置的,作为提醒,这个视图是向用户显示短消息作为用户体验的一部分。

Edited with sample code First, sorry, I mean UIPopoverPresentViewController , not UIPopoverController用示例代码编辑首先,抱歉,我的意思是UIPopoverPresentViewController ,而不是UIPopoverController

Here is the sample class:这是示例类:

@interface DemoPopOverPresentViewController : UIViewController

- (instancetype)initWithTitle:(NSString*)title message:(NSString*)message buttonTitle:(NSString*)buttonTitle;

@property NSString* titleText;
@property NSString* messageText;
@property NSString* buttonTitleText;

@property UILabel* titleLabel;
@property UILabel* textLabel;
@property UIButton* submitButton;

@end

@implementation DemoPopOverPresentViewController

- (instancetype)initWithTitle:(NSString*)title message:(NSString*)message buttonTitle:(NSString*)buttonTitle;
{
    self = [super init];

    if ( self ) {
        _titleText = title;
        _messageText = message;
        _buttonTitleText = buttonTitle;
    }

    return self;
}

- (void)viewDidLoad;
{
    [super viewDidLoad];

    _titleLabel = [UILabel new];
    [_titleLabel setTextAlignment:NSTextAlignmentCenter];
    [_titleLabel setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]];
    [_titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_titleLabel setText:_titleText];
    [self.view addSubview:_titleLabel];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_titleLabel]|"     options:0 metrics:nil views:NSDictionaryOfVariableBindings(_titleLabel)]];

    _textLabel = [UILabel new];
    [_textLabel setTextAlignment:NSTextAlignmentCenter];
    [_textLabel setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]];
    [_textLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_textLabel setNumberOfLines:0];
    [_textLabel setText:_messageText];
    [self.view addSubview:_textLabel];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_textLabel]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_textLabel)]];

    _submitButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [_submitButton setTitle:_buttonTitleText forState:UIControlStateNormal];
    [_submitButton addTarget:self action:@selector(submitButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
    [_submitButton setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.view addSubview:_submitButton];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_submitButton]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_submitButton)]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_titleLabel(<=44.0)]-16-[_textLabel]-16-[_submitButton(<=44.0)]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_titleLabel,_textLabel,_submitButton)]];
}

- (void)submitButtonTouched:(id)sender;
{
    [self dismissViewControllerAnimated:YES completion:^{

    }];
}

@end

Then on presentingViewController,然后在presentingViewController上,

  • first, it will need to implement UIPopoverPresentationControllerDelegate delegate首先,它需要实现UIPopoverPresentationControllerDelegate委托
  • then to initialise the class:然后初始化类:

     DemoPopOverPresentViewController* controller = [[DemoPopOverPresentViewController alloc] initWithTitle:@"Info" message:@"The quick brown fox jumps over the lazy dog" buttonTitle:@"Dismiss"]; controller.modalPresentationStyle = UIModalPresentationPopover; // set the content size of your 'alert view' controller.preferredContentSize = CGSizeMake(200.0, 150.0); UIPopoverPresentationController* pc = [controller popoverPresentationController]; pc.sourceView = self.view; pc.delegate = self; pc.sourceRect = CGRectMake(self.view.frame.size.width/2.0, self.view.frame.size.height/2.0, 0.0, 0.0); pc.permittedArrowDirections = NULL; [self presentViewController:controller animated:YES completion:^{ }];
  • implement delegate method for UIPopoverPresentationControllerDelegate : - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller and return UIModalPresentationNoneUIPopoverPresentationControllerDelegate实现委托方法: - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller并返回UIModalPresentationNone

This should certainly help you.这肯定会对您有所帮助。 (Swift 4.2) (斯威夫特 4.2)

let alert = UIAlertController(title: "Alert", message: "Some message", preferredStyle: .actionSheet)

alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) in

}))
alert.addAction(UIAlertAction(title: "Some", style: .default))
alert.addAction(UIAlertAction(title: "Some", style: .default))

let height:NSLayoutConstraint = NSLayoutConstraint(item: alert.view, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: view.frame.height)
alert.view.addConstraint(height);
present(alert, animated: true)
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

}]];


UIViewController *viewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];

if ( viewController.presentedViewController && !viewController.presentedViewController.isBeingDismissed ) {
    viewController = viewController.presentedViewController;
}

**NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:viewController.view.frame.size.height*0.8f];
[alert.view addConstraint:constraint];**

[viewController presentViewController:alert animated:YES completion:^{

}];

Just update width constraint value只需更新宽度约束值

// calculate new width
let newWidth = UIScreen.main.bounds.width * 0.90 - 270

// update width constraint value for main view
if let viewWidthConstraint = alertController.view.constraints.filter({ return $0.firstAttribute == .width }).first{
    viewWidthConstraint.constant = newWidth
}

// update width constraint value for container view
if let containerViewWidthConstraint = alertController.view.subviews.first?.constraints.filter({ return $0.firstAttribute == .width }).first {
    containerViewWidthConstraint.constant = newWidth
}

//present alertController
self.present(alertController, animated: true, completion: nil)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM