it-swarm.com.de

Fügen Sie Untertitel unter dem Titel in der Navigationsleiste in Xcode hinzu

Ich möchte also unter dem Titel in der Navigationsleiste in der Navigationssteuerung einen "Untertitel" hinzufügen.

Meistens alles, was ich bis jetzt schaue, möchte, dass ich CGRect verwende. Ich weiß nicht viel darüber, was das ist, und es hört sich an, als wollte ich eine völlig neue Sichtweise schaffen, die ich nicht tun möchte.

Meine Frage ist, gibt es eine Punktmethode, um eine Untertitelansicht leicht hinzuzufügen?

Das nächste, was ich gefunden habe, wurde auf Stack Overflow gepostet und hier ist der Link:

Untertitel in der Navigationsleiste erstellen

Anscheinend hat das letztes Jahr funktioniert, aber jetzt bekomme ich Fehler und es ist in meinem viewDidLoad ...

Ich habe das versucht:

self.navigationController? .navigationItem.Prompt = "Untertitel hier"

Es ist das einzige, was keine Fehler anzeigt, aber trotzdem nicht funktioniert. Es tut buchstäblich nichts. Zumindest nichts zur Laufzeit sichtbar.

Nebenbei bemerkt wird Swift bevorzugt. Vielen Dank!

29
AdrianGutierrez

Es gibt zwar eine Lösung, aber es gibt einige bekannte Probleme

Lösung schreibt eine Funktion wie diese

func setTitle(title:String, subtitle:String) -> UIView {
    let titleLabel = UILabel(frame: CGRectMake(0, -2, 0, 0))

    titleLabel.backgroundColor = UIColor.clearColor()
    titleLabel.textColor = UIColor.grayColor()
    titleLabel.font = UIFont.boldSystemFontOfSize(17)
    titleLabel.text = title
    titleLabel.sizeToFit()

    let subtitleLabel = UILabel(frame: CGRectMake(0, 18, 0, 0))
    subtitleLabel.backgroundColor = UIColor.clearColor()
    subtitleLabel.textColor = UIColor.blackColor()
    subtitleLabel.font = UIFont.systemFontOfSize(12)
    subtitleLabel.text = subtitle
    subtitleLabel.sizeToFit()

    let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
    titleView.addSubview(titleLabel)
    titleView.addSubview(subtitleLabel)

    let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width

    if widthDiff < 0 {
        let newX = widthDiff / 2
        subtitleLabel.frame.Origin.x = abs(newX)
    } else {
        let newX = widthDiff / 2
        titleLabel.frame.Origin.x = newX
    }

    return titleView
}

Verwendung dieser Funktion für die benutzerdefinierte Titelansicht in viewDidLoad

self.navigationItem.titleView = setTitle("Title", subtitle: "SubTitle")

Das einzige bekannte Problem ist, dass, wenn Untertitel sehr groß werden, die Fehlpositionierung auftritt.

Endergebnis  enter image description here

Quelle: https://Gist.github.com/nazywamsiepawel/0166e8a71d74e96c7898

43

Hier ist meine Version mit einer Stack-Ansicht auf einer Erweiterung. 

extension UINavigationItem {



     func setTitle(title:String, subtitle:String) {

            let one = UILabel()
            one.text = title
            one.font = UIFont.systemFont(ofSize: 17)
            one.sizeToFit()

            let two = UILabel()
            two.text = subtitle
            two.font = UIFont.systemFont(ofSize: 12)
            two.textAlignment = .center
            two.sizeToFit()



            let stackView = UIStackView(arrangedSubviews: [one, two])
            stackView.distribution = .equalCentering
            stackView.axis = .vertical

            let width = max(one.frame.size.width, two.frame.size.width)
            stackView.frame = CGRect(x: 0, y: 0, width: width, height: 35)

            one.sizeToFit()
            two.sizeToFit()



            self.titleView = stackView
        }
    }
50
user2325031

Vielen Dank für deine Antwort! @ Rajan Maheshwari 

Ihre Codierung hat einwandfrei funktioniert, mit Ausnahme der if-Anweisung, die Sie mit widthDiff gemacht haben.

Ich habe es ein wenig angepasst und alles hat reibungslos funktioniert.

if widthDiff < 0 {
        let newX = widthDiff / 2
        subtitleLabel.frame.Origin.x = abs(newX)
    } else {
        let newX = widthDiff / 2
        titleLabel.frame.Origin.x = newX
    }

Nochmals vielen Dank für Ihre Antwort!

11
AdrianGutierrez

@ iosjillian's Swift 4-Erweiterung funktioniert hervorragend und fügt ein bisschen mehr hinzu, um das Erscheinungsbild der Leiste und die Präferenzen der Benutzer zu berücksichtigen:

import UIKit

extension UINavigationItem {

  func setTitle(_ title: String, subtitle: String) {
    let appearance = UINavigationBar.appearance()
    let textColor = appearance.titleTextAttributes?[NSAttributedString.Key.foregroundColor] as? UIColor ?? .black

    let titleLabel = UILabel()
    titleLabel.text = title
    titleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.headline)
    titleLabel.textColor = textColor

    let subtitleLabel = UILabel()
    subtitleLabel.text = subtitle
    subtitleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.subheadline)
    subtitleLabel.textColor = textColor.withAlphaComponent(0.75)

    let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
    stackView.distribution = .equalCentering
    stackView.alignment = .center
    stackView.axis = .vertical

    self.titleView = stackView
  }
}
3
Dan

