在UIButton中使用UIBarButtonItem图标

UIBarButtonItem有多个可用的图标。 是否可以使用将标识符设置为“垃圾”后出现的图标:

垃圾图标

UIButton ? 没有像设置标识符样式那样直接的方法。

从网上某个地方下载图像,将其添加到您的项目,并将UIButton的图像设置为您刚下载的图像。

我没有find苹果正在使用的相同,但我发现这一个 。 只需在Pixelmator或Photoshop中更改它的颜色。

这是一个解决scheme,与任何系统栏button项目+它支持tintColor

 - (void)viewDidLoad { [super viewDidLoad]; [self.button setImage:[self imageFromSystemBarButton:UIBarButtonSystemItemTrash] forState:UIControlStateNormal]; self.button.tintColor = [UIColor redColor]; } - (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem { // Holding onto the oldItem (if any) to set it back later // could use left or right, doesn't matter UIBarButtonItem *oldItem = self.navigationItem.rightBarButtonItem; UIBarButtonItem *tempItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItem target:nil action:nil]; // Setting as our right bar button item so we can traverse its subviews self.navigationItem.rightBarButtonItem = tempItem; // Don't know whether this is considered as PRIVATE API or not UIView *itemView = (UIView *)[self.navigationItem.rightBarButtonItem performSelector:@selector(view)]; UIImage *image = nil; // Traversing the subviews to find the ImageView and getting its image for (UIView *subView in itemView.subviews) { if ([subView isKindOfClass:[UIImageView class]]) { image = ((UIImageView *)subView).image; break; } } // Setting our oldItem back since we have the image now self.navigationItem.rightBarButtonItem = oldItem; return image; } 

聚苯乙烯随意改善,如果你知道一个更好的办法,谢谢。

2017/10/05 不适用于iOS 11.0.1

快速3/4 (在主线上调用它)

 extension UIBarButtonSystemItem { func image() -> UIImage? { let tempItem = UIBarButtonItem(barButtonSystemItem: self, target: nil, action: nil) // add to toolbar and render it let bar = UIToolbar() bar.setItems([tempItem], animated: false) bar.snapshotView(afterScreenUpdates: true) // got image from real uibutton let itemView = tempItem.value(forKey: "view") as! UIView for view in itemView.subviews { if let button = view as? UIButton, let image = button.imageView?.image { return image.withRenderingMode(.alwaysTemplate) } } return nil } } 

UIBarButtonSystemItem.play.image()

对于Objective-C:

 + (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem { UIBarButtonItem* tempItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItem target:nil action:nil]; // Add to toolbar and render it UIToolbar *bar = [[UIToolbar alloc] init]; [bar setItems:@[tempItem] animated:NO]; [bar snapshotViewAfterScreenUpdates:YES]; // Ger image from real UIButton UIView *itemView = [(id)tempItem view]; for (UIView* view in itemView.subviews) { if ([view isKindOfClass:[UIButton class]]) { return [(UIButton*)view imageForState:UIControlStateNormal]; } } return nil; } 

基于@yycking的答案,我写了一个合适的Swift 3扩展:

 // // UIImage+imageFromSystemBarButton.swift // import UIKit extension UIImage{ class func imageFromSystemBarButton(_ systemItem: UIBarButtonSystemItem, renderingMode:UIImageRenderingMode = .automatic)-> UIImage { let tempItem = UIBarButtonItem(barButtonSystemItem: systemItem, target: nil, action: nil) // add to toolbar and render it UIToolbar().setItems([tempItem], animated: false) // got image from real uibutton let itemView = tempItem.value(forKey: "view") as! UIView for view in itemView.subviews { if view is UIButton { let button = view as! UIButton let image = button.imageView!.image! image.withRenderingMode(renderingMode) return image } } return UIImage() } } 

动作button示例(默认着色):

 let actionImage = UIImage.imageFromSystemBarButton(.action) let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) myButton.setImage(actionImage, for: .normal) view.addSubview(myButton) 

如果您希望无论上下文如何都将图像视为模板,请将renderingMode设置为.alwaysTemplate

  let actionImage = UIImage.imageFromSystemBarButton(.action, renderingMode: .alwaysTemplate) 

所有的iOS系统图标都可以使用一个称为(合适的)的iOS艺术作品提取器的方便的小应用程序来提取。 我一直用它来模仿iOS系统的行为。

下载Xcode项目:

https://github.com/0xced/iOS-Artwork-Extractor

正如在@Islam Q的回答中已经提到的那样,如果UINavigationItem当前不在屏幕上呈现,那么呈现的解决scheme可能会失败。 例如,如果视图控制器当前未被加载,则它失败。 事实上这个问题似乎是UINavigationBar在这些情况下缺less的布局。

更“防弹”的版本将是使用专门创build的UINavigationBar对象来获取系统项目图像。 这也将节省和恢复任何现有的UIBarButtonItems过时。

我已经把这个包装成了一个小帮手类:

LEABarButtonSystemItemImage.h:

 #import <UIKit/UIKit.h> /** LEABarButtonSystemItemImage interface */ @interface LEABarButtonSystemItemImage : NSObject + (UIImage *)imageFromBarButtonSystemItem:(UIBarButtonSystemItem)pBarButtonSystemItem; + (UIImage *)customImageForBarButtonSystemItem:(UIBarButtonSystemItem)pBarButtonSystemItem; + (NSDictionary<__kindof NSNumber*, __kindof UIImage*> *)barButtonItemImages; @end 

LEABarButtonSystemItemImage.m

 #import "LEABarButtonSystemItemImage.h" /** LEABarButtonSystemItemImage implementation */ @implementation LEABarButtonSystemItemImage /* imageFromBarButtonSystemItem: */ + (UIImage *)imageFromBarButtonSystemItem:(UIBarButtonSystemItem)pBarButtonSystemItem { static const CGFloat defaultNBBtnHW = 44.0; UINavigationBar * tempNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, defaultNBBtnHW, defaultNBBtnHW)]; UINavigationItem * tempNavigationItem = [[UINavigationItem alloc] init]; UIBarButtonItem * tempBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:pBarButtonSystemItem target:nil action:NULL]; tempNavigationBar.items = @[tempNavigationItem]; tempNavigationItem.rightBarButtonItems = @[tempBarButtonItem]; UIImage * barButtonSystemItemImage = nil; @try { UIView * barButtonItemView = [tempBarButtonItem valueForKey:@"view"]; for (UIView* subview in barButtonItemView.subviews) { if ([subview isKindOfClass:UIImageView.class]) { barButtonSystemItemImage = ((UIImageView *)subview).image; break; } } } @catch (...) { NSLog(@"%s: Exception while retrieving image from UIBarButtonItem!", __PRETTY_FUNCTION__); } return (barButtonSystemItemImage ?: [LEABarButtonSystemItemImage customImageForBarButtonSystemItem:pBarButtonSystemItem]); } /* customImageForBarButtonSystemItem: */ + (UIImage *)customImageForBarButtonSystemItem:(UIBarButtonSystemItem)pBarButtonSystemItem { NSString * customBarButtonSystemItemImageName = nil; switch (pBarButtonSystemItem) { case UIBarButtonSystemItemDone: customBarButtonSystemItemImageName = @"customBarButtonSystemItemDone"; break; case UIBarButtonSystemItemCancel: customBarButtonSystemItemImageName = @"customBarButtonSystemItemCancel"; break; case UIBarButtonSystemItemEdit: customBarButtonSystemItemImageName = @"customBarButtonSystemItemEdit"; break; case UIBarButtonSystemItemSave: customBarButtonSystemItemImageName = @"customBarButtonSystemItemSave"; break; case UIBarButtonSystemItemAdd: customBarButtonSystemItemImageName = @"customBarButtonSystemItemAdd"; break; case UIBarButtonSystemItemCompose: customBarButtonSystemItemImageName = @"customBarButtonSystemItemCompose"; break; case UIBarButtonSystemItemReply: customBarButtonSystemItemImageName = @"customBarButtonSystemItemReply"; break; case UIBarButtonSystemItemAction: customBarButtonSystemItemImageName = @"customBarButtonSystemItemAction"; break; case UIBarButtonSystemItemOrganize: customBarButtonSystemItemImageName = @"customBarButtonSystemItemOrganize"; break; case UIBarButtonSystemItemBookmarks: customBarButtonSystemItemImageName = @"customBarButtonSystemItemBookmarks"; break; case UIBarButtonSystemItemSearch: customBarButtonSystemItemImageName = @"customBarButtonSystemItemSearch"; break; case UIBarButtonSystemItemRefresh: customBarButtonSystemItemImageName = @"customBarButtonSystemItemRefresh"; break; case UIBarButtonSystemItemStop: customBarButtonSystemItemImageName = @"customBarButtonSystemItemStop"; break; case UIBarButtonSystemItemCamera: customBarButtonSystemItemImageName = @"customBarButtonSystemItemCamera"; break; case UIBarButtonSystemItemTrash: customBarButtonSystemItemImageName = @"customBarButtonSystemItemTrash"; break; case UIBarButtonSystemItemPlay: customBarButtonSystemItemImageName = @"customBarButtonSystemItemPlay"; break; case UIBarButtonSystemItemPause: customBarButtonSystemItemImageName = @"customBarButtonSystemItemPause"; break; case UIBarButtonSystemItemRewind: customBarButtonSystemItemImageName = @"customBarButtonSystemItemRewind"; break; case UIBarButtonSystemItemFastForward: customBarButtonSystemItemImageName = @"customBarButtonSystemItemFastForward"; break; case UIBarButtonSystemItemUndo: customBarButtonSystemItemImageName = @"customBarButtonSystemItemUndo"; break; case UIBarButtonSystemItemRedo: customBarButtonSystemItemImageName = @"customBarButtonSystemItemRedo"; break; case UIBarButtonSystemItemPageCurl: customBarButtonSystemItemImageName = @"customBarButtonSystemItemPageCurl"; break; default: break; } return (customBarButtonSystemItemImageName ? [UIImage imageNamed:customBarButtonSystemItemImageName] : nil); } /* barButtonItemImages */ + (NSDictionary<__kindof NSNumber*, __kindof UIImage*> *)barButtonItemImages { NSMutableDictionary<__kindof NSNumber*, __kindof UIImage*> * barButtonItemImages = [NSMutableDictionary dictionary]; // From: https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIBarButtonItem.h // unsigned int systemItem : 7; for (NSUInteger uIndex = 0; uIndex < (1<<7); ++uIndex) { UIImage* systemImage = [LEABarButtonSystemItemImage imageFromBarButtonSystemItem:uIndex]; if (systemImage) { [barButtonItemImages setObject:systemImage forKey:@(uIndex)]; } } NSLog(@"%s: %@", __PRETTY_FUNCTION__, barButtonItemImages); return barButtonItemImages; } @end 

作为附加/回退,如果没有系统项目图像可以被检索,则该方法返回自定义图像。 当然,这些自定义图像必须存在于应用程序包中。

最后一个方法'barButtonImages'是为了好奇而实现的…在UIBarButtonItem头中,成员systemItem被声明为使用7位(0..127)。 目前只有22个值从UIBarButtonSystemItemDonelogging到UIBarButtonItemSystemItemPageCurl …事实上; 我发现一些以索引超过100开始的未公开的图像(在6S +模拟器的iOS 9.3上testing):-)