Navigationsleiste mit UIImage für Titel

70

Ich möchte das Aussehen meiner App anpassen, indem ich anstelle von einfachem Text ein Logo als Titel der Navigationsleiste verwende. Wenn ich diesen Code benutze

let logo = UIImage(named: "logo.png")
self.navigationItem.titleView = logo;

Ich erhalte die Fehlermeldung "UIImage kann nicht in UIView konvertiert werden". Wie kann ich das richtig machen?

Darx
quelle

Antworten:

185

Legen Sie es in eine UIImageView

let logo = UIImage(named: "logo.png")
let imageView = UIImageView(image:logo)
self.navigationItem.titleView = imageView
Jack
quelle
Wo in der Klassenerklärung setzen Sie das?
Azochz
@JackWu Es funktioniert nicht, wenn ich es hinzufüge UINavigationController.viewDidLoad(die Klasse, die ich für den Navigationscontroller implementiert habe), aber es funktioniert, wenn ich es hinzufüge ViewController. Aber ich möchte diesen Code getrennt halten (also innerhalb meiner Klasse, die UINavigationController erweitert). Ist es möglich?
Patriks
@ Ronaldoh1 Dies tut genau das, was Sie in Ihrer Antwort sind, also weiß ich nicht, wie Sie sagen können "das funktioniert nicht mehr"
Jack
3
Dies funktioniert, aber Sie müssen viewDidLoadden Ansichts-Controller verwenden, der an den Navigations-Controller gesendet wird, nicht den Navigations-Controller selbst.
Martin Marconcini
@ MartínMarconcini Vielen Dank für die Klarstellung. Das war das Problem.
dcgoss
57

Ich benutze das. Es funktioniert in iOS 8

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    let image = UIImage(named: "YOURIMAGE")
    navigationItem.titleView = UIImageView(image: image)
}

Und hier ist ein Beispiel, wie Sie es mit CGRect machen können.

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 38, height: 38))
    imageView.contentMode = .ScaleAspectFit
    let image = UIImage(named: "YOURIMAGE")
    imageView.image = image
    navigationItem.titleView = imageView
}

Hoffe das wird helfen.

Fernando S. Kroes
quelle
Wo in der Unterklasse der Navigationsleiste platzieren Sie dies?
Hossein
@Hossein Ich kann mich nicht erinnern, es ist eine Weile her und ich habe das Projekt nicht. Es tut uns leid.
Fernando S. Kroes
2
Dies funktionierte besser und das Bild wurde so skaliert, wie ich es wollte. Dies sollte die akzeptierte Antwort sein.
Munib
34

Für Swift 4 und Sie können die Größe der Bildansicht anpassen

 let logoContainer = UIView(frame: CGRect(x: 0, y: 0, width: 270, height: 30))

 let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 270, height: 30))
 imageView.contentMode = .scaleAspectFit
 let image = UIImage(named: "your_image")
 imageView.image = image
 logoContainer.addSubview(imageView)
 navigationItem.titleView = logoContainer
vp2698
quelle
Vielen Dank
Mohammad Razipour
13

Ich habe die Antwort von @ Jack oben ausprobiert. Das Logo wurde angezeigt, das Bild nahm jedoch die gesamte Navigationsleiste ein. Ich wollte, dass es passt.

Swift 4, Xcode 9.2

1. Weisen Sie dem Navigationscontroller UIImage einen Wert zu. Passen Sie die Größe an, indem Sie den Rahmen und die Bildgröße teilen.

func addNavBarImage() {

        let navController = navigationController!

        let image = UIImage(named: "logo-signIn6.png") //Your logo url here
        let imageView = UIImageView(image: image)

        let bannerWidth = navController.navigationBar.frame.size.width
        let bannerHeight = navController.navigationBar.frame.size.height

        let bannerX = bannerWidth / 2 - (image?.size.width)! / 2
        let bannerY = bannerHeight / 2 - (image?.size.height)! / 2

        imageView.frame = CGRect(x: bannerX, y: bannerY, width: bannerWidth, height: bannerHeight)
        imageView.contentMode = .scaleAspectFit

        navigationItem.titleView = imageView
    }
  1. Fügen Sie die Funktion direkt unter hinzu viewDidLoad()

        addNavBarImage() 
    

Hinweis zum Bildobjekt. Vor dem Hochladen habe ich das Logo mit zusätzlichen Rändern angepasst, anstatt es an den Rändern zu beschneiden.

Endergebnis:

Geben Sie hier die Bildbeschreibung ein

Nachteile Bulaquena
quelle
Großartig. Vielen Dank Kumpel!
Mark
@Mark Habe gerade ein weiteres Nekromanten-Abzeichen verdient. Hoffe, es hat Ihren Bar Image Mate repariert!
Nachteile Bulaquena
Das Ändern der Größe hat bei mir nicht funktioniert, aber ich habe es behoben, indem ich die Breite der rechten und linken Balkenelemente vergrößert habe.
Coder ACJHP
9

