【问题标题】:UIImageView blocks UINavigationBar with AutoLayoutUIImageView 用 AutoLayout 阻塞 UINavigationBar
【发布时间】:2020-06-20 18:03:23
【问题描述】:

我正在尝试创建一个具有 UINavigationBar 和 UIImageView 的 UIViewController。我放入 UIImageView 的图像大小为416 × 901 pixels。我正在尝试创建一个视图,使导航栏位于顶部,然后 UIImageView 固定在屏幕边缘和工具栏下方。但是,当我运行我的应用程序时,UIImage 似乎超出了导航栏。

这是来自 Xcode 的截图:

如您所见,UINavigationBar 被 UIImage 遮挡。当我删除图像时,布局看起来像我预期的那样(我注释掉 UIImage 分配image.image = [UIImage imageNamed:@"attachment.jpg"];,您可以在下面发布的代码中看到):

我很困惑。我猜它与 UIImageView 中缺少的参数有关,或者我需要创建一个完全不同的约束,但我不确定。我已经粘贴了下面布局的代码。我很感激我能得到的任何帮助。

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

UINavigationBar *navigation = [[UINavigationBar alloc] initWithFrame:CGRectZero];
    navigation.translatesAutoresizingMaskIntoConstraints = NO;
    UINavigationItem* navigationItem = [[UINavigationItem alloc] initWithTitle:@"Edit"];
    UIBarButtonItem* cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];
    navigationItem.leftBarButtonItem = cancelBtn;

    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save:)];
    navigationItem.rightBarButtonItem = doneBtn;

    [navigation setItems:@[navigationItem]];
    navigation.delegate = self;

    UIImageView *image = [[UIImageView alloc] init];
    image.contentMode = UIViewContentModeScaleAspectFit;
    image.backgroundColor = [UIColor redColor];
    image.image = [UIImage imageNamed:@"attachment.jpg"];
    image.translatesAutoresizingMaskIntoConstraints = NO;

    UIView *content = [[UIView alloc] initWithFrame:CGRectZero];
    content.translatesAutoresizingMaskIntoConstraints = NO;
    content.backgroundColor = [UIColor yellowColor];
    [content addSubview:image];
    [content addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[image]-0-|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(image)]];
    [content addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[image]-0-|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(image)]];


    [self.view addSubview:navigation];
    [self.view addSubview:content];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[navigation]-0-[content]-0-|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(navigation, content)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[navigation]-0-|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(navigation, content)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[content]-0-|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(navigation, content)]];
}


- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar {
        return UIBarPositionTopAttached;
}

- (void)cancel:(id)button {}
- (void)save:(id)button {}

@end

我刚刚注意到 Xcode 中有一些关于布局的运行时警告。这是 Xcode 向我展示的内容:

我猜导航栏的高度是模棱两可的,因为 UIImageView 的高度没有很好的定义。但是在这种情况下,我试图固定图像的高度,期望导航的高度能够很好地定义。基本上,我依靠导航来定义 UIImageView 需要多少空间。也许我需要修复两个元素之一的高度?

【问题讨论】:

    标签: ios objective-c autolayout ios-autolayout


    【解决方案1】:

    添加自己的导航栏有点奇怪,因为它需要在设备旋转时调整大小。

    像这样尝试(我不喜欢 VFL - 有时似乎有它自己的问题):

    @interface ViewController ()
    @property (strong, nonatomic) NSLayoutConstraint *navBarHeightCon;
    @end
    
    @implementation ViewController
    
    - (void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];
        _navBarHeightCon.constant = (self.view.bounds.size.height > self.view.bounds.size.width)? 44 : 32;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UINavigationBar *navigation = [[UINavigationBar alloc] initWithFrame:CGRectZero];
        navigation.translatesAutoresizingMaskIntoConstraints = NO;
        UINavigationItem* navigationItem = [[UINavigationItem alloc] initWithTitle:@"Edit"];
        UIBarButtonItem* cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];
        navigationItem.leftBarButtonItem = cancelBtn;
    
        UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save:)];
        navigationItem.rightBarButtonItem = doneBtn;
    
        [navigation setItems:@[navigationItem]];
        navigation.delegate = self;
    
        UIImageView *image = [[UIImageView alloc] init];
        image.contentMode = UIViewContentModeScaleAspectFit;
        image.backgroundColor = [UIColor redColor];
    
        image.image = [UIImage imageNamed:@"attachment.jpg"];
        image.translatesAutoresizingMaskIntoConstraints = NO;
    
        UIView *content = [[UIView alloc] initWithFrame:CGRectZero];
        content.translatesAutoresizingMaskIntoConstraints = NO;
        content.backgroundColor = [UIColor yellowColor];
    
        [content addSubview:image];
    
        [self.view addSubview:navigation];
        [self.view addSubview:content];
    
        UILayoutGuide *g = self.view.safeAreaLayoutGuide;
    
        _navBarHeightCon = [navigation.heightAnchor constraintEqualToConstant:44.0];
    
        [NSLayoutConstraint activateConstraints:@[
    
            // constrain content view top to navigation bar bottom
            [content.topAnchor constraintEqualToAnchor:navigation.bottomAnchor],
    
            // constrain content view bottom / leading / trailing to safe area
            [content.bottomAnchor constraintEqualToAnchor:g.bottomAnchor],
            [content.leadingAnchor constraintEqualToAnchor:g.leadingAnchor],
            [content.trailingAnchor constraintEqualToAnchor:g.trailingAnchor],
    
            // constrain image top / bottom / leading / trailing to content view
            [image.topAnchor constraintEqualToAnchor:content.topAnchor],
            [image.bottomAnchor constraintEqualToAnchor:content.bottomAnchor],
            [image.leadingAnchor constraintEqualToAnchor:content.leadingAnchor],
            [image.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
    
            // constrain navigation bar top / leading / trailing to safe area
            [navigation.topAnchor constraintEqualToAnchor:g.topAnchor],
            [navigation.leadingAnchor constraintEqualToAnchor:g.leadingAnchor],
            [navigation.trailingAnchor constraintEqualToAnchor:g.trailingAnchor],
    
            // height constraint will be set in viewWillLayoutSubviews
            _navBarHeightCon,
    
        ]];
    
    }
    
    - (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar {
        return UIBarPositionTopAttached;
    }
    
    - (void)cancel:(id)button {}
    - (void)save:(id)button {}
    
    @end
    

    【讨论】:

      【解决方案2】:

      经过(过多)调查后,here 发布的解决方案对我有用。

      具体

      解决方法是将SuperView的Hugging Priority提高到High(750以上),将UIImageView的抗压优先级降低到Low(250以下)。这将使约束覆盖图像的固有大小。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-20
        • 1970-01-01
        • 2013-11-16
        • 2016-07-06
        • 2014-05-25
        相关资源
        最近更新 更多