UIBarButtonItem在用作左侧或右侧导航栏项目时,自定义视图未在iOS 7上正确对齐

jar*_*air 75 uinavigationbar uibutton uibarbuttonitem uinavigationitem ios7

以下代码通过iOS 6运行:

UIButton *myButton = nil;
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
myButton.bounds = CGRectMake(0,0,44,30);
// setup myButton's images, etc.

UIBarButtonItem *item = nil;
item = [[UIBarButtonItem alloc] initWithCustomView:customButton];
Run Code Online (Sandbox Code Playgroud)

这是按钮应该如何对齐:

正常定位

但是,在iOS 7上,按钮似乎从右侧或左侧偏移了太多像素:

iOS 7上的定位不正确

如何才能使我的自定义条形按钮项目正确对齐?

mal*_*lex 67

适用于iOS11!

您可以使用负灵活空格和rightBarButtonItems属性而不是rightBarButtonItem:

UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
spacer.width = -10; // for example shift right bar button to the right

self.navigationItem.rightBarButtonItems = @[spacer, yourBarButton];
Run Code Online (Sandbox Code Playgroud)

  • 它违反了人机界面指南.这就是为什么它不可定制的原因.他们希望你不要管它.对于不阅读指南的设计人员来说,这是一个问题. (3认同)
  • 我无法理解为什么我们要破解这么简单的东西......至少已经存在了一年.没有解决方案Apple? (2认同)

jar*_*air 57

为了修复此错误,您必须子类化UIButton以便您可以覆盖alignmentRectInsets.根据我的测试,您需要返回具有正向右偏移或正向左偏移的UIEdgeInsets,具体取决于按钮位置.这些数字对我来说没有任何意义(根据常识,至少其中一个应该是负数),但这实际上是有效的:

- (UIEdgeInsets)alignmentRectInsets {
    UIEdgeInsets insets;
    if (IF_ITS_A_LEFT_BUTTON) {
        insets = UIEdgeInsetsMake(0, 9.0f, 0, 0);
    } 
    else { // IF_ITS_A_RIGHT_BUTTON
        insets = UIEdgeInsetsMake(0, 0, 0, 9.0f);
    }
    return insets;
}
Run Code Online (Sandbox Code Playgroud)

特别感谢@zev建议我尝试调整alignmentRectInsets.

  • 这可以工作,但是当我从导航堆栈中弹出一个视图并且它"返回"动画时,按钮仍然错误地偏移大约半秒钟,然后它跳转到正确的位置.知道如何防止这种情况发生吗? (3认同)

Bas*_*CAD 28

我已经尝试了上面的所有答案,但对我来说没有任何效果.这是有效的,如果有人需要这个:

(不需要子类化)

// Add your barButtonItem with custom image as the following 
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:self action:@selector(categoryButtonPressed)];
// set your custom image
[barButton setImage:categoryImage];
// finally do the magic
barButton.imageInsets = UIEdgeInsetsMake(0.0, -20, 0, 0);
Run Code Online (Sandbox Code Playgroud)

- 看看结果.

注意左侧按钮和右侧按钮的空格(右侧按钮具有默认行为)

在此输入图像描述


Chr*_*ner 10

Ok, I went the other "direction". I made everything line up properly via Storyboard with iOS 7 (assuming this is how it will continue to work). And then using the describe sub-class approach, I sub-class UIButton with the following implementation.

- (UIEdgeInsets)alignmentRectInsets {
    UIEdgeInsets insets;
    if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
        if ([self isLeftButton]) {
            insets = UIEdgeInsetsMake(0, -10, 0, 0);
        } else {
            insets = UIEdgeInsetsMake(0, 0, 0, -10);
        }
    } else {
        insets = UIEdgeInsetsZero;
    }

    return insets;
}

- (BOOL)isLeftButton {
    return self.frame.origin.x < (self.superview.frame.size.width / 2);
}
Run Code Online (Sandbox Code Playgroud)

So this code only runs if the device is pre-iOS 7.

Thanks for the insight @jaredsinclair!