Sie können ein benutzerdefiniertes UINavigationItem verwenden, sodass Sie nur "Navigationselement" als YourCustomClass auf dem Main.storyboard ändern müssen.

In Swift 3

class FixedImageNavigationItem: UINavigationItem {

private let fixedImage : UIImage = UIImage(named: "your-header-logo.png")!
private let imageView : UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 37.5))

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    imageView.contentMode = .scaleAspectFit
    imageView.image = fixedImage
    self.titleView = imageView

}

}
Photonenpunkt
quelle
5

Das hat bei mir im September 2015 funktioniert - Ich hoffe, das hilft jemandem da draußen.

// 1
    var nav = self.navigationController?.navigationBar
    // 2 set the style 
    nav?.barStyle = UIBarStyle.Black
    nav?.tintColor = UIColor.yellowColor()
    // 3
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
    imageView.contentMode = .ScaleAspectFit
    // 4
    let image = UIImage(named: "logo.png")
    imageView.image = image
    // 5
    navigationItem.titleView = imageView
Ronaldoh1
quelle
1
Wenn diese Lösung nicht funktioniert, erstellen Sie einen Verweis auf die Navigationsleiste in der UIViewController-Klasse. @IBOutlet schwach var navBar: UINavigationBar! Dann statt zu navigationItem.titleView = imageViewtun self.navBar.topItem?.titleView = imageView Es wird hier erklärt:
knopch1425
5

Hier ist eine praktische Funktion für Swift 4.2, die ein Bild mit Titeltext zeigt: -

Geben Sie hier die Bildbeschreibung ein

override func viewDidLoad() {

    super.viewDidLoad()

    //Sets the navigation title with text and image
    self.navigationItem.titleView = navTitleWithImageAndText(titleText: "Dean Stanley", imageName: "online")
}

func navTitleWithImageAndText(titleText: String, imageName: String) -> UIView {

    // Creates a new UIView
    let titleView = UIView()

    // Creates a new text label
    let label = UILabel()
    label.text = titleText
    label.sizeToFit()
    label.center = titleView.center
    label.textAlignment = NSTextAlignment.center

    // Creates the image view
    let image = UIImageView()
    image.image = UIImage(named: imageName)

    // Maintains the image's aspect ratio:
    let imageAspect = image.image!.size.width / image.image!.size.height

    // Sets the image frame so that it's immediately before the text:
    let imageX = label.frame.origin.x - label.frame.size.height * imageAspect
    let imageY = label.frame.origin.y

    let imageWidth = label.frame.size.height * imageAspect
    let imageHeight = label.frame.size.height

    image.frame = CGRect(x: imageX, y: imageY, width: imageWidth, height: imageHeight)

    image.contentMode = UIView.ContentMode.scaleAspectFit

    // Adds both the label and image view to the titleView
    titleView.addSubview(label)
    titleView.addSubview(image)

    // Sets the titleView frame to fit within the UINavigation Title
    titleView.sizeToFit()

    return titleView

}
Gagandeep Gambhir
quelle
Das funktioniert super. Eine Frage: Wie können wir sicherstellen, dass das Bild immer kreisförmig ist? Wie soll der Eckenradius eingestellt werden? @ Gagandeep
Vandal
3

Swift 5.1, Xcode 11

Manchmal, wenn Ihr Bild in hoher Auflösung ist, verschiebt sich imageView von der Mitte. Ich würde empfehlen, diese Methode zu verwenden

  lazy var navigationTitleImageView = UIImageView()

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.setNavigationBar()
    
    self.navigationTitleImageView.image = logo
    self.navigationTitleImageView.contentMode = .scaleAspectFit
    
    self.navigationTitleImageView.translatesAutoresizingMaskIntoConstraints = false
    
    if let navC = self.navigationController{
        navC.navigationBar.addSubview(self.navigationTitleImageView)
        self.navigationTitleImageView.centerXAnchor.constraint(equalTo: navC.navigationBar.centerXAnchor).isActive = true
        self.navigationTitleImageView.centerYAnchor.constraint(equalTo: navC.navigationBar.centerYAnchor, constant: 0).isActive = true
        self.navigationTitleImageView.widthAnchor.constraint(equalTo: navC.navigationBar.widthAnchor, multiplier: 0.2).isActive = true
        self.navigationTitleImageView.heightAnchor.constraint(equalTo: navC.navigationBar.widthAnchor, multiplier: 0.088).isActive = true
    }
}

und viewWillDisappear ()

  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationTitleImageView.removeFromSuperview()
}

oder reduzieren Sie einfach die Bildgröße

Kedar Sukerkar
quelle
2

Wenn Sie das automatische Layout bevorzugen und ein dauerhaftes festes Bild in der Navigationsleiste wünschen, das nicht bei jedem Bildschirm animiert wird, funktioniert diese Lösung gut:

