垂直对齐 UINavigationItems

Posted

技术标签:

【中文标题】垂直对齐 UINavigationItems【英文标题】:vertically aligning UINavigationItems 【发布时间】:2011-07-03 23:37:27 【问题描述】:

我已将 UINavigationBar 的高度自定义为 100 像素,我想在此自定义栏上添加按钮。

一切都很好,只是按钮似乎无论如何都想坐在导航栏的底部。我无法让它与导航栏的中心或顶部对齐。

这里是代码;首先我在应用委托中创建一个导航控制器,并在右侧添加一个按钮。

// set main navigation controller
temp *tempc = [[temp alloc] initWithNibName:@"temp" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tempc];

UIBarButtonItem *navItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];

[tempc.navigationItem setRightBarButtonItem:navItem];
[self.window addSubview:self.navigationController.view];
[self.window makeKeyAndVisible];

然后我在“临时”视图控制器中调整导航栏的大小,如下所示:

- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 100.0f);
    [self.navigationController.navigationBar setFrame:frame];
    [self.navigationController.navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin];

我也尝试向 rightBarButtonItem 添加自定义视图,但无法让添加的自定义视图完全触及顶部。

以及这次不幸尝试的代码:

// set main navigation controller
temp *tempc = [[temp alloc] initWithNibName:@"temp" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tempc];

UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 36.0f, 80.0f)];
[customView setBackgroundColor:[UIColor blueColor]];

UIButton *customButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[customButton setFrame:CGRectMake(0, 22.0f, 36.0f, 36.0f)];
[customButton setTitle:@"+" forState:UIControlStateNormal];

[customView addSubview:customButton];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithCustomView:customView];

有谁知道如何在 UINavigationBar 上垂直对齐 UIBarButtonItems?

【问题讨论】:

【参考方案1】:

这会将页面标题和所有按钮向上移动 20 像素:

[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-20.0 forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundVerticalPositionAdjustment:-20.0 forBarMetrics:UIBarMetricsDefault];

【讨论】:

这段代码放在哪里?我把它放在 viewDidLoad 中,没有任何反应 在应用程序中委托给 didFinishLaunchingWithOptions @kraag22 你有在UIBarButtonItem 的实例上使用这个的例子吗,例如[_myBarButtonItem setTitleVerticalPositionAdjustment:-20.0 forBarMetrics:UIBarMetricsDefault]; - 我似乎无法让它工作。【参考方案2】:

如果您只有rightBarButtonItem 并且没有剩余,则当前接受的来自 alhcr 的答案(选项 1)不起作用。它还对 UINavigationBar 的子视图排序进行了假设,这并不能保证,并且很可能在未来的 ios 版本中发生变化。这是自定义导航按钮框架的更好方法:

// UINavigationBar subclass

- (void)layoutSubviews 

    [super layoutSubviews];

    UINavigationItem *navigationItem = [self topItem];

    for (UIView *subview in [self subviews]) 

        if (subview == [[navigationItem rightBarButtonItem] customView]) 

            CGRect newRightButtonRect = CGRectMake(...new rect...);
            [subview setFrame:newRightButtonRect];
        
        else if (subview == [[navigationItem backBarButtonItem] customView]) 

            CGRect newBackButtonRect = CGRectMake(...new rect...);
            [subview setFrame:newBackButtonRect];
        
    

【讨论】:

但这也会自动改变 Titleview 的框架。 also 我如何设置横向和纵向的框架? 这会在 iOS 8 及更高版本上导致无限循环,因为导航项使用自动布局。【参考方案3】:

选项 1:

创建 UINavigationBar 子类 在此类中覆盖 - (void)layoutSubviews,您将在其中重新定位 UIBarButtonItems 在 Interface Builder 中将 UINavigationBar 类设置为 UINavigationBar 子类

例子:

UINavigationBar 的子类内部:

- (void)layoutSubviews 
    int index = 0;
    for ( UIButton *button in [self subviews] ) 
        if(index == 1) 
            [button setFrame:CGRectMake(5,40,60,40)]; //leftBarButtonItem
         else if(index == 2) 
            [button setFrame:CGRectMake(275,40,40,40)]; //rightBarButtonItem
        
        ++index;
    

视图控制器:

- (void)viewDidLoad 
...
    UIBarButtonItem *navItem1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
    UIBarButtonItem *navItem2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:nil action:nil];
    [self.navigationItem setRightBarButtonItem:navItem1];   
    [self.navigationItem setLeftBarButtonItem:navItem2];

    CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 100.0f);
    [self.navigationController.navigationBar setFrame:frame];
...

选项 2(插入 UIBarButtonItem 不起作用):

UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,320,100)];
[self.view addSubview:navigationBar];

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(0,25,50,50)];
[navigationBar addSubview:button];

【讨论】:

感谢您为我指明正确的方向!我没有对 UINavigationBar 进行子类化,而是创建了一个类别并将选项 1 中的代码添加到 (void)drawRect:(CGRect)rect 而不是 layoutSubviews。出于某种原因,如果我尝试修改 layoutSubviews 中按钮的框架,titleView 将保持向左对齐而不是居中。【参考方案4】:

我通过在自定义按钮的 Image Edge Insets 中进行调整找到了解决此问题的方法。我在应用程序中要求增加导航栏的高度,增加高度后会导致 rightBarButtonItem 和 leftBarButtonItem 图像未定位问题。

找到下面的代码:-

UIImage *image = [[UIImage imageNamed:@"searchbar.png"];
UIButton* searchbutton = [UIButton buttonWithType:UIButtonTypeCustom];
[searchbutton addTarget:self action:@selector(searchBar:) forControlEvents:UIControlEventTouchUpInside]; 
searchbutton.frame = CGRectMake(0,0,22, 22);
[searchbutton setImage:image forState:UIControlStateNormal];
[searchbutton setImageEdgeInsets:UIEdgeInsetsMake(-50, 0,50, 0)];
// Make BarButton Item
 UIBarButtonItem *navItem = [[UIBarButtonItem alloc] initWithCustomView:searchbutton];
self.navigationItem.rightBarButtonItem = navItem;

【讨论】:

以上是关于垂直对齐 UINavigationItems的主要内容,如果未能解决你的问题,请参考以下文章

text 只需一行SCSS就可以垂直和水平对齐或只是垂直对齐,它同时支持两者。

左对齐的水平堆栈视图和顶部对齐的垂直堆栈视图

RichEdit 垂直文本对齐

与边距水平对齐,同时不丢失垂直对齐

跨越与浮动垂直对齐

iOS 7后退按钮箭头垂直对齐