【问题标题】:Customizing UIBarButtonItem "Done" style and "Plain" style separately using UIAppearance使用 UIAppearance 分别自定义 UIBarButtonItem“完成”样式和“普通”样式
【发布时间】:2012-09-25 13:03:11
【问题描述】:

我知道如何使用-setBackgroundImage: forState: barMetrics: 自定义UIBarButtonItem,但我想为UIBarButtonItemStyleDoneUIBarButtonItemStylePlain 使用不同的图像。

有没有办法使用UIAppearance 协议来实现这一点?还是每次我想要“完成”样式按钮时都必须设置图像?

(我尝试过使用如下代码:

[[UIBarButtonItem appearance] setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarButtonItemStyleDone];

但这只是将每个条形按钮设置为“完成”图像。)

谢谢!

【问题讨论】:

  • 你想改变按钮点击后的图像吗?
  • 我已经自定义了后退按钮。我希望有不同的“正常”栏按钮(例如 iOS 如何使用蓝色按钮表示“完成”和“保存”,但灰色按钮表示“取消”)。
  • @James,一种选择是使用来自UIBarButtonItem 的自定义子类作为完成按钮的CustomDoneBarButtonItem,并将其用作[[CustomDoneBarButtonItem appearance] setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarButtonItemStyleDone]。每当您添加完成按钮时,请创建此自定义类的对象并添加它。
  • 这不起作用,因为当您在子类上调用appearance 时,它会在超类上调用appearance,并且您所有的 UIBarButtonItem 都会获得这种样式。看到这个线程:stackoverflow.com/questions/11022468/…

标签: iphone ios customization uibarbuttonitem uiappearance


【解决方案1】:

iOS 6中可以使用UIBarButtonItem类的新方法:

- (void)setBackgroundImage:(UIImage *)backgroundImage
                  forState:(UIControlState)state
                     style:(UIBarButtonItemStyle)style
                barMetrics:(UIBarMetrics)barMetrics

它为指定的状态、样式和指标设置背景图像。 更多详情可in the Apple docs

所以要改变所有 UIBarButtonItems 的外观,你可以使用类似的东西:

UIImage *doneBackgroundImage = [[UIImage imageNamed:@"button_done.png"]
   resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)];

[[UIBarButtonItem appearance] setBackgroundImage:doneBackgroundImage
                                            forState:UIControlStateNormal
                                               style:UIBarButtonItemStyleDone
                                          barMetrics:UIBarMetricsDefault];

【讨论】:

  • 它是官方 API,仅在 iOS 6 中可用(我已明确说明)。它解决了所描述的问题:“使用 UIAppearance 协议完成此 [UIBarButtonItemStyleDone 和 UIBarButtonItemStylePlain 的不同图像] 的方法”。
  • 是的,很抱歉,downvote 没有意义确实读错了 - 完全是我的错!正确的。谢谢你 :) 我需要 ios5... 否则会很容易
  • 没问题,我也在为 iOS 5 寻找好的解决方案 ;-)
  • 当我问这个问题时,我也在寻找适用于 iOS 5 的解决方案,但由于没有特别说明,我会接受这个答案。
  • 任何想法如何自定义 UIarButtonItemStyleDone 的文本标题属性? setTitleTextAttributes:forState: 缺少样式参数;(
【解决方案2】:

适用于 IOS5*

我发现的唯一方法是使用 UIBarButtonItem 类别:

UIBarButtonItem+Appearance.h

#import <Foundation/Foundation.h>

@interface UIBarButtonItem (Appearance)

+ (void) setupAppearance;

@end

UIBarButtonItem+Appearance.m

#import "UIBarButtonItem+Appearance.h"
#import <objc/runtime.h>

@implementation UIBarButtonItem (Appearance)

+ (void) setupAppearance {
    [[UIBarButtonItem appearance]  setBackgroundImage: [[UIImage imageNamed:@"customButton"]
                                                                  resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
                                                       forState: UIControlStateNormal
                                                     barMetrics: UIBarMetricsDefault];

    [[UIBarButtonItem appearance]  setBackgroundImage: [[UIImage imageNamed:@"customButtonHiglhighted"]
                                                                  resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
                                                       forState: UIControlStateHighlighted
                                                     barMetrics: UIBarMetricsDefault];



    Class klass = objc_getClass("UIBarButtonItem");
    Method targetMethod = class_getInstanceMethod(klass, @selector(setStyle:));
    Method newMethod = class_getInstanceMethod(klass, @selector(__setStyle:));
    method_exchangeImplementations(targetMethod, newMethod);
}

- (void) __setStyle:(UIBarButtonItemStyle)style {
    [self __setStyle:style];

    if(style == UIBarButtonItemStyleDone) {
        [self setBackgroundImage:[[UIImage imageNamed:@"customDoneButton"] resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
                        forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:[UIImage imageNamed:@"customDoneButtonClicked"]
                        forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
    } else {
        [self setBackgroundImage:[[UIImage imageNamed:@"customButton"] resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)]
                        forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:[UIImage imageNamed:@"customButtonHighlighted"]
                        forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
    }
}

@end

希望这是您正在寻找的。 此解决方案的功劳归于https://gist.github.com/2633081

【讨论】:

  • 这是MethodSwizzling吗?如果是,则始终存在应用商店被拒绝的风险。
  • @acb 是的,但我知道很多应用程序都这样做,虽然这绝不会使这合法化,但我觉得没关系在这种情况下
  • 不幸的是,这似乎不适用于某些系统控制器,例如在 MFMailComposeViewController 上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 2011-08-24
  • 2018-03-22
  • 2017-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多