自定义rightBarButtonItem消失

我在NavBar中有一个自定义的RightBarButtomItem的奇怪的错误。 我有一个TabBar应用程序。 如果该应用程序已加载button显示正确。 如果我点击标签button不断显示。 如果我回到已经显示的标签之一,button消失。 最后,button只在其中一个标签中随机显示。

我的代码完美工作,如果我设置一个标准的rightBarButtomItem编程。 但不是自定义graphics。 如果一个ChildViewController被按下并popup,该button再次出现。 它似乎仍然存在但不可见!

我认为我在CustomTabBarViewController中的sharedRightButton的引用是错误的!

任何人都可以帮忙吗?

CustomTabBarController.h

#import <UIKit/UIKit.h> #import "EZBadgeView.h" @interface CustomTabBarController : UITabBarController { EZBadgeView *badgeView; UIButton *btn; UIImage *rightBarButtonItemImage; UIImage *rightBarButtonItemImageTapped; UIImage *rightBarButtonItemImageSelected; } @property (nonatomic, strong) UIBarButtonItem *sharedRightButton; @property (nonatomic, strong) EZBadgeView *badgeView; @property(nonatomic, strong) UIButton *btn; @property(nonatomic, strong) UIImage *rightBarButtonItemImage; @property(nonatomic, strong) UIImage *rightBarButtonItemImageTapped; @property(nonatomic, strong) UIImage *rightBarButtonItemImageSelected; @end 

CustomTabBarController.m

  #import "CustomTabBarController.h" @interface CustomTabBarController () @end @implementation CustomTabBarController @synthesize sharedRightButton, badgeView, btn, rightBarButtonItemImage, rightBarButtonItemImageSelected, rightBarButtonItemImageTapped; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateBadgeNumber:) name:@"updateBadgeNumber" object:nil]; if (self.badgeView && self.badgeView.superview) { [self.badgeView removeFromSuperview]; } self.badgeView = [[EZBadgeView alloc] init]; CGRect badgeFrame = self.badgeView.frame; badgeFrame.origin.x = 31.0f; badgeFrame.origin.y = -6.0f; badgeFrame = CGRectIntegral(badgeFrame); self.badgeView.frame = badgeFrame; self.badgeView.badgeBackgroundColor = [self colorWithRGBHex:kRed withAlpha:1.0f]; self.badgeView.userInteractionEnabled = NO; self.badgeView.badgeTextFont = [UIFont fontWithName:@"BrownStd-Bold" size:12]; self.badgeView.shouldShowGradient = NO; self.badgeView.shouldShowShine = NO; // Allocate UIButton self.btn = [UIButton buttonWithType:UIButtonTypeCustom]; self.btn.frame = CGRectMake(0, 0, 46, 30); self.rightBarButtonItemImage = [UIImage imageNamed:@"button_mixer.png"]; [self.btn setBackgroundImage:rightBarButtonItemImage forState:UIControlStateNormal]; self.rightBarButtonItemImageTapped = [UIImage imageNamed:@"button_mixer_pressed.png"]; [self.btn setBackgroundImage:rightBarButtonItemImageTapped forState:UIControlStateHighlighted]; self.rightBarButtonItemImageSelected = [UIImage imageNamed:@"button_mixer_active.png"]; [self.btn setBackgroundImage:rightBarButtonItemImageSelected forState:UIControlStateSelected]; [self.btn addTarget:self action:@selector(clickedTest:) forControlEvents:UIControlEventTouchUpInside]; [self.btn setBackgroundColor:[UIColor clearColor]]; [self.btn addSubview:self.badgeView]; //Add NKNumberBadgeView as a subview on UIButton // Initialize UIBarbuttonitem... self.sharedRightButton = [[UIBarButtonItem alloc] initWithCustomView:btn]; self.badgeView.badgeValue = @"0"; self.badgeView.hidden = YES; } - (void)updateBadgeNumber:(NSMutableArray *)soundArray { self.badgeView.badgeValue = [NSString stringWithFormat:@"%i",[soundArray count]]; self.badgeView.hidden = ([soundArray count] == 0); } - (void)clickedTest:(id)sender { NSLog(@"%s", __FUNCTION__); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (UIColor *)colorWithRGBHex:(UInt32)hex withAlpha:(float)alpha { int r = (hex >> 16) & 0xFF; int g = (hex >> 8) & 0xFF; int b = (hex) & 0xFF; return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:alpha]; } @end 