Falls jemand nach Objective-C-Code der oben genannten Lösung sucht 

    UILable *title = [[UILabel alloc]init];
    UILabel *subtitle = [[UILabel alloc]init];

   [title setFont:[UIFont systemFontOfSize:12]];
   [title setTextColor:[UIColor whiteColor]];
   [title setFont:[UIFont systemFontOfSize:17]];
   [title sizeToFit];
   title.text = @"Title";

   [subtitle setTextColor:[UIColor whiteColor]];
   [subtitle setFont:[UIFont systemFontOfSize:12]];
   [subtitle setTextAlignment:NSTextAlignmentCenter];
   [subtitle sizeToFit];
   subtitle.text = @"Subtitle Title";

   UIStackView *stackVw = [[UIStackView alloc]initWithArrangedSubviews:@[title,subtitle]];
   stackVw.distribution = UIStackViewDistributionEqualCentering;
   stackVw.axis = UILayoutConstraintAxisVertical;
   stackVw.alignment =UIStackViewAlignmentCenter;


   [stackVw setFrame:CGRectMake(0, 0, MAX(title.frame.size.width, subtitle.frame.size.width), 35)];
   self.navigationItem.titleView = stackVw;
3
Mubeen Qazi

Vielen Dank für die Antwort @ Rajan Maheshwari

Wenn jemand das Problem hat, dass der Titel falsch ausgerichtet wird, wenn der Untertiteltext länger als der Titeltext ist, fügte ich der unten stehenden Antwort des Rajans den folgenden Code hinzu, in dem das Untertitellabel instanziiert wird:

// Fix incorrect width bug
if (subtitleLabel.frame.size.width > titleLabel.frame.size.width) {
    var titleFrame = titleLabel.frame
    titleFrame.size.width = subtitleLabel.frame.size.width
    titleLabel.frame = titleFrame
    titleLabel.textAlignment = .center
}

Ich hoffe, das hilft jemandem, der das gleiche Problem wie ich hatte

2
Nick Kirsten

Schnell 4:

import UIKit

class NavigationTitleView: UIView {

    private var contentStackView = UIStackView()
    private var titleLabel = UILabel()
    private var subTitleLabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)

        viewConfig()
        addViewsConfig()
        layoutViewsConfig()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    func set(title: String, subTitle: String){

        self.titleLabel.text = title
        self.subTitleLabel.text = subTitle

    }

    private func viewConfig() {

        contentStackView.axis = .vertical
        contentStackView.alignment = .center
        contentStackView.distribution  = .fill
        contentStackView.spacing = 5


        self.backgroundColor = .clear
        self.titleLabel.textColor = .white
        self.self.subTitleLabel.textColor = .white

    }

    private func addViewsConfig() {

        contentStackView.addArrangedSubview(subTitleLabel)
        contentStackView.addArrangedSubview(titleLabel)
        self.addSubview(contentStackView)

    }

    private func layoutViewsConfig(){

        contentStackView.translatesAutoresizingMaskIntoConstraints = false
        contentStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0.0).isActive = true
        contentStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true

    }

}

Benutzen:

import UIKit

class  ViewController: UIViewController {

    private var navigationTitleView = NavigationTitleView()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.titleView = navigationTitleView
        navigationTitleView.set(title: "title", subTitle: "subTitle")

    }

}

 enter image description here

1

Eine andere Lösung, die nur one und NSAttributedString verwendet, um zwischen Titel und Untertitel (mit unterschiedlichen Schriftgrößen, Schriftstärken, Farben usw.) zu unterscheiden. Entfernt das Problem der unterschiedlichen Etikettenausrichtung. 

extension UIViewController {
    func setTitle(_ title: String, subtitle: String) {
        let rect = CGRect(x: 0, y: 0, width: 400, height: 50)
        let titleSize: CGFloat = 20     // adjust as needed
        let subtitleSize: CGFloat = 15

        let label = UILabel(frame: rect)
        label.backgroundColor = .clear
        label.numberOfLines = 2
        label.textAlignment = .center
        label.textColor = .black

        let text = NSMutableAttributedString()
        text.append(NSAttributedString(string: title, attributes: [.font : UIFont.boldSystemFont(ofSize: titleSize)]))
        text.append(NSAttributedString(string: "\n\(subtitle)", attributes: [.font : UIFont.systemFont(ofSize: subtitleSize)]))
        label.attributedText = text
        self.navigationItem.titleView = label
    }
}

Benutzerdefinierte titleView basiert teilweise auf https://stackoverflow.com/a/34298491/3918865

1

Die Antwort von @ user2325031 hat mir sehr gefallen, aber ich fand, dass es nicht nötig war, die Beschriftungen an die Größe anzupassen und den Rahmen einzustellen. Ich habe auch die Ausrichtung von stackView auf .center per @ GerardoMRs Vorschlag gesetzt.

extension UINavigationItem {

    func setTitle(_ title: String, subtitle: String) {
        let titleLabel = UILabel()
        titleLabel.text = title
        titleLabel.font = .systemFont(ofSize: 17.0)
        titleLabel.textColor = .black

        let subtitleLabel = UILabel()
        subtitleLabel.text = subtitle
        subtitleLabel.font = .systemFont(ofSize: 12.0)
        subtitleLabel.textColor = .gray

        let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
        stackView.distribution = .equalCentering
        stackView.alignment = .center
        stackView.axis = .vertical

        self.titleView = stackView
    }

}
0
iosjillian