0

У меня странная ошибка с пользовательским rightBarButtomItem в NavBar. У меня есть приложение TabBar. Если приложение загружено, кнопка отображается правильно. Если я нажимаю вкладки, кнопка продолжает показывать. Если я вернусь к одной из вкладок, которые уже были показаны, кнопка исчезает. В конце кнопка отображается только случайно на одной из вкладок.Пользовательский rightBarButtonItem исчезает

Мой код работает отлично, если я программно программировал стандартный элемент rightBarButtomItem. Но не с пользовательской графикой. Если ChildViewController нажат и появится, кнопка снова появится. Кажется, он все еще там, но не видно!

Я думаю, что мои ссылки на sharedRightButton в CustomTabBarViewController ошибочны!

Может ли кто-нибудь помочь?

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 –

+0

Это было первое, что я пробовал. Это тоже не сработало. Кажется, что проблема с TabBarController. Но я не знаю. – rockstarberlin

ответ

1

мне кажется, что создание нового CustomTabBarController для каждого контроллера представления принципиально неправильно, особенно если это необходимо проблема в том, что ваша правая кнопка не появляется. Проблема в том, что вы создаете новые, фантомные контроллеры панели вкладок и, что еще хуже, теряете ссылку на реальный контроллер панели ввода контроллера.

Ваше решение попадает в ядро ​​проблемы, а это потому, что вы добавляете subviews для своей кнопки, а именно создаете с initWithCustomView и т. Д., Что вы не можете поделиться кнопкой с несколькими навигационными контроллерами. Кнопка общей общей кнопки справа работает, если вы создаете простой UIBarButtonItem с initWithTitle (или другими простыми вариантами), но это не сработает, если вы сделаете это с настраиваемым представлением для своей кнопки.

Правильным решением является создание нового экземпляра 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.м:

#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

+0

Теперь я изменил свой код, и он отлично работает! большое спасибо! один вопрос у меня, как я вижу, ваш код намного чище, чем мой: вы помещаете интерфейс и определение свойства в файл реализации. Я видел это раньше, но не был уверен, какая разница. Другое дело, используя свойство с uderscore, как _badgeView и badgeView. Я тоже это видел, но не понимаю. Не могли бы вы предоставить мне ссылку, где это объясняется? – rockstarberlin

+1

@rockstarberlin. Идея поместить некоторые определения свойств в файл .m (в так называемом «расширении частного класса») заключается в том, чтобы ограничить файл .h для тех общедоступных интерфейсов, которые необходимы другим классам и сохранить все детали gory частной реализации в файле .m. Это функционально то же самое (что касается файла .m), но он чище и менее запутанным, когда вы идете использовать класс в какой-то будущий день. Я также заметил, что у вас есть некоторые свойства, которые вам нужны только во время инициализации, поэтому я просто сделал эти локальные переменные (или полностью избавился от переменной). – Rob

Смежные вопросы