UIImageView使用AutoLayout阻止UINavigationBar

问题描述 投票:0回答:1

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

这里是Xcode的屏幕截图:

Layout Analyzer 1Layout Analyzer 2

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

Layout Analyzer 3Layout Analyzer 4

我很沮丧。我猜想它与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向我显示的内容:

Xcode warnings

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

ios objective-c autolayout ios-autolayout
1个回答
0
投票

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

尝试这样(我不喜欢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
© www.soinside.com 2019 - 2024. All rights reserved.