如何动态调整导航栏中的标题大小

时间:2013-02-19 11:38:36

标签: iphone uinavigationcontroller resize uinavigationbar autoresize

我有一些显示在导航控制器中的视图。其中两个视图的导航栏标题较长。

问题是,当标题太长而不适合时,某些字符会被截断并添加“...”。

有什么办法可以告诉导航栏自动调整标题文字的大小以适应吗?

9 个答案:

答案 0 :(得分:35)

在ViewDidload中使用以下代码。

目标C

self.title = @"Your TiTle Text";
UILabel* tlabel=[[UILabel alloc] initWithFrame:CGRectMake(0,0, 200, 40)];
tlabel.text=self.navigationItem.title;
tlabel.textColor=[UIColor whiteColor];
tlabel.font = [UIFont fontWithName:@"Helvetica-Bold" size: 30.0];
tlabel.backgroundColor =[UIColor clearColor];
tlabel.adjustsFontSizeToFitWidth=YES;
tlabel.textAlignment = NSTextAlignmentCenter;
self.navigationItem.titleView=tlabel;

Swift版

self.title = "Your Title Text"
let tlabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
tlabel.text = self.title
tlabel.textColor = UIColor.white
tlabel.font = UIFont.systemFont(ofSize: 30, weight: .bold)
tlabel.backgroundColor = UIColor.clear
tlabel.adjustsFontSizeToFitWidth = true
tlabel.textAlignment = .center
self.navigationItem.titleView = tlabel

希望它适合你。谢谢

答案 1 :(得分:9)

Swift版本的Accepted Answer +将标签文本放在中心位置:

Swift 2.3:

    self.title = "Your TiTle Text"
    let tlabel = UILabel(frame: CGRectMake(0, 0, 200, 40))
    tlabel.text = self.title
    tlabel.textColor = UIColor.whiteColor()
    tlabel.font = UIFont.boldSystemFontOfSize(17) //UIFont(name: "Helvetica", size: 17.0)
    tlabel.backgroundColor = UIColor.clearColor()
    tlabel.adjustsFontSizeToFitWidth = true
    tlabel.textAlignment = .Center
    self.navigationItem.titleView = tlabel

和Swift 3:

    self.title = "Your TiTle Text"
    let frame = CGRect(x: 0, y: 0, width: 200, height: 40)
    let tlabel = UILabel(frame: frame)
    tlabel.text = self.title
    tlabel.textColor = UIColor.white
    tlabel.font = UIFont.boldSystemFont(ofSize: 17) //UIFont(name: "Helvetica", size: 17.0)
    tlabel.backgroundColor = UIColor.clear
    tlabel.adjustsFontSizeToFitWidth = true
    tlabel.textAlignment = .center
    self.navigationItem.titleView = tlabel

答案 2 :(得分:1)

上述解决方案均无法为我提供可靠的解决方案。 但是我通过使用提供答案的不同元素找到了一个解决方案,它在Swift 2中非常优雅,因为每次更改标签时都不需要任何自定义代码,它只是在标题上使用属性观察者。

请注意,在我的情况下,我在导航栏的左侧有一个后退按钮,它将文本从屏幕中心推出,以解决此问题,我使用了属性文本和tailIndent。以下代码中的所有评论/信息:

class VCHowToTopic : UIViewController {


    //add handlers so that any manipulation of the title is caught and transferred to the custom drawn UILabel
    override var title : String? {
        set {
            super.title = newValue
            configureTitleView()
        }
        get {
            return super.title
        }
    }

    //MARK: - lifecycle


    func configureTitleView() {
        //some large number that makes the navigationbar schrink down our view when added
        let someVeryLargeNumber = CGFloat(4096)
        //create our label
        let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: someVeryLargeNumber, height: someVeryLargeNumber))
        //0 means unlimited number of lines
        titleLabel.numberOfLines = 0
        //define style of the text (we will be using attributed text)
        let style = NSMutableParagraphStyle()
        style.alignment = .Center
        //top compensate for the backbutton which moves the centered text to the right side of the screen
        //we introduce a negative tail indent, the number of 56 has been experimentally defined and might
        //depend on the size of your custom back button (if you have one), mine is 22x22 px
        style.tailIndent = -56
        //create attributed text also with the right color
        let attrText = NSAttributedString(string: title!, attributes: [NSParagraphStyleAttributeName : style,
            NSForegroundColorAttributeName : UIColor.whiteColor()])
        //configure the label to use the attributed text
        titleLabel.attributedText = attrText
        //add it as the titleview
        navigationItem.titleView = titleLabel
    }


}

