导航栏按钮项目的图像 swift

Posted

技术标签:

【中文标题】导航栏按钮项目的图像 swift【英文标题】:image for nav bar button item swift 【发布时间】:2015-07-17 10:08:06 【问题描述】:

我想在我的导航栏左侧快速显示图像。

我已尝试添加导航栏按钮项并在那里设置图像。

问题是我必须使用一个非常小的图像才能很好地适应导航栏。但是制作这么小的图像会导致像素化,尤其是在更大的手机 iPhone 6 和 6 Plus 上。

有没有办法使用高质量的图像,然后将框架设置为适合导航栏的范围?

我的尝试:

var image = UIImage(named: "Harp.png")

image = image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)

self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
self.navigationItem.leftBarButtonItem.frame = CGRectMake(0, 0, 53, 31)
//image.frame = CGRectMake(0, 0, 53, 31)

我尝试先将框架放在图像上,然后再放在条形按钮项目上。 但这是抛出一个错误:

在没有更多上下文的情况下,表达式的类型是模棱两可的。

【问题讨论】:

为什么不使用资产目录? 维奈是对的。使用资产目录既简单又自动。如果我错了,请纠正我,但我使用@1、@2、@3 以下分辨率:44x44、88x88 和 132x132 像素。另外,有时我需要使用插图来修正尺寸(如果你在 IBuilder 中有按钮,你可以从那里修复它)。 【参考方案1】:

试试这个

let button = UIButton(type: UIButtonType.Custom)
button.setImage(UIImage(named: "yourImageName.png"), forState: UIControlState.Normal)
button.addTarget(self, action:Selector("callMethod"), forControlEvents: UIControlEvents.TouchDragInside)
button.frame=CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItems = [newBackButton,barButton]

对于 Swift 3

let button = UIButton.init(type: .custom)
button.setImage(UIImage.init(named: "yourImageName.png"), for: UIControlState.normal)
button.addTarget(self, action:#selector(ViewController.callMethod), for:.touchUpInside)
button.frame = CGRect.init(x: 0, y: 0, width: 30, height: 30) //CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem.init(customView: button)
            self.navigationItem.leftBarButtonItem = barButton

斯威夫特 4

let button = UIButton(type: UIButton.ButtonType.custom)
button.setImage(UIImage(named: "getstarted"), for: .normal)
button.addTarget(self, action:#selector(callMethod), for: .touchDragInside)
button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItems = [barButton]

这里是行动

@objc func callMethod()    
    //do stuff here
 

【讨论】:

一个问题,动作没有被触发?我有一个“tryLogout”操作和一个函数 tryLogout(),但它没有触发注销功能? 抱歉,我发现只是事件类型需要更改 你确定第二个是用于 Swift 3 的吗?我记得在 Swift 3 中,所有方法的参数都有标签。但是您的button.addTarget(self... 的第一个参数没有标签。 为我工作(Swift 3.0)。忘记设置框架xD 如果我想在图片旁边添加一个小文本怎么办?例如,我想显示用户有多少硬币。所以我需要显示一个硬币图像和旁边的硬币数量。如何做呢?谢谢。【参考方案2】:

使用此代码:

self.navigationItem.leftBarButtonItem = nil

let button = UIButton(type: .custom)
button.setImage(UIImage (named: "ChatTab"), for: .normal)
button.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)

let button2 = UIButton(type: .custom)
button2.setImage(UIImage (named: "ActivityTab"), for: .normal)
button2.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)

let barButtonItem2 = UIBarButtonItem(customView: button2)
self.navigationItem.rightBarButtonItems = [barButtonItem, barButtonItem2]

输出:

【讨论】:

【参考方案3】:

Swift 5、XCode 11 使导航栏项具有圆形图像、来自资产的图像或从 URL 下载。

1) 新文件:UIBarButtonItem+RoundedView.swift

import Foundation

