2010-04-21 7 views
88

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

C'est la même chose que le bouton de retour, mais un bouton vers l'avant.

Cette application est pour un projet InHouse, donc je ne se soucient pas si Apple rejette ou approuve ou qu'il aime :-)

Si je l'initWithCustomView: propriété v du 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 en 10 vues, ce n'est pas sec. Je suppose que je dois sous-classer, mais quoi?

  • NSView?
  • UIBarButtonItem?

grâce,

salutations,

+3

Merci d'avoir partagé votre code, c'est tout ce que je avais besoin :). – Max

+1

Tout le monde, j'ai utilisé la réponse fournie par San le 6 février. Il m'a fallu 5 minutes pour intégrer mon Storyboard, et ça a fonctionné parfaitement. La propriété Selector est sous l'inspecteur de connexions de IB. Contrôle glisser de UIButton à l'objet ViewController et les méthodes apparaîtront. Appuyez sur la méthode que vous voulez et vous avez fait à peu près. La seule chose qui reste serait un peu de nettoyage de code. Utilisé btnXXXXX.hidden pour masquer et afficher pour remplacer barbuttonitem = nil. Mais cette méthode était facile et très propre. – user589642

Répondre

44

Vous pouvez ajouter une méthode à UIBarButtonItem sans le sous-classement à l'aide de 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 partout dans votre code, vous pouvez créer un objet bar appelant cette méthode (à condition d'inclure un en-tête avec sa déclaration).

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

+0

PS => oui, cela fonctionne aussi, moins de code :-) – mongeta

+0

PPS => merci, maintenant ajouté – mongeta

+0

La catégorie personnalisée: Je dois créer le fichier d'en-tête avec ces déclarations, et le fichier d'implémentation, où je mets le code que vous référez? merci – mongeta

6

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

Ainsi, 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 
36

Je l'ai trouvé cette façon facile. Il est sugested sur le dessus. "random.png" doit être dans le projet. Faites simplement glisser et déposez n'importe quelle 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; 
+1

merci, ça marche! – offset

49

Une autre solution simple est

  1. Faites glisser une norme UIButton
  2. Réglé sur mesure le style du bouton et définissez votre image pour ce bouton
  3. Faites-le glisser sur le UINavigationBar
  4. Set Selector
+0

Probablement la solution la plus simple. Merci! – Prine

+0

@Prine Merci :) – san

+1

Brillant! Le seul bizarre - il ne fonctionnerait pas si vous faites glisser le bouton directement à la barre de navigation. Le bouton doit être défini sur Personnalisé avant d'être ajouté à la barre de navigation. Je ne sais pas pourquoi, mais c'est comme ça. Donc étape # 1 - signifie faire glisser UIBatton quelque part sur votre interface utilisateur autre que la barre de navigation. –

1

Ok que c atégorie fonctionne très bien, car il n'y a 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 
3

Cela peut également être effectuée par programme et (de plats):

En premier lieu, créer une vue personnalisée. Cette vue personnalisée peut contenir une image, un bouton ou tout ce que vous voulez. La vue personnalisée peut être faite par programmation ou 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]; 

Ensuite, créez un UIBarButtonItem et l'initialiser avec la vue personnalisée.

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

Maintenant, ajoutez simplement le UIBarButton personnalisé à la leftBarButtonItem:

self.navigationItem.leftBarButtonItem = customBarButtonItem; 
0

Une autre solution, pense qu'il est plus simple dans le cas où le bouton création programatically:

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]; 
1

Check this out simple, Solution.

- (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; 
} 

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

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

+0

Une ligne de solutions de code sont définitivement bonnes dans mon livre –

+0

Vous pouvez simplement utiliser [UIImage new] au lieu d'utiliser l'image transparente. –

4
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"] 
                    style:UIBarButtonItemStylePlain 
                    target:self 
                    action:@selector(showMenu)]; 
Questions connexes