web-dev-qa-db-fra.com

UIBarButtonItem avec une image personnalisée et aucune bordure

Je veux créer un UIBarButtonItem avec une image personnalisée, mais je ne veux pas de la bordure ajoutée par l'iPhone, car mon image a une bordure spéciale.

C'est la même chose que le bouton Précédent, mais un bouton Suivant.

Cette application est pour un projet inHouse, donc je ne me soucie pas de savoir si Apple le rejette, l'approuve ou l'aime :-)

Si j'utilise la propriété initWithCustomView: v de UIBarButtonItem, je peux le faire:

UIImage *image = [UIImage imageNamed:@"right.png"];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage: [image stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateNormal];
[button setBackgroundImage: [[UIImage imageNamed: @"right_clicked.png"] stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateHighlighted];

 button.frame= CGRectMake(0.0, 0.0, image.size.width, image.size.height);

[button addTarget:self action:@selector(AcceptData)    forControlEvents:UIControlEventTouchUpInside];

UIView *v=[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, image.size.width, image.size.height) ];

[v addSubview:button];

UIBarButtonItem *forward = [[UIBarButtonItem alloc] initWithCustomView:v];

self.navigationItem.rightBarButtonItem= forward;

[v release];
[image release];

Cela fonctionne, mais si je dois répéter ce processus dans 10 vues, ce n'est pas DRY.

Je suppose que je dois sous-classe, mais quoi?

  • NSView?
  • UIBarButtonItem?

merci,

cordialement,

88
mongeta

Vous pouvez ajouter une méthode à UIBarButtonItem sans la sous-classer à l'aide de la catégorie personnalisée: 

@interface UIBarButtonItem(MyCategory)

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action;

@end

@implementation UIBarButtonItem(MyCategory)

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action{
 // Move your item creation code here
}
@end

Donc, n'importe où dans votre code, vous pouvez créer un élément de barre appelant cette méthode (à condition d'inclure un en-tête avec sa déclaration).

P.S. Vous n'avez pas besoin d'utiliser 'v' UIView car vous pouvez créer UIBarButtonItem avec un bouton comme vue personnalisée directement.
P.P.S. Vous avez également besoin de [version ultérieure] dans votre code.

44
Vladimir

Une autre solution simple est 

  1. Faites glisser un UIButton standard 
  2. Définissez le style du bouton sur Personnalisé et définissez votre image pour ce bouton
  3. Faites-le glisser sur la barre UINavigation
  4. Set Selector
50
san

J'ai trouvé ça facile. C'est suggéré en haut. "random.png" doit être dans le projet. Il suffit de glisser et déposer une image.

 UIButton *a1 = [UIButton buttonWithType:UIButtonTypeCustom];
        [a1 setFrame:CGRectMake(0.0f, 0.0f, 25.0f, 25.0f)];
        [a1 addTarget:self action:@selector(randomMsg) forControlEvents:UIControlEventTouchUpInside];
        [a1 setImage:[UIImage imageNamed:@"config.png"] forState:UIControlStateNormal];
        UIBarButtonItem *random = [[UIBarButtonItem alloc] initWithCustomView:a1];

 //? line incomplete ?//   imageNamed:@"random.png"] style:UIBarButtonItemStylePlain target:self action:@selector(randomMsg)];

    self.navigationItem.rightBarButtonItem = random;
37
m-farhan

Une alternative consiste à sous-classer UIBarButtonItem. Pourquoi? Pour que l'action soit invoquée sur la cible avec l'expéditeur correct. Dans le code ci-dessus, l'argument d'expéditeur dans le message d'action est l'instance UIButton et non l'instance UIBarButtonItem. Cela serait important, par exemple, si vous souhaitez présenter un UIPopoverController à partir du bouton. En sous-classant UIBarButtonItem, vous pouvez ajouter un ivar qui conserve la cible d'origine, permettant ainsi à nos instances de sous-classes d'intercepter, de modifier et de transmettre le message d'action avec l'expéditeur approprié.

Donc, CCFBarButtonItem.h:

#import <uIKit/UIBarButtonItem.h>

