0

我在NavBar中有一個自定義rightBarButtomItem的奇怪錯誤。我有一個TabBar應用程序。如果應用程序已加載,則按鈕顯示正確。如果我點擊按鈕不斷顯示的標籤。如果我回到已經顯示的其中一個標籤,按鈕消失。最後,按鈕僅在其中一個選項卡中隨機顯示。自定義rightBarButtonItem正在消失

我的代碼完美工作,如果我以編程方式設置標準的RightBarButtomItem。但不適用於自定義圖形。如果一個ChildViewController被按下並彈出,該按鈕再次出現。它似乎仍然存在,但不可見!

我認爲我在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 

而且我設置的按鈕一樣,在每個視圖:

@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; 

} 
+0

嘗試在ViewWillAppear或ViewDidAppear中設置按鈕 – 2013-02-20 02:56:32

+0

這是我第一次嘗試。那也沒用。看起來TabBarController存在問題。但我不知道。 – rockstarberlin 2013-02-20 03:02:39

回答

1

我感到那創造一個新CustomTabBarController對於每個視圖控制器來說都是根本錯誤的,特別是如果要解決的話右鍵沒有出現的問題。問題在於您正在創建新的幻像標籤欄控制器,更糟糕的是,失去了對視圖控制器的真正標籤欄控制器的引用。

您的解決方案涉及到問題的核心問題,這是因爲您要爲按鈕添加子視圖,即創建UIBarButtonIteminitWithCustomView等,您無法與多個導航控制器共享該按鈕。如果您使用initWithTitle(或其他簡單變體)創建了一個簡單的UIBarButtonItem,但共享的常用右鍵按鈕可以正常工作,但如果您使用自定義按鈕進行操作,則該按鈕不起作用。

正確的解決方案是創建一個具有所需行爲和外觀的新實例UIBarButtonItem。然後,任何需要該欄按鈕項的視圖控制器都可以創建該按鈕的一個實例。因此,新的自定義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。L:

#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]; 
} 

所有這一切都實現了你提出的解決方案的重要組成部分,即確保我們有一個正確的條形按鈕項目的獨特實例,但沒有創建多餘的選項卡欄控制器的問題。

+0

好吧,我會稍後再試!感謝您的幫助! – rockstarberlin 2013-02-20 17:06:23

+0

我已經改變了我的代碼,它完美的工作!再一次非常感謝你!!!我有一個問題,因爲我看到你的代碼比我的清晰得多:你將接口和屬性定義放在實現文件中。我之前看到過,但不知道它有什麼不同。另一件事是使用像_badgeView與badgeView的uderscore屬性。我之前也看到過,但不瞭解它。你能否給我提供一個解釋它的鏈接? – rockstarberlin 2013-02-21 03:31:31

+1

@rockstarberlin - 將一些屬性定義放入.m文件(在所謂的「私人類擴展名」中)的想法是將.h文件限制爲其他類所需的公共接口,並保留所有的細節.m文件中的私有實現。它的功能是一樣的(只要.m文件可以),但是當你在將來的某個日子使用這個類時,它會更乾淨,更容易混淆。我還注意到,你有一些你在初始化時只需要的屬性,所以我只是做了那些局部變量(或者完全擺脫了變量)。 – Rob 2013-02-21 03:50:00