class ImageBarButton : UIView 
    var imageView: UIImageView!
    var button: UIButton!

    convenience init(withUrl imageURL: URL? = nil, withImage image: UIImage? = nil, frame: CGRect = CGRect(x: 0, y: 0, width: 40, height: 40)) 
        self.init(frame: frame)

        imageView = UIImageView(frame: frame)
        imageView.backgroundColor = .white
        imageView.layer.cornerRadius = frame.height/2
        imageView.clipsToBounds = true
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        addSubview(imageView)

        button = UIButton(frame: frame)
        button.backgroundColor = .clear
        button.setTitle("", for: .normal)
        addSubview(button)

        if let url = imageURL  // you can use pods like Nuke or Kingfisher 
         URLSession(configuration: .default).dataTask(with: URL(string: imageUrl)!) [weak self] (data, response, error) in
          if let data = data , let image = UIImage(data: data) 
              DispatchQueue.main.async 
                self?.imgView.image = image
              
           
         .resume()
         else if let image = image 
            self.imageView.image = image
        
    

    func load()-> UIBarButtonItem 
        return UIBarButtonItem(customView: self)
    

2)添加导航栏项,可以使用navigationItem.rightBarButtonItems、navigationItem.leftBarButtonItems

private func initalizeNavigationBarItems() 
    let searchBarButtonView = ImageBarButton(withImage: #imageLiteral(resourceName: "greenSearchIcon")) // Assets
    searchBarButtonView.button.addTarget(self, action: #selector(presentSearchViewController), for: .touchUpInside)

    if let user = AccountManager.currentUser, let userProfilePictureURL = user.imageUrl  // API Url
        let profileBarButtonView = ImageBarButton(withUrl: userProfilePictureURL)
        profileBarButtonView.button.addTarget(self, action: #selector(presentMoreViewController), for: .touchUpInside)
        navigationItem.rightBarButtonItems = [searchBarButtonView.load(), profileBarButtonView.load()]
     else 
        let profileBarButtonView = ImageBarButton(withImage: #imageLiteral(resourceName: "profileIcon"))
        profileBarButtonView.button.addTarget(self, action: #selector(presentMoreViewController), for: .touchUpInside)
        navigationItem.rightBarButtonItems = [searchBarButtonView.load(), profileBarButtonView.load()]
    


@objc func presentMoreViewController(_ sender: Any) 
    // present MoreViewController


@objc func presentSearchViewController(_ sender: Any) 
    // present SearchViewController

预览

【讨论】:

【参考方案4】:

Swift 4 和 5:

let imageView = UIImageView(image: UIImage(named: "Harp"))
let buttonItem = UIBarButtonItem(customView: imageView)
self.navigationItem.leftBarButtonItem = buttonItem

【讨论】:

虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。 @double-beep 接受的答案并没有做到这一点。正如你所看到的,这是一个糟糕的答案。在您阅读此内容后,我将删除我更好的解决方案。 不,你不需要这个,我也没有强迫你删除你的答案。你最好不要这样做。当然,纯代码解决方案很棒,但带有解释的解决方案非常好,并且获得了更多的支持。【参考方案5】:

有一种方法可以使用不同尺寸的图像,具体取决于设备。它被称为资产目录。您的项目中可能已经有一个,或者如果没有,您可以使用File > New > File > Resource > Asset Catalogue 添加一个。

在您的资产目录中,您可以拥有多个“图像集”(这些将显示在左侧下方)。添加底部带有“+”的新图像集。对于每个图像集,您可以为@1x、@2x 和@3x 中的每一个提供不同的图像(例如不同大小的图像)。

然后,要在代码中使用这些图像之一,您只需使用 UIImage(named: "name_of_image_set") - 注意不要扩展。将加载正确的图像,具体取决于设备。

希望这会有所帮助!

【讨论】:

问题是较大的图像超出了导航栏。使用 Avijit 的解决方案对其进行了排序

以上是关于导航栏按钮项目的图像 swift的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift 4中的导航栏上添加图像后退按钮

Swift:如何通过按导航栏按钮访问标签栏项目

JSQ 消息视图控制器:在导航栏上添加“返回”按钮和图像,Swift

导航栏中的 Swift 自定义后退按钮

不在导航栏上制作栏按钮项目和标题(iOS,Swift)

Swift 自定义导航项