我在每个视图中都像这样设置button:

 @implementation MyVC @synthesize tabBarController; - (void)viewDidLoad { //NSLog(@"begin: %s", __FUNCTION__); [super viewDidLoad]; // right bar button from custom tabbarcontroller self.tabBarController = [[CustomTabBarController alloc] init]; self.navigationItem.rightBarButtonItem = self.tabBarController.sharedRightButton; } 

这让我觉得,为每个视图控制器创build一个新的CustomTabBarController是根本错误的,尤其是如果它是要解决你的右键没有出现的问题。 问题是你正在创build新的幻影标签栏控制器,更糟糕的是,失去了对视图控制器的真正标签栏控制器的引用。

你的解决scheme到达了问题的核心,那就是因为你正在为你的button添加子视图,也就是用initWithCustomView创buildUIBarButtonItem等,所以你不能与多个导航控制器共享button。 如果使用initWithTitle (或其他简单的变体)创build一个简单的UIBarButtonItem ,共享的常用右键button就可以工作,但是如果使用自定义button来实现这一点,则不起作用。

正确的解决scheme是创build一个新的UIBarButtonItem实例,具有您需要的行为和外观。 然后,任何需要该栏button项的视图控制器都可以创build该button的一个实例。 因此,新的自定义RightBarButtonItem可能如下所示:

RightBarButtonItem.h:

 @interface RightBarButtonItem : UIBarButtonItem - (id)initWithTarget:(id)target action:(SEL)action; @end 

RightBarButtonItem.m:

 @interface RightBarButtonItem () @property (nonatomic, strong) EZBadgeView *badgeView; @end @implementation RightBarButtonItem - (id)initWithTarget:(id)target action:(SEL)action { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(0, 0, 46, 30); self = [super initWithCustomView:button]; if (self) { _badgeView = [[EZBadgeView alloc] init]; CGRect badgeFrame = self.badgeView.frame; badgeFrame.origin.x = 31.0f; badgeFrame.origin.y = -6.0f; badgeFrame = CGRectIntegral(badgeFrame); _badgeView.frame = badgeFrame; _badgeView.badgeBackgroundColor = [self colorWithRGBHex:kRed withAlpha:1.0f]; _badgeView.userInteractionEnabled = NO; _badgeView.badgeTextFont = [UIFont fontWithName:@"BrownStd-Bold" size:12]; _badgeView.shouldShowGradient = NO; _badgeView.shouldShowShine = NO; [button setBackgroundImage:[UIImage imageNamed:@"button_mixer.png"] forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage imageNamed:@"button_mixer_pressed.png"] forState:UIControlStateHighlighted]; [button setBackgroundImage:[UIImage imageNamed:@"button_mixer_active.png"] forState:UIControlStateSelected]; [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; [button setBackgroundColor:[UIColor clearColor]]; [button addSubview:_badgeView]; //Add NKNumberBadgeView as a subview on UIButton _badgeView.badgeValue = @"0"; _badgeView.hidden = YES; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateBadgeNumber:) name:@"updateBadgeNumber" object:nil]; } return self; } - (void)dealloc { // don't forget to have mechanism to remove the observer when this button is deallocated [[NSNotificationCenter defaultCenter] removeObserver:self name:@"updateBadgeNumber" object:nil]; } - (void)updateBadgeNumber:(NSMutableArray *)soundArray { self.badgeView.badgeValue = [NSString stringWithFormat:@"%i",[soundArray count]]; self.badgeView.hidden = ([soundArray count] == 0); } - (UIColor *)colorWithRGBHex:(UInt32)hex withAlpha:(float)alpha { int r = (hex >> 16) & 0xFF; int g = (hex >> 8) & 0xFF; int b = (hex) & 0xFF; return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:alpha]; } @end 

然后, CustomTabBarController被大大简化:

CustomTabBarController.h:

 @interface CustomTabBarController : UITabBarController - (UIBarButtonItem *)rightBarButton; @end 

CustomTabBarController.m:

 #import "RightBarButtonItem.h" @implementation CustomTabBarController - (UIBarButtonItem *)rightBarButton { return [[RightBarButtonItem alloc] initWithTarget:self action:@selector(clickedTest:)]; } - (void)clickedTest:(id)sender { NSLog(@"%s", __FUNCTION__); } @end 

最后,所有添加到标签栏控制器的视图控制器都可以简单地执行:

 - (void)viewDidLoad { [super viewDidLoad]; CustomTabBarController *tabBarController = (id)self.tabBarController; self.navigationItem.rightBarButtonItem = [tabBarController rightBarButton]; } 

所有这一切都实现了您提出的解决scheme的关键部分,即确保我们拥有正确的条形button项目的唯一实例,但没有创build冗余的选项卡栏控制器的问题。