Usar el icono de UIBarButtonItem en UIButton
UIBarButtonItem
tiene múltiples iconos disponibles. ¿Es posible utilizar el icono que aparece después de configurar su identificador a 'papelera':
Con un UIButton
? No hay un método straighforward para hacer eso como establecer el identificador o el estilo .
8 answers
Descarga la imagen desde algún lugar de la web, agrégala a tu proyecto y establece la imagen de UIButton
a la imagen que acabas de descargar.
No encontré lo mismo que Apple está usando, pero encontré este. Simplemente cambie su color en Pixelmator o Photoshop.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-17 14:30:41
2017/10/05 no funciona en iOS 11.0.1
Para swift 3/4 (llámelo en el hilo principal)
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()
Para 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];
// Get 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-13 02:23:13
Aquí hay una solución que funciona con CUALQUIER elemento del botón de la barra del sistema + admite 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;
}
P.D. Siéntase libre de mejorar si conoce una manera mejor, gracias.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-06 10:56:07
Basado en la respuesta de @yycking, escribí una extensión adecuada Swift 3/4 :
//
// 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
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 view is UIButton {
let button = view as! UIButton
let image = button.imageView!.image!
image.withRenderingMode(renderingMode)
return image
}
}
return UIImage()
}
}
Ejemplo con botón de acción (color por defecto):
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)
Si desea que su imagen siempre se trate como una plantilla independientemente del contexto, establezca renderingMode en .Todas las plantillas
let actionImage = UIImage.imageFromSystemBarButton(.action, renderingMode: .alwaysTemplate)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-19 12:10:25
Como ya se mencionó en los comentarios a la respuesta de @Islam Q, la solución presentada podría fallar, si el UINavigationItem no se muestra actualmente en pantalla. Falla, por ejemplo, si el controlador de vista no está cargado actualmente. De hecho, el problema parece ser la disposición faltante de la UINavigationBar en estos casos.
Una versión más 'a prueba de balas' sería usar un objeto UINavigationBar especialmente creado solo para obtener las imágenes del elemento del sistema. Esto sería también hace que guardar y restaurar cualquier UIBarButtonItems existentes sea obsoleto.
He empaquetado esto en una pequeña clase auxiliar:
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
Como add on/fallback , el método devuelve una imagen personalizada, si no se pudo recuperar ninguna imagen de elemento del sistema. Por supuesto, estas imágenes personalizadas deben estar presentes en el paquete de aplicaciones.
El último método 'barButtonImages' se implementó solo por curiosidad... en el encabezado UIBarButtonItem el systemItem miembro es declarado para usar 7 bits (0..127). Actualmente solo se documentan 22 valores de UIBarButtonSystemItemDone a UIBarButtonItemSystemItemPageCurl... y de hecho, encontré algunas imágenes indocumentadas que comienzan con índices superiores a 100 (probadas en iOS 9.3 en el simulador 6S+): -)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-11 18:22:29
Todos los iconos del sistema iOS se pueden extraer usando una pequeña y práctica aplicación llamada (adecuadamente) iOS Artwork Extractor. Lo uso todo el tiempo cuando quiero imitar los comportamientos del sistema iOS.
Descargue el proyecto Xcode en:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-08 05:02:12
Lo estaba usando para ImageView en la celda de la tabla y de alguna manera el color de tinte no funcionó donde lo configuré... Así que terminé con este código donde se establece el color de la imagen.
+ (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem :(UIColor *) color {
UIToolbar *bar = UIToolbar.new;
UIBarButtonItem *buttonItem = [UIBarButtonItem createWithItem:systemItem];
[bar setItems:@[buttonItem] animated:NO];
[bar snapshotViewAfterScreenUpdates:YES];
for (UIView *view in [(id) buttonItem view].subviews)
if ([view isKindOfClass:UIButton.class]) {
UIImage *image = [((UIButton *) view).imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
[color set];
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
return nil;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-13 17:41:36
Usando Quartz2D con Swift 4.2
Las soluciones basadas en una extensión para extraer la imagen de la UIBarButtonSystemItem
no funcionan en iOS 11/12, así que decidí agregar una clase personalizada para dibujar los iconos sin agregar ninguno .png
Esto se implementa para .basura y .acción que son los iconos que necesito en mi proyecto. Siéntase libre de agregar el resto.
Úselo de la siguiente manera (debe ajustarse al protocolo SystemIConDelegate
, establecer la propiedad Delegate y agregar método requerido):
let trashIcon = SystemIcon(withType: .trash)
trashIcon.delegate = self
shareButton = UIButton()
shareButton.addSubview(trashIcon)
La clase SystemIcon
está aquí. Está optimizado para 30 X 30 puntos:
import UIKit
protocol SystemIconDelegate {
func systemIconButtonClicked()
}
class SystemIcon: UIView {
var type: UIBarButtonItem.SystemItem!
let color = UIColor.blue
var delegate: SystemIconDelegate?
convenience init(withType: UIBarButtonItem.SystemItem) {
self.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
self.backgroundColor = .clear
self.type = withType
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.delegate?.systemIconButtonClicked()
}
override func draw(_ rect: CGRect) {
let w = self.frame.width
let h = self.frame.height
let context = UIGraphicsGetCurrentContext()
context?.setStrokeColor(color.cgColor)
context?.setLineWidth(1.0)
switch type! {
case .action:
//Box
context?.stroke(CGRect(x: w * 0.16, y: h * 0.3, width: w * 0.69, height: h * 0.69))
context?.setFillColor(UIColor.white.cgColor)
context?.fill(CGRect(x: w * 0.4, y: 0, width: w * 0.2, height: h * 0.5))
//Arrow
context?.move(to: CGPoint(x: w * 0.5, y: h * 0.02))
context?.addLine(to: CGPoint(x: w * 0.5, y: h * 0.64))
context?.move(to: CGPoint(x: w * 0.33, y: h * 0.19))
context?.addLine(to: CGPoint(x: w * 0.5, y: h * 0.02))
context?.addLine(to: CGPoint(x: w * 0.67, y: h * 0.19))
context?.strokePath()
case .trash:
context?.move(to: CGPoint(x: w * 0.1, y: h * 0.15))
context?.addLine(to: CGPoint(x: w * 0.9, y: h * 0.15))
//Can
context?.move(to: CGPoint(x: w * 0.2, y: h * 0.15))
context?.addArc(tangent1End: CGPoint(x: w * 0.25, y: h * 0.95), tangent2End: CGPoint(x: w * 0.5, y:h * 0.95), radius: CGFloat.x(2.0))
context?.addArc(tangent1End: CGPoint(x: w * 0.75, y: h * 0.95), tangent2End: CGPoint(x: w * 0.8, y: h * 0.15), radius: CGFloat.x(2.0))
context?.addLine(to: CGPoint(x: w * 0.8, y: h * 0.15))
// Handle
context?.move(to: CGPoint(x: w * 0.34, y: h * 0.15))
context?.addArc(tangent1End: CGPoint(x: w * 0.34, y: h * 0.02), tangent2End: CGPoint(x: w * 0.5, y: h * 0.02), radius: CGFloat.x(2.0))
context?.addArc(tangent1End: CGPoint(x: w * 0.66, y : h * 0.02), tangent2End: CGPoint(x: w * 0.66, y: h * 0.15), radius: CGFloat.x(2.0))
context?.addLine(to: CGPoint(x: w * 0.66, y: h * 0.15))
//Lines
context?.move(to: CGPoint(x: w * 0.35, y: h * 0.25))
context?.addLine(to: CGPoint(x: w * 0.38, y: h * 0.8))
context?.move(to: CGPoint(x: w * 0.5, y: h * 0.25))
context?.addLine(to: CGPoint(x: w * 0.5, y: h * 0.8))
context?.move(to: CGPoint(x: w * 0.65, y: h * 0.25))
context?.addLine(to: CGPoint(x: w * 0.62, y: h*0.8))
default:
break
}
context?.strokePath()
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-04 18:58:32