自定义UINavigationBar和返回按钮

6
4个回答

18

我写了以下类别以自定义返回按钮:

UIBarButtonItem+StyledButton.h

@interface UIBarButtonItem (StyledButton)
+ (UIBarButtonItem *)styledBackBarButtonItemWithTarget:(id)target selector:(SEL)selector;
+ (UIBarButtonItem *)styledCancelBarButtonItemWithTarget:(id)target selector:(SEL)selector;
+ (UIBarButtonItem *)styledSubmitBarButtonItemWithTitle:(NSString *)title target:(id)target selector:(SEL)selector;
@end

UIBarButtonItem+StyledButton.m

@implementation UIBarButtonItem (StyledButton)

+ (UIBarButtonItem *)styledBackBarButtonItemWithTarget:(id)target selector:(SEL)selector;
{
   UIImage *image = [UIImage imageNamed:@"button_back"];
   image = [image stretchableImageWithLeftCapWidth:20.0f topCapHeight:20.0f];

   NSString *title = NSLocalizedString(@"Back", nil);
   UIFont *font = [UIFont boldSystemFontOfSize:12.0f];

   UIButton *button = [UIButton styledButtonWithBackgroundImage:image font:font title:title target:target selector:selector];
   button.titleLabel.textColor = [UIColor blackColor];

   CGSize textSize = [title sizeWithFont:font];
   CGFloat margin = (button.frame.size.height - textSize.height) / 2;
   CGFloat marginRight = 7.0f;
   CGFloat marginLeft = button.frame.size.width - textSize.width - marginRight;
   [button setTitleEdgeInsets:UIEdgeInsetsMake(margin, marginLeft, margin, marginRight)]; 
   [button setTitleColor:[UIColor colorWithRed:53.0f/255.0f green:77.0f/255.0f blue:99.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];   

   return [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
}

+ (UIBarButtonItem *)styledCancelBarButtonItemWithTarget:(id)target selector:(SEL)selector;
{
   UIImage *image = [UIImage imageNamed:@"button_square"];
   image = [image stretchableImageWithLeftCapWidth:20.0f topCapHeight:20.0f];

   NSString *title = NSLocalizedString(@"Cancel", nil);
   UIFont *font = [UIFont boldSystemFontOfSize:12.0f];

   UIButton *button = [UIButton styledButtonWithBackgroundImage:image font:font title:title target:target selector:selector];   
   button.titleLabel.textColor = [UIColor blackColor];   
   [button setTitleColor:[UIColor colorWithRed:53.0f/255.0f green:77.0f/255.0f blue:99.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];   

   return [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
}

+ (UIBarButtonItem *)styledSubmitBarButtonItemWithTitle:(NSString *)title target:(id)target selector:(SEL)selector;
{
   UIImage *image = [UIImage imageNamed:@"button_submit"];
   image = [image stretchableImageWithLeftCapWidth:20.0f topCapHeight:20.0f];

   UIFont *font = [UIFont boldSystemFontOfSize:12.0f];

   UIButton *button = [UIButton styledButtonWithBackgroundImage:image font:font title:title target:target selector:selector];
   button.titleLabel.textColor = [UIColor whiteColor];
   [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];   

   return [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
}

UIButton+StyledButton.h

@interface UIButton (UIButton_StyledButton)
+ (UIButton *)styledButtonWithBackgroundImage:(UIImage *)image font:(UIFont *)font title:(NSString *)title target:(id)target selector:(SEL)selector;
@end

UIButton+StyledButton.m

@implementation UIButton (UIButton_StyledButton)

+ (UIButton *)styledButtonWithBackgroundImage:(UIImage *)image font:(UIFont *)font title:(NSString *)title target:(id)target selector:(SEL)selector
{
   CGSize textSize = [title sizeWithFont:font];
   CGSize buttonSize = CGSizeMake(textSize.width + 20.0f, image.size.width);

   UIButton *button = [[[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, buttonSize.width, buttonSize.height)] autorelease];
   [button addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside];
   [button setBackgroundImage:image forState:UIControlStateNormal];
   [button setTitle:title forState:UIControlStateNormal];
   [button.titleLabel setFont:font];

   return button;
}

@end


使用起来很简单,例如:

- (void)viewDidLoad
{
   [super viewDidLoad];

   self.navigationItem.leftBarButtonItem = [UIBarButtonItem styledBackBarButtonItemWithTarget:self selector:@selector(dismissModalViewController)];
   self.navigationItem.rightBarButtonItem = [UIBarButtonItem styledSubmitBarButtonItemWithTitle:NSLocalizedString(@"Done", nil) target:self selector:@selector(doneButtonTouched:)];
}


以上代码来自一个仍在进行中的项目,因此它可能需要进行一些清理,但它按照预期工作。使用没有文本的图像作为按钮,并确保它们是可拉伸的(即不要把图像做得太小,并注意渐变色)。以下示例中返回按钮的图像仅为31 x 30像素,但被拉伸以适应文本。

一些结果示例:

返回按钮

输入图像描述

取消/完成 按钮

输入图像描述


干得好!你能和我分享一下“button_back.png”这个图片吗?我们需要设置按钮的“按下”状态吗? - user403015
抱歉,我无法分享这些图片,它们是由UX设计师为我的雇主支付的项目设计的。当按下UIButton时,默认情况下,图像将获得某种半透明叠加效果,因此我没有添加任何特定的按下状态图像,但如果需要自定义,则可以添加。 - Wolfgang Schreurs
1
请注意,在iOS 5中,stretchableImageWithLeftCapWidth:topCapHeight:已被弃用,您应该使用capInsets代替。参考:http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImage_Class/DeprecationAppendix/AppendixADeprecatedAPI.html - Aaron Ash
这里的棘手之处在于您不是自定义 backBarButtonItem,而是设置了 leftBarButtonItem。这让我感到困惑,但文档更加清晰地说明了:“如果您想在此项为后退项时使用不同的标题,请使用 backBarButtonItem 属性。”并且进一步解释道:“导航栏默认在左侧显示返回按钮,在中心显示标题。您可以通过指定自定义的左、中或右视图来更改此行为。”这一点起初并不明显。 - Aaron

6

我已经使用过这段代码几次:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Set the custom back button
    UIImage *buttonImage = [UIImage imageNamed:@"back_button.png"];

    //create the button and assign the image
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:buttonImage forState:UIControlStateNormal];

    //set the frame of the button to the size of the image (see note below)
    button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);

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

    //create a UIBarButtonItem with the button as a custom view
    UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    self.navigationItem.leftBarButtonItem = customBarItem;

 // Cleanup
 [customBarItem release];
}

-(void)back {
    // Tell the controller to go back
    [self.navigationController popViewControllerAnimated:YES];
}

来自这个网站。 希望能对您有所帮助!


这解决了我们的问题,谢谢!唯一的问题是你必须将这段代码放入每个需要返回按钮的视图控制器中。如果有更通用的解决方案就更好了。 - Giovanni

0

以下是您需要做的。

1)在界面生成器中将自定义按钮添加到导航项:

enter image description here

2) 在代码中执行以下操作:

#define IS_IOS7  ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)

- (void)viewDidLayoutSubviews {

    [super viewDidLayoutSubviews];

    if (IS_IOS7) { 

        [self shiftView:self.navigationItem.leftBarButtonItem.customView horizontallyBy:-11];
        [self shiftView:self.navigationItem.rightBarButtonItem.customView horizontallyBy:11];
    }
}

- (void)shiftView:(UIView*)view horizontallyBy:(int)offset {
      CGRect frame = view.frame;
      frame.origin.y += offset;
      view.frame = frame;
}

0

你需要构建一个自定义的UIButton,并将其传递给UIBarButton initWithCustomView。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接