使用布局锚将自定义导航栏项居中

时间:2018-07-18 16:12:52

标签: ios autolayout uinavigationbar uisearchbar layout-anchor

我已经创建了一个自定义导航项目(标题和UISearchBar)来替换iOS上的标准导航标题,并且我正尝试使用布局锚将其放在UINavigationBar中。

但是,布局约束[self.navigationItem.titleView.centerXAnchor constraintEqualToAnchor:self.navigationController.navigationBar.centerXAnchor].active = YES;不起作用,并且包含搜索栏的UIView显示在UINavigationBar的左侧。

其他限制:

  • 宽度应为屏幕宽度的1/3
  • 我要避免将width设置为常数,以使视图响应方向和其他布局变化

如何使导航栏项居中?

ScreenViewController.m

- (void) viewDidLoad {
    [super viewDidLoad];

    // Create the search bar
    self.searchBar = [SearchBar new];

    // Create a new UIView as titleView (otherwise I'm receiving an error)   
    self.navigationItem.titleView = [UIView new];

    // Add into view hierarchy and turn off auto constraints
    [self.navigationController.navigationBar addSubview:self.navigationItem.titleView];
    [self.navigationItem.titleView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.navigationItem.titleView addSubview:self.searchBar.view];            
    [self.searchBar.view setTranslatesAutoresizingMaskIntoConstraints:NO];

    // Set anchors for the wrapping view
    [self.navigationItem.titleView.widthAnchor constraintEqualToAnchor:self.navigationController.navigationBar.widthAnchor multiplier:1.0/3.0].active = YES;
    //[self.navigationItem.titleView.heightAnchor constraintEqualToConstant:50.0].active = YES;
    [self.navigationItem.titleView.topAnchor constraintEqualToAnchor:self.navigationController.navigationBar.topAnchor].active = YES;
    [self.navigationItem.titleView.centerXAnchor constraintEqualToAnchor:self.navigationController.navigationBar.centerXAnchor].active = YES;
    [self.navigationItem.titleView.bottomAnchor constraintEqualToAnchor:self.navigationController.navigationBar.bottomAnchor].active = YES;

    // Set anchors for the search bar
    [self.searchBar.view.widthAnchor constraintEqualToAnchor:self.navigationItem.titleView.widthAnchor multiplier:1.0].active = YES;
    //[self.navigationItem.titleView.heightAnchor constraintEqualToConstant:50.0].active = YES;
    [self.searchBar.view.topAnchor constraintEqualToAnchor:self.navigationItem.titleView.topAnchor].active = YES;
    [self.searchBar.view.bottomAnchor constraintEqualToAnchor:self.navigationItem.titleView.bottomAnchor].active = YES;
    //[self.searchBar.view.leftAnchor constraintEqualToAnchor:self.navigationItem.titleView.leftAnchor].active = YES;
    //[self.searchBar.view.rightAnchor constraintEqualToAnchor:self.navigationItem.titleView.rightAnchor].active = YES;
    [self.searchBar.view.centerXAnchor constraintEqualToAnchor:self.navigationItem.titleView.centerXAnchor].active = YES;
}

预期结果: Centering search bar

我得到了什么(标题视图未居中): Centering search bar problem

视图层次结构:

View hierarchy

2 个答案:

答案 0 :(得分:1)

您正在做的事情既不可能也不合法。您根本没有制作“自定义导航栏项”(如标题中所述)。您试图将子视图直接添加到导航栏。你不能那样做。将内容放入导航栏中的方法是将其分配为视图控制器的ZonedDateTime,既可以作为条形按钮项,也可以作为导航项的真实navigationItem。 (您将其称为变量 titleView,但实际上并不是将其作为导航项的titleView。)

答案 1 :(得分:0)

这是我的解决方案,仅更改标题视图,将其宽度锚点设置为导航栏的一小部分以使其具有响应性:

// Create search bar and set it as title view
self.searchBar = [SearchBar new];
self.navigationItem.titleView = self.searchBar.view;

// Turn auto constraints off
[self.searchBar.view setTranslatesAutoresizingMaskIntoConstraints:NO];

// Set the layout anchors
[self.navigationItem.titleView.widthAnchor constraintEqualToConstant:250.0].active = YES; // Had to set the width to a constant
// Was still causing problems
//[self.navigationItem.titleView.widthAnchor constraintEqualToAnchor:self.navigationController.navigationBar.widthAnchor multiplier:1.0/3.0].active = YES;// Still need to access the navigation bar's anchor
[self.navigationItem.titleView.heightAnchor constraintEqualToConstant:50.0].active = YES;