如何处理 iOS 11 Navigation BarButtonItems 错误?

Posted

技术标签:

【中文标题】如何处理 iOS 11 Navigation BarButtonItems 错误?【英文标题】:How to handle iOS 11 Navigation BarButtonItems bug? 【发布时间】:2017-07-04 02:21:28 【问题描述】:

我在 ios 11 中发现了一个 UINavigationBar 错误。首先使用 self.navigationItem.rightBarButtonItems = @[fixSpaceItem, item] 在 vi​​ewDidLoad 中设置导航项按钮。并使用手势弹回,但我并没有真正弹回,当弹回开始时,我松开手指并让视图控制器取消弹回,然后右导航按钮项消失。左边的项目按钮有同样的问题。要重现此错误,您必须添加 fixSpaceItem,如 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]。真实设备而不是模拟器可以重现该错误。 这是我的主要代码:

- (void)viewDidLoad 
    [super viewDidLoad];

    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;

    self.navigationItem.rightBarButtonItems = @[[self negativeSpacerWithWidth:5],[self rightButton]];
    self.navigationItem.leftBarButtonItems = @[[self negativeSpacerWithWidth:5], [self leftButton]];



- (UIBarButtonItem *)leftButton 
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
    [button setImage:[UIImage imageNamed:@"icon_app_back_normal"] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
    return item;


- (UIBarButtonItem *)rightButton 
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
    [button setImage:[UIImage imageNamed:@"setting"] forState:UIControlStateNormal];
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
    return item;


- (UIBarButtonItem *)negativeSpacerWithWidth:(CGFloat)width 
    UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    [spacer setWidth:width];
    return spacer;

【问题讨论】:

即使没有固定空间,我也看到了同样的结果。在我的情况下,导航栏会更新为您要弹出的视图控制器的导航项,但当您取消弹出中间手势时,它永远不会恢复为当前的视图控制器导航项。希望它在下一个测试版中得到解决。 【参考方案1】:

当您将FixedSpace BarButtonItem 添加到BarButtonItem array 时,这似乎是一个错误。如果你想给导航项设置偏移量,可能还得用其他方式,比如改变按钮的imageEdgeInsets。

- (void)viewDidLoad 
    [super viewDidLoad];

    // Do not set Fixed Space type button item.
    self.navigationItem.leftBarButtonItem = [self leftButton];
    self.navigationItem.rightBarButtonItem = [self rightButton];

    // It work too
    //self.navigationItem.leftBarButtonItems = @[[self leftButton], [self leftButton]];
    //self.navigationItem.rightBarButtonItems = @[[self rightButton], [self rightButton]];


    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;


- (UIBarButtonItem *)leftButton

    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
    //...

    // to add offset you want
    button.imageEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 15);

    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
    return item;


- (UIBarButtonItem *)rightButton

    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
    //...

    // to add offset you want
    button.imageEdgeInsets = UIEdgeInsetsMake(0, 15, 0, -15);

    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
    return item;

【讨论】:

【参考方案2】:
let hamButtonWidthConstraint = hamButton.widthAnchor.constraint(equalToConstant: 40)

let hamButtonHeightConstraint = hamButton.heightAnchor.constraint(equalToConstant: 40)

hamButtonWidthConstraint.isActive = true

hamButtonHeightConstraint.isActive = true

【讨论】:

【参考方案3】:

我尝试调整图像的大小以使其适合导航项,并且效果很好。虽然您不需要实际调整图像大小,但您可以使用下面提供的函数在运行时调整图像大小。

    UIImage *imgCart = [self imageWithImage:[UIImage imageNamed:@"ic_cart"] scaledToSize:CGSizeMake(35, 35)] ;
    UIButton *btnCart = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
    [btnCart addTarget:self action:@selector(btnCartClicked:) forControlEvents:UIControlEventTouchUpInside];
    [btnCart setBackgroundImage:imgCart forState:UIControlStateNormal];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btnCart];



-(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize 
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

【讨论】:

以上是关于如何处理 iOS 11 Navigation BarButtonItems 错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 System.Runtime.InteropServices.COMException (0x800706BA):RPC 服务器不可用。 (来自 HRESULT 的异常:0x800706BA

如何处理来自 API 调用的 ios 数据

socket.io:如何处理 4000 个用户?

如何处理所有的贬低

我应该如何处理 iOS 中的 ASIHTTPRequest 异步调用?

如何处理 Socket.io 和 Express 的会话?