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

时间:2014-11-06 07:34:55

标签: objective-c iphone xcode ipad ios8

我有一个带有TextFile的UIAlertController。 问题是默认的UIAlertController是一个非常小的尺寸。它的文字无法正常显示。

所以,我想增加UIAlertController的高度和宽度。换句话说,我想创建一个自定义的UIAlertController。这样做的方法是什么?

6 个答案:

答案 0 :(得分:7)

我知道这已关闭,但我发现你可以像这样添加约束到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);

答案 1 :(得分:2)

我认为你不能设定尺寸。错误的解决方法是,在邮件上设置\n。 UIAlertView也有同样的限制。

我建议使用UIPopoverController并实现自己的dismiss按钮,因为UIAlertController的目的更多是根据Apple文档向用户显示警报消息(短消息)。我不认为消息墙可以被视为警报消息。

一般来说,我认为此限制是由Apple设定的,提醒一下此视图是向用户显示短信,作为其用户体验的一部分。

使用示例代码编辑 首先,抱歉,我的意思是UIPopoverPresentViewController,而不是UIPopoverController

以下是示例类:

@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

然后在presentViewController上,

  • 首先,它需要实施UIPopoverPresentationControllerDelegate委托
  • 然后初始化课程:

    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:^{
    
    }];
    
  • UIPopoverPresentationControllerDelegate实施委托方法:- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller并返回UIModalPresentationNone

答案 2 :(得分:1)

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:^{

}];

答案 3 :(得分:1)

这肯定会对您有所帮助。 (快速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)

答案 4 :(得分:1)

您可以通过约束来控制UIAlertController。

让我们说我们希望此警报范围更广:

Alert with big content

如果查看视图层次结构,将会看到UIKit将UIAlertController的宽度限制为270:

View hierarchy

选中此视图子级,您可以发现它的第一个子级也具有此优先级998。

知道在提交警报控制器之前我们可以更新此约束。像这样:

    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)

现在,您的警报将占据您90%的屏幕:

90% wide screen alert

现在我只能找到这种解决方案。可能会有更优雅的变体和安全的解决方案,但我想您会明白的。

答案 5 :(得分:0)

仅更新宽度约束值

// 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)