【问题标题】:iOS - add image and text in title of Navigation bariOS - 在导航栏的标题中添加图像和文本
【发布时间】:2016-07-24 03:14:52
【问题描述】:

我想创建一个导航栏,类似于所附图片中的内容。

导航栏的标题将是图像和文本的组合。

  1. 是否应该按照任何最佳实践来执行此操作?

  2. 怎么做?

【问题讨论】:

    标签: swift navigationbar


    【解决方案1】:

    作为this answer shows,最简单的解决方案是将文本添加到您的图像中,然后将该图像添加到导航栏,如下所示:

    var image = UIImage(named: "logo.png")
    self.navigationItem.titleView = UIImageView(image: image)
    

    但如果您必须分别添加文本和图像(例如,在本地化的情况下),您可以将导航栏的标题视图设置为包含图像和文本,方法是将它们添加到 UIView 并设置navigationItem 的标题视图到 UIView,例如(假设导航栏是导航控制器的一部分):

    // Only execute the code if there's a navigation controller 
    if self.navigationController == nil {
        return
    }
    
    // Create a navView to add to the navigation bar
    let navView = UIView()
    
    // Create the label
    let label = UILabel()
    label.text = "Text"
    label.sizeToFit()
    label.center = navView.center
    label.textAlignment = NSTextAlignment.Center
    
    // Create the image view
    let image = UIImageView()
    image.image = UIImage(named: "Image.png")
    // To maintain the image's aspect ratio:
    let imageAspect = image.image!.size.width/image.image!.size.height
    // Setting the image frame so that it's immediately before the text:
    image.frame = CGRect(x: label.frame.origin.x-label.frame.size.height*imageAspect, y: label.frame.origin.y, width: label.frame.size.height*imageAspect, height: label.frame.size.height)
    image.contentMode = UIViewContentMode.ScaleAspectFit
    
    // Add both the label and image view to the navView
    navView.addSubview(label)
    navView.addSubview(image)
    
    // Set the navigation bar's navigation item's titleView to the navView
    self.navigationItem.titleView = navView
    
    // Set the navView's frame to fit within the titleView
    navView.sizeToFit()
    

    【讨论】:

    • @NaveedAhmad。谢谢女士,不是男人。 :)
    【解决方案2】:

    使用水平的UIStackView 应该更干净更容易

    请将下一个扩展名添加到UIViewController

    extension UIViewController {
        func setTitle(_ title: String, andImage image: UIImage) {
            let titleLbl = UILabel()
            titleLbl.text = title
            titleLbl.textColor = UIColor.white
            titleLbl.font = UIFont.systemFont(ofSize: 20.0, weight: .bold)
            let imageView = UIImageView(image: image)
            let titleView = UIStackView(arrangedSubviews: [imageView, titleLbl])
            titleView.axis = .horizontal
            titleView.spacing = 10.0
            navigationItem.titleView = titleView
        }
    }
    

    然后在你的 viewController 中使用它:

    setTitle("yourTitle", andImage: UIImage(named: "yourImage"))
    

    (这会将文本和图标一起对齐到中心,如果您希望文本居中并且图标在左侧,只需添加一个空的UIView,其宽度限制等于图标宽度)

    【讨论】:

    • @AwaisFayyaz 你能提供更多细节吗?
    • 我复制粘贴了您的代码并运行它。但是标题没有显示。我正在导航控制器的根视图控制器中编写此代码。
    • 这非常有效。非常感谢。对于某些人来说,标题可能不会显示,因为 textColor 是白色的。
    • 伟大而“迅速”的解决方案,也非常简单。谢谢!
    【解决方案3】:

    这是我为 Swift 4 支付的 2 美分,因为接受的答案对我不起作用(大部分不在屏幕上):

    // .. in ViewController
    var navBar = CustomTitleView()
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
    
        // =================== navBar =====================
        navBar.loadWith(title: "Budget Overview", leftImage: Images.pie_chart)
        self.navigationItem.titleView = navBar
    
    }
    
    class CustomTitleView: UIView
    {
    
    var title_label = CustomLabel()
    var left_imageView = UIImageView()
    
    override init(frame: CGRect){
        super.init(frame: frame)
        setup()
    }
    
    required init?(coder aDecoder: NSCoder){
        super.init(coder: aDecoder)
        setup()
    }
    
    func setup(){
        self.addSubview(title_label)
        self.addSubview(left_imageView)
    
    }
    
    func loadWith(title: String, leftImage: UIImage?)
    {
    
        //self.backgroundColor = .yellow
    
        // =================== title_label ==================
        //title_label.backgroundColor = .blue
        title_label.text = title
        title_label.font = UIFont.systemFont(ofSize: FontManager.fontSize + 5)
    
    
        // =================== imageView ===================
        left_imageView.image = leftImage
    
        setupFrames()
    }
    
    func setupFrames()
    {
    
        let height: CGFloat = Navigation.topViewController()?.navigationController?.navigationBar.frame.height ?? 44
        let image_size: CGFloat = height * 0.8
    
        left_imageView.frame = CGRect(x: 0,
                                      y: (height - image_size) / 2,
                                      width: (left_imageView.image == nil) ? 0 : image_size,
                                      height: image_size)
    
        let titleWidth: CGFloat = title_label.intrinsicContentSize.width + 10
        title_label.frame = CGRect(x: left_imageView.frame.maxX + 5,
                                   y: 0,
                                   width: titleWidth,
                                   height: height)
    
    
    
        contentWidth = Int(left_imageView.frame.width)
        self.frame = CGRect(x: 0, y: 0, width: CGFloat(contentWidth), height: height)
    }
    
    
    var contentWidth: Int = 0 //if its CGFloat, it infinitely calls layoutSubviews(), changing franction of a width 
    override func layoutSubviews() {
        super.layoutSubviews()
    
        self.frame.size.width = CGFloat(contentWidth)
    
    }
    
    }
    

    【讨论】:

    • 这很好用。现在我正在尝试将图像和标签左对齐到左侧按钮栏。我应该使用约束来做到这一点吗?谢谢
    【解决方案4】:

    Swift 4.2 + Interface Builder 解决方案

    作为Lyndsey Scottanswer 的后续,您还可以在Interface Builder 中创建一个UIView .xib,使用它来布置您的标题和图像,然后对其进行更新-通过@IBOutlet 飞行。这对于动态内容、国际化、可维护性等很有用。

    创建一个带有UILabel 插座的UIView 子类,并将您的新.xib 分配给该类:

    import UIKit
    
    class FolderTitleView: UIView {
    
        @IBOutlet weak var title : UILabel!
    
        /// Create an instance of the class from its .xib
        class func instanceFromNib() -> FolderTitleView {
            return UINib(nibName: "FolderTitleView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! FolderTitleView
        }
    }
    

    将标签连接到您的 .xib 中的插座(在我的示例中为 title),然后在您的 UIViewController 中:

    /// Reference to the title view
    var folderTitleView : FolderTitleView?
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // Set the screen title to match the active folder
        updateTitle()    
    }
    
    /// Updates the title of the navigation controller.
    func updateTitle() {
        self.title = ""
        if folderTitleView == nil {
            folderTitleView = FolderTitleView.instanceFromNib()
            self.navigationItem.titleView = folderTitleView
        }
        folderTitleView!.title.text = "Listening"
        folderTitleView!.layoutIfNeeded()
    }
    

    这会产生一个带有嵌入图像的漂亮的自居中标题栏,您可以轻松地从代码中更新它。

    【讨论】:

      【解决方案5】:

      // 为我工作

      1. 创建视图并设置框架
      2. 现在在视图中添加图像并设置框架
      3. 添加图片后,在同一视图中添加标签并设置框架
      4. 将图片和标签添加到视图后,将相同的视图添加到navigationItem

        让 navigationView = UIView(frame: CGRect(x: 0, y: 0, width: 50 , height: 55))

        let labell : UILabel = UILabel(frame: CGRect(x: -38, y: 25, width: 150, height: 25))
        labell.text = "Your text"
        labell.textColor = UIColor.black
        labell.font = UIFont.boldSystemFont(ofSize: 10)
        navigationView.addSubview(labell)
        
        let image : UIImage = UIImage(named: ValidationMessage.headerLogoName)!
        let imageView = UIImageView(frame: CGRect(x: -20, y: 0, width: 100, height: 30))
        imageView.contentMode = .scaleAspectFit
        imageView.image = image
        //navigationItem.titleView = imageView
        
        navigationView.addSubview(imageView)
        
        navigationItem.titleView = navigationView
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-22
        • 1970-01-01
        • 1970-01-01
        • 2018-04-14
        • 1970-01-01
        • 2022-01-22
        • 2021-03-23
        • 2018-06-23
        相关资源
        最近更新 更多