自定义背景指示图像和iOS 11

我在我的应用程序中使用自定义后退button。 这个自定义后退button是这样设置的:

UINavigationBar.appearance().backIndicatorImage = UIImage(named: "Back").withRenderingMode(.alwaysOriginal) UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(asset: .back).withRenderingMode(.alwaysOriginal) 

在iOS 11之前,这段代码实现了这个诀窍,但现在在iOS 11中,button不再是垂直居中了,如下所示:

在这里输入图像说明

我可以将后退button图像的高度更改为44,但这会在iOS <11中破坏它。我也可以使用两个不同的图像,但是我正在寻找更干净的东西,例如将图像垂直居中button容器视图。

编辑:

原来,正如banxii1988所说的那样,这个问题是由setBackButtonTitlePositionAdjustment引起的,当值故意将标题移动到可见屏幕之外。 这是一个黑客,以避免在每个视图控制器中删除后退button标题。 我决定删除这个黑客​​,我做了正确的事情是:

  1. 将故事板中的后退button项目设置为" "
  2. 在每个视图控制器没有关联的故事板,我以编程方式设置backBarButtonItem navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

请注意,在视图控制器中看到的后退button标题在导航堆栈中的前一个标题中设置。

1)如果有任何移除PositionAdjustment。 如

  bap.setBackButtonTitlePositionAdjustment(UIOffset(horizontal: 0, vertical: -64), for: .default) 

2)检查导航堆栈中的前一个ViewController是否有标题

我觉得这个方法可以! 这对我有用。

 if(@available(iOS 11, *)) { [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal]; [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateHighlighted]; } else { [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60) forBarMetrics:UIBarMetricsDefault]; } 

对于任何无法解决的问题:

1)在你的项目(cmd + shift + f)中search“setBackButtonTitle”,你会发现如下代码:

 [[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[xController class]]] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault]; 

2)用这个更改上面的代码:

 [[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[xController class]]] setBackButtonTitlePositionAdjustment:UIOffsetMake(-200, 0) forBarMetrics:UIBarMetricsDefault]; 

从iOS 11开始,上面的代码我们用来隐藏button标题,随着标题本身一起移回button。 但是,如果你只是水平移动后退button的标题,一切正常,没有backdraws。

经过几次尝试失败,这对我们的iOS 11工作:

 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-200, -5) forBarMetrics:UIBarMetricsDefault]; 

诀窍是将x轴上的“返回”文本移回很多,并在y轴上移动一点,因为setBackButtonTitlePositionAdjustment结果是影响图像和文本。

但是,我们不知道这个解决scheme能工作多久,它可能随时由苹果“固定”

我会build议方法swizzling来解决它,我已经在我的一些项目中使用这个解决scheme,它工作正常。

1 – 创build一个UIViewController的类别。

2-import#import <objc/runtime.h>

3-粘贴以下方法

 #import "UIViewController+Extras.h" #import <objc/runtime.h> @implementation UIViewController (Extras) + (void)load { static dispatch_once_t once_token; dispatch_once(&once_token, ^{ SEL viewDidLoadSelector = @selector(viewDidLoad); SEL viewDidLoadModifyBackButtonSelector = @selector(modifyBackButton_viewDidLoad); Method originalMethod = class_getInstanceMethod(self, viewDidLoadSelector); Method extendedMethod = class_getInstanceMethod(self, viewDidLoadModifyBackButtonSelector); method_exchangeImplementations(originalMethod, extendedMethod); }); } - (void)modifyBackButton_viewDidLoad { [self modifyBackButton_viewDidLoad]; self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil]; } @end 
 if(@available(iOS 11, *)) { [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal]; [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateHighlighted]; } else { [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60) forBarMetrics:UIBarMetricsDefault]; } 

上面的解决scheme由@Tonin工作,但唯一的担心是导航栏左键文本(如“取消”)是透明的(清晰的颜色)时,共享到其他应用程序(电子邮件,消息等),翻转颜色,如果需要共享function:

 UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[title, URL] applicationActivities:nil]; [activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) { // set clear color when back from share [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal]; }]; [self presentViewController:activityViewController animated:YES completion:^{ // set white color when share to other app [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateNormal]; }]; 

适用于SWIFT 3+

  if #available(iOS 11, *) { UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal) UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .highlighted) } else { UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), for:UIBarMetrics.default) } 

这个解决scheme适用于iOS 9,10和11

  var backButtonImage: UIImage = UIImage(named: "backButton")! UINavigationBar.appearance().backIndicatorImage = backButtonImage UINavigationBar.appearance().backIndicatorTransitionMaskImage = backButtonImage if #available(iOS 11, *) { UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-300, 0), for:UIBarMetrics.default) } else { UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -200), for:UIBarMetrics.default) }