0

NavBar のカスタム rightBarButtomItem に奇妙なバグがあります。TabBar アプリケーションがあります。アプリが読み込まれている場合、ボタンは正しく表示されます。タブをクリックすると、ボタンが表示され続けます。すでに表示されているタブの 1 つに戻ると、ボタンが消えます。最後に、ボタンはいずれかのタブにランダムに表示されます。

プログラムで標準の 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;

}
4

1 に答える 1

1

CustomTabBarController特に右ボタンが表示されないという問題を解決する場合は特に、ビューコントローラーごとに新しいものを作成することは根本的に間違っていると思います。問題は、新しいファントム タブ バー コントローラーを作成していることです。さらに悪いことに、ビュー コントローラーの実際のタブ バー コントローラーへの参照が失われています。

あなたの解決策は問題の核心に到達します。つまり、ボタンのサブビューを追加しているため、つまりUIBarButtonItemwithinitWithCustomViewなどを作成しているため、ボタンを複数のナビゲーションコントローラーと共有できないということです。共有された共通の右バー ボタンは、単純なUIBarButtonItemwith 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];
}

これらすべてにより、提案されたソリューションの重要な部分が達成されます。つまり、冗長なタブ バー コントローラーを作成する問題を回避しながら、右側のバー ボタン項目の一意のインスタンスを確保することができます。

于 2013-02-20T13:23:45.703 に答える