答案 3 :(得分:1)

如果您将视图添加到titleView中,并且想要调整视图大小,则可以使用此代码(Swift 3)

self.translatesAutoresizingMaskIntoConstraints = false
self.layoutIfNeeded()
self.sizeToFit()
self.translatesAutoresizingMaskIntoConstraints = true

答案 4 :(得分:1)

您可以将UILabel创建为UINavigationItem的titleView,并将其adjustsFontSizeToFitWidth设置为true

class MyViewController: UIViewController {
    override var title: String? {
        didSet {
            (self.navigationItem.titleView as? UILabel)?.text = self.title
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.titleView = UILabel().apply {
            $0.font = .boldSystemFont(ofSize: 18)
            $0.minimumScaleFactor = 0.5
            $0.adjustsFontSizeToFitWidth = true
            $0.text = self.title
        }
    }
}

易于使用:

myViewController.title = "This is a long title, but don’t worry."

上面的代码中的apply闭包是一个技巧,目的是使编程体验更好。还有一个with闭包。推荐给大家。

protocol ScopeFunc {}

extension ScopeFunc {
    @inline(__always) func apply(_ block: (Self) -> ()) -> Self {
        block(self)
        return self
    }

    @inline(__always) func with<R>(_ block: (Self) -> R) -> R {
        return block(self)
    }
}

extension NSObject: ScopeFunc {}

答案 5 :(得分:0)

您需要使用uilabel自定义导航栏标题视图并提供调整字体大小..

    [self.navigationItem setTitleView:<"Include any UI View subclass">];

答案 6 :(得分:0)

Swift 5和iOS 13 / iOS 14

如果您在 Swift 5和iOS 13 中拥有较大的标题,则上面的答案将不起作用,因为它们只是在导航栏中添加了另一个标题。相反,您可以在需要时使用largeTitleTextAttributes属性(自iOS 11起可用)缩小标题。
假设您已经通过情节提要或代码设置了大标题,则可以使用以下方法:

private func configureNavigationTitle(_ title: String) {
        let tempLabel = UILabel()
        tempLabel.font = UIFont.systemFont(ofSize: 34, weight: .bold)
        tempLabel.text = title

        if tempLabel.intrinsicContentSize.width > UIScreen.main.bounds.width - 30 {
            var currentTextSize: CGFloat = 34
            for _ in 1 ... 34 {
                currentTextSize -= 1
                tempLabel.font = UIFont.systemFont(ofSize: currentTextSize, weight: .bold)
                if tempLabel.intrinsicContentSize.width < UIScreen.main.bounds.width - 30 {
                    break
                }
            }
            navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: currentTextSize, weight: .bold)]
        }
        self.title = title
    }

因此,基本上,我们使用助手标签来获得标题的宽度,然后缩小字体大小,直到标题适合我们的导航栏。 从viewDidLoad()调用它:

override func viewDidLoad() {
        super.viewDidLoad(
        configureNavigationTitle("A very long title which fits perfectly fine")
    }

答案 7 :(得分:-1)

这里是Swift中的一个例子,它也允许多行。使用PureLayout简化自动布局。

override func viewDidLoad() {
  super.viewDidLoad()
  configureTitleView()
}

func configureTitleView() {
  let titleLabel = UILabel()
  titleLabel.numberOfLines = 0
  titleLabel.textAlignment = .Center
  titleLabel.font = UIFont.boldSystemFontOfSize(17.0)
  titleLabel.text = searchLoc.mapItem.name
  navigationItem.titleView = titleLabel
  titleLabel.autoPinEdgesToSuperviewMargins() // PureLayout method
  titleLabel.adjustsFontSizeToFitWidth = true
}

一个用法示例:

enter image description here

答案 8 :(得分:-1)

Swift 4和iOS 13

添加此内容,以便我将来的自己找到它。由于某种原因添加到titleView的视图不希望自动调整其大小。因此,您必须手动进行操作。

示例

(navigationItem.titleView as? UILabel)?.text = "A longer string..." // label not resized and text is cut off

解决方案

navigationItem.titleView?.translatesAutoresizingMaskIntoConstraints = false
navigationItem.titleView?.setNeedsLayout()
navigationItem.titleView?.layoutIfNeeded()
navigationItem.titleView?.translatesAutoresizingMaskIntoConstraints = true

感谢@Paolo Musolino带领我来到这里。