Пользовательские права BarButtonItem исчезают
У меня есть странная ошибка с пользовательским rightBarButtomItem в NavBar. У меня есть приложение TabBar. Если приложение загружено, кнопка отображается правильно. Если я нажимаю на вкладки, кнопка продолжает показываться. Если я вернусь к одной из вкладок, которая уже была показана, кнопка исчезнет. В конце кнопка отображается случайным образом только на одной из вкладок.
Мой код работает отлично, если я устанавливаю стандартный 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;
}
1 ответ
Меня поражает, что создание нового CustomTabBarController
для каждого контроллера представления в корне неправильно, особенно если для решения проблемы не отображается ваша правая кнопка. Проблема в том, что вы создаете новые фантомные контроллеры панели вкладок и, что еще хуже, теряете ссылку на реальный контроллер панели вкладок представления.
Ваше решение доходит до сути проблемы, которая заключается в том, что вы добавляете подпредставления для своей кнопки, а именно создаете UIBarButtonItem
с 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.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];
}
Все это достигает критически важной части предложенного вами решения, а именно обеспечения того, чтобы у нас был уникальный экземпляр элемента правой панели кнопок, но без проблемы создания избыточных контроллеров панели вкладок.