@interface CCFBarButtonItem : UIBarButtonItem
{
@protected
    id _originalTarget;
}
- (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action;
@end

et CCFBarButtonItem.m

#import "CCFBarButtonItem.h"
#import <UIKit/UIButton.h>
#import <UIKit/UIView.h>
#import <UIKit/UIImage.h>

@implementation CCFBarButtonItem

#pragma mark - Object life cycle

- (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action;
{
    _ASSIGN( _originalTarget, target );

    UIButton *imgButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [imgButton setImage:image forState:UIControlStateNormal];
    imgButton.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    [imgButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];

    self = [super initWithCustomView:imgButton];

    return self;
}

- (void)dealloc;
{
    MCRelease(_originalTarget);
    [super dealloc];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
{
    if( [_originalTarget respondsToSelector:aSelector] )
    {
        return [_originalTarget methodSignatureForSelector:aSelector];
    }
    else
    {
        return [super methodSignatureForSelector:aSelector];
    }
}

- (void)forwardInvocation:(NSInvocation *)anInvocation;
{
    SEL aSelector = [anInvocation selector];
    if( [_originalTarget respondsToSelector:aSelector] )
    {
        //  modify the 'sender' argument so that it points to self
        [anInvocation setArgument:&self atIndex:2];
        [anInvocation invokeWithTarget:_originalTarget];
    }
    else
    {
        [self doesNotRecognizeSelector:aSelector];
    }
}
@end
6
FluffulousChimp
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"]
                                                                    style:UIBarButtonItemStylePlain
                                                                   target:self
                                                                   action:@selector(showMenu)];
4
alexmorhun

Cela peut aussi être fait par programme (bien sûr):

Commencez par créer une vue personnalisée. Cette vue personnalisée peut contenir une image, un bouton ou tout autre élément de votre choix. La vue personnalisée peut être créée par programme ou dans IB:

UIImage *customImage = [UIImage imageNamed:@"imageName"];
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, customImage.size.width, customImage.size.height)];
customView.backgroundColor = [UIColor colorWithPatternImage:customImage];

Créez ensuite un UIBarButtonItem et initialisez-le avec la vue personnalisée.

UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];

Maintenant, ajoutez simplement le UIBarButton personnalisé au leftBarButtonItem:

self.navigationItem.leftBarButtonItem = customBarButtonItem;
3
abriggs

Ok cette catégorie fonctionne très bien car il n’ya aucun problème avec Popovercontroller :-)

#import <UIKit/UIKit.h>

@interface UIBarButtonItem (BarButtonItemExtended)
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action;
-(void)performBarButtonAction:(id)sender;
@end



#import "UIBarButtonItem+BarButtonItemExtended.h"

@implementation UIBarButtonItem (BarButtonItemExtended)

+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action
{    
    UIButton *imgButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [imgButton setImage:image forState:UIControlStateNormal];
    imgButton.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);

    UIBarButtonItem *b = [[UIBarButtonItem alloc]initWithCustomView:imgButton];

    [imgButton addTarget:b action:@selector(performBarButtonAction:) forControlEvents:UIControlEventTouchUpInside];

    [b setAction:action];
    [b setTarget:target];

    return b;
}

-(void)performBarButtonAction:(UIButton*)sender
{
    [[self target] performSelector:self.action withObject:self];
}
@end
1
Raegtime

Découvrez cette solution simple.

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
barButtonItem.image = [UIImage imageNamed:@"navButton.png"];
barButtonItem.style = UIBarButtonItemStylePlain;

[barButtonItem setBackgroundImage:[UIImage imageNamed:@"1x1.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
self.masterPopoverController = popoverController;
}

1x1.png est une image png transparente de 1 pixel que vous pouvez télécharger à partir du lien ci-dessous.

http://commons.wikimedia.org/wiki/File:1x1.png

1
Fremy Jose

Une autre solution, pensez que c'est plus simple dans le cas où vous créez un bouton par programmation:

UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithImage:defaultImage
                                             landscapeImagePhone:landscapeImage
                                                           style:UIBarButtonItemStylePlain
                                                          target:self
                                                          action:@selector(someSelector)];
[button setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[button setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
0
Mikhail