在UIButton中使用UIBarButtonItem图标

问题描述 投票:34回答:9

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

“垃圾桶图标”

带有UIButton?没有像设置identifierstyle那样的直接方法。

ios cocoa-touch uibutton uibarbuttonitemstyle
9个回答
9
投票

从网络上的某处下载图像,将其添加到您的项目中,然后将UIButton的图像设置为刚刚下载的图像。

我没有找到与Apple正在使用的相同,但我发现了this one。只需在Pixelmator或Photoshop中更改其颜色即可。


24
投票

iOS 13现在支持SF SymbolsUIImage(systemName: "trash")


对于Swift 4.2 (在主线程上调用它)

extension UIBarButtonItem.SystemItem {
    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];

    // 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;
}

15
投票

这里是与ANY一起使用的解决方案,它支持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.S。如果您知道更好的方法,请随时进行改进,谢谢。


9
投票

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

//  UIImage+FromSystemItem.swift

import UIKit

extension UIImage {

    public convenience init?(systemItem sysItem: UIBarButtonItem.SystemItem, renderingMode:UIImage.RenderingMode = .automatic) {
        guard let sysImage = UIImage.imageFromSystemItem(sysItem, renderingMode: renderingMode)?.cgImage else {
            return nil
        }

        self.init(cgImage: sysImage)
    }

    private class func imageFromSystemItem(_ systemItem: UIBarButtonItem.SystemItem, renderingMode:UIImage.RenderingMode = .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 nil
    }
}

带操作按钮的示例(默认颜色):

let actionImage = UIImage(systemItem: .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(systemItem: .action, renderingMode: .alwaysTemplate) 

4
投票

所有iOS系统图标都可以使用一个名为(非常合适)iOS Artwork Extractor的便捷小应用程序进行提取。当我想模仿iOS系统行为时,会一直使用它。

在以下位置下载Xcode项目:>>

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


4
投票

正如@Islam Q的答案的注释中已经提到的,如果当前未在屏幕上呈现UINavigationItem


2
投票

在Swift 4.2中使用Quartz2D


1
投票

我在表单元格中将它用于imageView,所以无论我在何处设置颜色,着色都无法正常工作。所以我最终得到了这段代码,在其中为图像设置了颜色。


1
投票

基于@yycking answer,这是Xamarin.iOS C#端口:

© www.soinside.com 2019 - 2024. All rights reserved.