【问题标题】:How to set height and width of a UIAlertController in IOS 8如何在 IOS 8 中设置 UIAlertController 的高度和宽度
【发布时间】:2015-01-02 15:20:02
【问题描述】:

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

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

【问题讨论】:

    标签: objective-c iphone xcode ipad ios8


    【解决方案1】:

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

    假设我们希望此警报更广泛:

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

    查看这个view children,可以发现它的第一个child也有这个优先级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%:

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

    【讨论】:

    • 聪明的想法,但不幸的是,对我不起作用。也许 uialertcontroller 视图的层次结构在 ios13 中发生了变化。
    【解决方案2】:

    我知道这已关闭,但我发现您可以像这样向 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);
    

    【讨论】:

    • 我也只能让它为身高工作。
    • 仅适用于 iPhone。 iPad 吐出“无法同时满足约束”。因此,如果苹果给 iPhone 增加了限制,那么同样的问题也会出现。
    • @Jonathan Ellis 以同样的方式添加宽度约束,如下所示:** var width:NSLayoutConstraint = NSLayoutConstraint(item: alertController.view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem:无,属性:NSLayoutAttribute.NotAnAttribute,乘数:1,常量:self.view.frame.width * 0.80) alertController.view.addConstraint(width); ** 在我的项目中,我使用它来控制宽度并且它有效..
    【解决方案3】:

    我不认为你可以设置大小。不好的解决方法是在消息上设置\n。 UIAlertView 也有同样的限制。

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

    一般来说,我认为这个限制是由 Apple 设置的,以提醒这个视图是向用户显示短消息作为其 UX 的一部分。

    使用示例代码编辑 首先,对不起,我的意思是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
    

    然后在展示ViewController,

    • 首先,它需要实现UIPopoverPresentationControllerDelegatedelegate
    • 然后初始化类:

      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

    【讨论】:

    • 是的,我知道这是为长消息显示 UIPopoverController 的好方法,但客户端需要 UIAlertController。
    • 然后,您可以使用 UIPopOverController 来模拟警报窗口的 UI。
    • 你能给我一个示例代码或任何对我有帮助的教程吗?
    • 据我所知,Popover 的问题在于它必须指出它的来源,这与只出现在屏幕上的警报不同。
    【解决方案4】:

    这肯定会对您有所帮助。 (斯威夫特 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)
    

    【讨论】:

      【解决方案5】:
      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:^{
      
      }];
      

      【讨论】:

      • 如何设置alertviewcontroller的宽度
      【解决方案6】:

      只更新宽度约束值

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

      【讨论】:

        猜你喜欢
        • 2015-04-24
        • 1970-01-01
        • 2021-01-04
        • 2011-08-20
        • 2017-12-26
        • 1970-01-01
        • 2022-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多