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?
merci,
cordialement,
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.
Une autre solution simple est
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;
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
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(showMenu)];
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;
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
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.
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];