本文介绍了自定义rightBarButtonItem消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在NavBar中有一个自定义rightBarButtomItem的奇怪错误。我有一个TabBar应用程序。如果加载了应用程序,则按钮显示正确。如果我点击标签,按钮会一直显示。如果我回到已经显示的其中一个标签,按钮就会消失。最后,按钮只在其中一个标签中随机显示。

I have a strange bug with a custom rightBarButtomItem in the NavBar. I have a TabBar application. If the app is loaded the button shows up correct. If i click through the tabs the button keeps showing. If i go back to one of the tabs which was already shown the button disappears. At the end the button only shows randomly in one of the tabs.

如果我以编程方式设置标准的rightBarButtomItem,我的代码将完美运行。但不是自定义图形。如果按下并弹出ChildViewController,则会再次出现该按钮。它似乎仍然存在但不可见!

My code works perfectly if i set a standard rightBarButtomItem programatically. But not with custom graphics. If a ChildViewController is pushed and popped the button appears again. It seems it is still there but not visible!

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

I think my referencing of the sharedRightButton within the CustomTabBarViewController is wrong!

有人可以提供帮助吗?

CustomTabBarController.h

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

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

我将按钮设置为在每个视图中:

And i set the button like that in each view:

@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 从根本上是错误的,特别是如果要解决你的右键没有出现的问题。问题是你正在创建新的幻像标签栏控制器,更糟糕的是,失去了对视图控制器真实标签栏控制器的引用。

It strikes me that creating a new CustomTabBarController for every view controller is fundamentally wrong, especially if it's to solve the problem that your right button isn't appearing. The issue is that you're creating new, phantom tab bar controllers, and worse, losing the reference to the view controller's real tab bar controller.

你的解决方案到达了这个问题的内核,因为你要为你的按钮添加子视图,即用 initWithCustomView UIBarButtonItem >等,您无法与多个导航控制器共享按钮。如果您使用 initWithTitle (或其他类似的简单变体)创建一个简单的 UIBarButtonItem ,则共享的常用右侧栏按钮有效,但如果您使用按钮的自定义视图执行此操作,则无效。

Your solution gets to the kernel of the problem, which is that, because you're adding subviews for your button, namely creating the UIBarButtonItem with initWithCustomView, etc., that you cannot share the button with multiple navigation controllers. The shared, common right bar button works if you create a simple UIBarButtonItem with initWithTitle (or other simple variations like that), but it doesn't work if you do it with a custom view for your button.

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

The right solution is to create a new UIBarButtonItem instance that has the behavior and appearance that you need. Then, any view controller that needs that bar button item can create an instance of that button. Thus, the new custom RightBarButtonItem might look like:

RightBarButtonItem.h:

RightBarButtonItem.h:

@interface RightBarButtonItem : UIBarButtonItem

- (id)initWithTarget:(id)target action:(SEL)action;

@end

RightBarButtonItem.m:

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:

CustomTabBarController.h:

@interface CustomTabBarController : UITabBarController

- (UIBarButtonItem *)rightBarButton;

@end

CustomTabBarController.m:

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

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

And, finally, all of the view controllers that are added to the tab bar controller, can simply do:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CustomTabBarController *tabBarController = (id)self.tabBarController;

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

所有这些都是您提出的解决方案的关键部分,即确保我们有一个正确的条形按钮项的唯一实例,但没有创建冗余标签栏控制器的问题。

All of this achieves the critical part of your proposed solution, namely to ensure that we have a unique instance of the right bar button item, but without the problem of creating redundant tab bar controllers.

这篇关于自定义rightBarButtonItem消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 05:54