Ios 自定义右巴布托教派正在消失

Ios 自定义右巴布托教派正在消失,ios,uitabbarcontroller,custom-controls,uinavigationbar,rightbarbuttonitem,Ios,Uitabbarcontroller,Custom Controls,Uinavigationbar,Rightbarbuttonitem,我有一个奇怪的错误,导航栏上有一个自定义的右按钮。我有一个TabBar应用程序。如果应用程序已加载,则按钮显示正确。如果我点击标签,按钮会一直显示。如果我回到一个已经显示的选项卡,按钮就会消失。最后,按钮仅在其中一个选项卡中随机显示 如果我以编程方式设置一个标准的rightBarButtomItem,我的代码就可以完美地工作。但不能使用自定义图形。如果按下并弹出ChildViewController,则该按钮将再次出现。它似乎还在那里,但看不见 我认为我在CustomTabBarViewCont

我有一个奇怪的错误,导航栏上有一个自定义的右按钮。我有一个TabBar应用程序。如果应用程序已加载,则按钮显示正确。如果我点击标签,按钮会一直显示。如果我回到一个已经显示的选项卡,按钮就会消失。最后,按钮仅在其中一个选项卡中随机显示

如果我以编程方式设置一个标准的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
我在每个视图中都这样设置按钮:

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

}

给我留下深刻印象的是,为每个视图控制器创建一个新的
CustomTabBarController
从根本上来说是错误的,特别是如果它是为了解决右键没有出现的问题。问题是您正在创建新的虚拟选项卡栏控制器,更糟糕的是,丢失了对视图控制器的真实选项卡栏控制器的引用

您的解决方案触及了问题的核心,即,由于您正在为按钮添加子视图,即使用
initWithCustomView
创建
uiBarButtonim
,因此无法与多个导航控制器共享按钮。如果您使用
initWithTitle
(或其他类似的简单变体)创建一个简单的
uiBarButtonim
,则共享的公共右栏按钮可以工作,但如果您使用按钮的自定义视图来执行此操作,则无法工作

正确的解决方案是创建一个新的
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];
}

所有这些都实现了您提出的解决方案的关键部分,即确保我们拥有右栏按钮项的唯一实例,但不存在创建冗余选项卡栏控制器的问题。

尝试在ViewWillAppear或ViewDidAppearth中设置按钮,这是我第一次尝试。那也没用。TabBarController似乎有问题。但我不知道。我现在已经更改了代码,它工作得非常好!再次感谢大家!!!在我看来,您的代码比我的代码更清晰:您将接口和属性定义放在实现文件中。我以前见过,但不确定这有什么不同。另一件事是使用uderscore属性,比如_BadgeViewvs.badgeView。我以前也见过,但不明白。你能给我一个解释它的链接吗?@rockstarberlin-将一些属性定义放在.m文件中的想法(在所谓的“私有类扩展名”中)将.h文件限制为其他类所需的公共接口,并将私有实现的所有详细信息保留在.m文件中。它在功能上是相同的(就.m文件而言),但是在将来的某个日期使用该类时,它会更干净、更容易混淆。我还注意到您有一些只在初始化期间需要的属性,所以我只创建了那些局部变量(或完全删除了该变量)。@rockstarberlin如果是uuu变量,微妙的问题是您不应该在初始化器方法中使用访问器方法(self.前缀)。看见
- (void)viewDidLoad
{
    [super viewDidLoad];

    CustomTabBarController *tabBarController = (id)self.tabBarController;

    self.navigationItem.rightBarButtonItem = [tabBarController rightBarButton];
}