class CustomTitleNavigationController: UINavigationController {

override func viewDidLoad() {
    super.viewDidLoad()

    let logo = UIImage(named: "MyHeaderImage")

    let imageView = UIImageView(image:logo)
    imageView.contentMode = .scaleAspectFit
    imageView.translatesAutoresizingMaskIntoConstraints = false

    navigationBar.addSubview(imageView)

    navigationBar.addConstraint (navigationBar.leftAnchor.constraint(equalTo: imageView.leftAnchor, constant: 0))
    navigationBar.addConstraint (navigationBar.rightAnchor.constraint(equalTo: imageView.rightAnchor, constant: 0))
    navigationBar.addConstraint (navigationBar.topAnchor.constraint(equalTo: imageView.topAnchor, constant: 0))
    navigationBar.addConstraint (navigationBar.bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 0))
}
Danfordham
quelle
2

Ich habe dies für iOS 10 und iOS 11 geschrieben und es hat bei mir funktioniert:

extension UINavigationBar {
    func setupNavigationBar() {
        let titleImageWidth = frame.size.width * 0.32
        let titleImageHeight = frame.size.height * 0.64
        var navigationBarIconimageView = UIImageView()
        if #available(iOS 11.0, *) {
            navigationBarIconimageView.widthAnchor.constraint(equalToConstant: titleImageWidth).isActive = true
            navigationBarIconimageView.heightAnchor.constraint(equalToConstant: titleImageHeight).isActive = true
        } else {
            navigationBarIconimageView = UIImageView(frame: CGRect(x: 0, y: 0, width: titleImageWidth, height: titleImageHeight))
        }
        navigationBarIconimageView.contentMode = .scaleAspectFit
        navigationBarIconimageView.image = UIImage(named: "image")
        topItem?.titleView = navigationBarIconimageView
    }
}
Narine Balasanyan
quelle
1

Lassen Sie uns versuchen, auszuchecken

let image = UIImage(named: "Navbar_bg.png")
navigationItem.titleView = UIImageView(image: image)
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
imageView.contentMode = .ScaleAspectFit
Yonathan Yuri Faber
quelle
2
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich dabei, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Vaultah
1
    let imageView = UIImageView(frame: (CGRect(x: 0, y: 0, width: 40, height: 
    40)))
    imageView.contentMode = .scaleAspectFit
    let image = UIImage (named: "logo") // logo is your NPG asset 
    imageView.image = image
    self.navigationItem.titleView = imageView
mila kohen
quelle
3
Bitte erläutern Sie, was Ihr Code bewirkt. Nur-Code-Antworten werden in StackOverflow als schlechte Qualität angesehen.
Quinz
1

Funktioniert für mich in Swift 4 (quadratisches Bild 40x40)

let imageView = UIImageView()
imageView.frame.size.width = 40
imageView.frame.size.height = 40
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "YOUR_IMAGE_NAME")
imageView.image = image
navigationItem.titleView = imageView

Wenn Sie andere Maßnahmen wünschen, versuchen Sie es

let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 100.5)))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "YOUR_IMAGE_NAME")
imageView.image = image
navigationItem.titleView = imageView

Ich hoffe es dient dir. Für mich geht das.

Oscar Castellon
quelle
1

Programmatisch könnte so gemacht werden.

private var imageView: UIView {

    let bannerWidth = navigationBar.frame.size.width * 0.5 // 0.5 its multiplier to get correct image width
    let bannerHeight = navigationBar.frame.size.height

    let view = UIView()
    view.backgroundColor = .clear
    view.frame = CGRect(x: 0, y: 0, width: bannerWidth, height: bannerHeight)

    let image = UIImage(named: "your_image_name")
    let imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFit
    imageView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)

    view.addSubview(imageView)

    return view
}

Das ändert einfach titleView

navigationItem.titleView = imageView
Владислав Шматок
quelle
0

Objective-C- Version:

//create the space for the image
UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 256, 144)];
//bind the image with the ImageView allocated
myImage.image = [UIImage imageNamed:@"logo.png"];
//add image into imageview
_myNavigationItem.titleView = myImage;

Nur für den Fall, dass jemand (wie ich) hier angekommen ist und nach der Antwort in Ziel-C gesucht hat .

Jack T.
quelle
0

Das hat bei mir funktioniert ... probier es aus

let image : UIImage = UIImage(named: "LogoName")
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
imageView.contentMode = .scaleAspectFit
imageView.image = image
navigationItem.titleView = imageView
Sohail
quelle
0

Um die Bildansicht mit der richtigen Größe und in der Mitte zu erhalten, sollten Sie den folgenden Ansatz verwenden:

let width = 120 // choose the image width
let height = 20 // choose the image height
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)) //44 is the standard size of the top bar
let imageView = UIImageView(frame: CGRect(x: (view.bounds.width - width)/2, y: (44 - height)/2, width: width, height: height))
imageView.contentMode = .scaleAspectFit //choose other if it makes sense
imageView.image = UIImage(named: "your_image_name")
titleView.addSubview(imageView)
navigationItem.titleView = titleView
Felipe Almeida
quelle