Wie entferne ich schnell den Rand der Navigationsleiste?


131

Ich habe versucht, die NavigationBars-Grenze ohne Glück zu entfernen. Ich habe recherchiert und die Leute scheinen zu sagen, dass shadowImage und BackgroundImage auf Null gesetzt werden sollen, aber das funktioniert in meinem Fall nicht.

Mein Code

    self.navigationController?.navigationBar.barTintColor = UIColor(rgba: "#4a5866")
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(named: ""), forBarMetrics: UIBarMetrics.Default)
    self.navigationController?.navigationBar.shadowImage = UIImage(named: "")

Illustration:

Geben Sie hier die Bildbeschreibung ein

Antworten:


309

Das Problem liegt bei diesen beiden Zeilen:

self.navigationController?.navigationBar.setBackgroundImage(UIImage(named: ""), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage(named: "")

Da Sie kein Bild ohne Namen haben, wird UIImage(named: "")zurückgegeben nil, was bedeutet, dass das Standardverhalten einsetzt:

Wenn nicht Null, wird anstelle des Standardschattenbilds ein benutzerdefiniertes Schattenbild angezeigt. Damit ein benutzerdefinierter Schatten angezeigt wird, muss ein benutzerdefiniertes Hintergrundbild auch mit -setBackgroundImage: forBarMetrics: festgelegt werden (wenn das Standardhintergrundbild verwendet wird, wird das Standardschattenbild verwendet).

Sie benötigen ein wirklich leeres Bild. Initialisieren Sie also einfach mit UIImage():

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()

2
Diese Antwort funktioniert wirklich. Denn wenn Sie eine akzeptierte Antwort (Code) verwenden, wird die Symbolleiste imageViews entfernt.
Sergey Krasiuk

1
Dies sollte die akzeptierte Antwort sein. Funktioniert auch bei der Einstellung von UINavigationBar.appearance ()
Heinrisch

1
Dies sollte die akzeptierte Antwort für Swift 3 sein. Die akzeptierte Antwort funktionierte für mich in Swift 2, aber nicht in Swift 3
ColinMasters

1
Für den swift3 sollten Sie etwas anders schreiben: self.navigationController? .navigationBar.setBackgroundImage (UIImage (), für: UIBarMetrics.default) self.navigationController? .navigationBar.shadowImage = UIImage ()
Chetan Dobariya

5
Diese Methode widerspricht dem großen Titel in iOS 11
SteffenK

54

Swift 4 & Swift 5

Rand entfernen:

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for:.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.layoutIfNeeded()

Grenze wiederherstellen:

self.navigationController?.navigationBar.setBackgroundImage(nil, for:.default)
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.layoutIfNeeded()

2
Perfekte Antwort :)
PJR

Benötigen wir hier layoutIfNeeded ()?
Korgx9

1
Ja korgx9, wir brauchen es. Andernfalls ändert sich die Farbe erst beim nächsten Zeichnen.
Sazzad Hissain Khan

37

Dadurch wird das Schattenbild vollständig entfernt

for parent in self.navigationController!.navigationBar.subviews {
 for childView in parent.subviews {
     if(childView is UIImageView) {
         childView.removeFromSuperview()
     }
 }
}

1
Könnten Sie näher darauf eingehen?
Kmeixner

1
Auch für mich funktioniert diese Lösung, während die Antwort von @Nate Cook nicht funktioniert hat. : S
Luca Davanzo

2
Heiliger Schäfer !! Nach all der Suche ist dies das EINZIGE, was funktioniert hat.
Tuan Anh Vu

es funktioniert, aber ich habe auch ein Menüsymbol in der Navigationsleiste und es ist verschwunden: / Ich möchte nur, dass der Rand gelöscht wird. HILFE: /
Stephy Samaniego

Dies hat bei mir funktioniert, aber nach dem Drücken des neuen ViewControllers wird die Leitung von dort nach entfernt. Wie kann ich das verhindern?
Anirudha Mahale

36

Mit Swift 2 können Sie dies folgendermaßen tun:

AppDelegate-Datei

Innerhalb der func-Anwendung (..., didFinishLaunchingWithOptions launchOptions: ...)

UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: .Default)

für Swift 3:

UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)

Korrekte Antwort.
Ed.

Dies ist die umfassende Antwort!
madeny

Es ist besser, solche nützlichen Standardeinstellungen in Appdelegate zu schreiben, als sie an ungeraden Stellen zu schreiben. Richtige Antwort :)
Md Rais

35

Schreiben Sie dies einfach in die Erweiterung von UINavigationBar

extension UINavigationBar {

    func shouldRemoveShadow(_ value: Bool) -> Void {
        if value {
            self.setValue(true, forKey: "hidesShadow")
        } else {
            self.setValue(false, forKey: "hidesShadow")
        }
    }
}

Und aus Ihrer Sicht Controller ...

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.shouldRemoveShadow(true)        
}

Und um dies für jeden viewController rückgängig zu machen, übergeben Sie einfach false.


Dies funktioniert großartig, ABER es verbirgt sich, wenn für ALLE VCS auf dem Navi-Stack. Wenn Sie es in vc1 verwenden und vc1 auf vc2 pushen kann, wird es auch auf vc2 ausgeblendet. Um den Schatten in vc2 anzuzeigen, müssen Sie ihn in viewDidLoad auf false setzen. Das Problem ist, wenn Sie zu vc1 zurückkehren, wird es erneut angezeigt, da es in vc2 zurückgesetzt wurde. Sie müssen Logik verwenden, um hin und her zu gehen, was sich möglicherweise nicht lohnt. Wenn Sie jedoch nicht möchten, dass das Schattenbild überhaupt auf einem VCS angezeigt wird, ist dies der einfachste Weg
Lance Samaria

Nehmen wir an, wir haben einen Stapel viewController mit 5 viewControllern (und wir haben den Schatten im ersten versteckt). Jetzt nur für den 3. viewController, ich möchte den Schatten NICHT verbergen. Also werde ich diese Methode mit FALSE in viewWillAppear und mit TRUE in viewWillDisappear von 3rd viewController aufrufen. Das ist alles, was es braucht!
Gaurav Chandarana

Ihr absolut korrektes, gutes Denken! Denken Sie nicht, dass ich Ihre Antwort geklopft habe, weil sie sehr prägnant und effizient ist. Ich habe sie auch hochgestimmt. Ich benutze es, um es und die navBar für Fehlermeldungen zu entfernen. Das Problem, das ich fand, war, als ich es in vc1 entfernte, aber vc2 anzeigte. Wenn jedoch ein Fehler in vc2 auftrat, funktionierte das Entfernen in viewWillDisappear möglicherweise nicht. Aber es ist wieder eine sehr einzigartige Situation. Ich mag die viewWillDisappear-Idee für den allgemeinen Fall und Sie sollten sie Ihrer Antwort hinzufügen. Unabhängig davon, ob Ihr Code funktioniert und es ist eine einfache Möglichkeit, den Schatten zu entfernen! 👍🏿👍🏿
Lance Samaria

Klappt wunderbar. Wollten Sie nur sicherstellen, dass dies keine privaten Einstellungen sind?
Inokey

2
Dies ist eine ausgezeichnete Antwort! Ich habe eine Antwort hinzugefügt, die den Code rationalisiert.
Scott Gardner

13

Vor barStyledem .BlackEinstellen des Farbtons auf einstellen:

self.navigationController?.navigationBar.translucent = false
self.navigationController?.navigationBar.barStyle = .Black
self.navigationController?.navigationBar.barTintColor = UIColor.blueColor()

Ist es zufällig, dass dies tatsächlich funktioniert? oder überdenke ich
Joe

@ Joe gut es funktioniert hier :-) funktioniert es nicht für dich?
GPBL

Das ist die Sache, es funktioniert. Ich frage mich nur, ob es eine Erklärung dafür gibt, warum der BarStyle in Schwarz umgewandelt wird und dann die gesamte BarTintColor in Blau umgewandelt wird :)
Joe

Vielleicht setzt es auf schwarz und undurchsichtig, es schaltet einige Ebenen / Ansicht in der Navigationsleiste aus ...
GPBL

Ich habe versucht, dies zu verwenden, und es entfernt die unterste Zeile, aber wenn ein Balken Weiß verwendet wird, ist der Titel nicht sichtbar: /
RileyDev

11

Swift 5

Wenn Sie setBackgroundImage / shadowImage verwenden, um den Haaransatz auszublenden, tritt eine leichte Verzögerung auf. Diese Methode beseitigt die Verzögerung. Gutschrift an Chameleon Framework . Dies ist die Methode, die sie verwenden (in ObjC)


extension UINavigationController {
    func hideHairline() {
        if let hairline = findHairlineImageViewUnder(navigationBar) {
            hairline.isHidden = true
        }
    }
    func restoreHairline() {
        if let hairline = findHairlineImageViewUnder(navigationBar) {
            hairline.isHidden = false
        }
    }
    func findHairlineImageViewUnder(_ view: UIView) -> UIImageView? {
        if view is UIImageView && view.bounds.size.height <= 1.0 {
            return view as? UIImageView
        }
        for subview in view.subviews {
            if let imageView = self.findHairlineImageViewUnder(subview) {
                return imageView
            }
        }
        return nil
    }
}

1
FWIW, dies ist die einzige Lösung, die unter iOS 13.4 für mich funktioniert hat ...
Kevinstueber

9

Die Antwort von Luca Davanzo ist großartig, aber sie funktioniert nicht in iOS 10. Ich habe sie so geändert, dass sie in iOS 10 und darunter funktioniert.

for parent in navigationController!.view.subviews {
    for child in parent.subviews {
        for view in child.subviews { 
            if view is UIImageView && view.frame.height == 0.5 {
                view.alpha = 0
            }
        }
    }
}

Sie können auch UINavigationController erweitern und dies abrufen. removeFromSuperview()on the line funktioniert unter iOS 10 nicht, daher habe ich das Alpha einfach auf 0 gesetzt, damit dieser eine Anruf überall kompatibel ist.


Netter Fang, gibt es eine Möglichkeit, den Schatten in einigen viewControllern während der Navigation ein- oder auszublenden?
Ashkan.H

Sie sollten lieber nach Höhen suchen, die eine haben height >= 1.0. Bei iPhone-Modellen mit 3x Retina-Bildschirm (z. B. 8 Plus, XR ...) hat der Haaransatz eine Höhe von 0,33.
fl034

7

Verwenden Sie zum Entfernen des Rahmens aus der UINavigationBar in Swift 3+:

UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
UINavigationBar.appearance().isTranslucent = false

5

für schnell 3

in viewDidLoadMethode

navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()


4

Aktualisiert für Swift 4, falls sich jemand wundert

navigationBar.shadowImage = UIImage()
navigationBar.backIndicatorImage = UIImage()

Es ist jetzt noch weniger ausführlich.


2

Dies ist der Weg, wenn Sie dies tun möchten, ohne die Hintergrundfarbe zu ändern:

// Remove the border ImageView from the NavigationBar background
func hideBottomBorder() {
    for view in navigationBar.subviews.filter({ NSStringFromClass($0.dynamicType) == "_UINavigationBarBackground" }) as [UIView] {
        if let imageView = view.subviews.filter({ $0 is UIImageView }).first as? UIImageView {
            imageView.removeFromSuperview()
        }
    }
}

HINWEIS: Dies kann in einer Produktions-App abstürzen. Anscheinend mag die Navigationsleiste nicht, dass ihre Ansicht verschwindet


2

Die akzeptierte Antwort funktionierte für mich, aber ich bemerkte, dass in der Navigationsleiste ein deutliches Blinken zu sehen war, als ich wollte, dass das Schattenbild beim Zurückspringen oder Vorwärtsschieben zu einem anderen VC wieder angezeigt wird.

Bei Verwendung dieser Methode navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") in viewWillAppear wird die Schattenleiste im aktuellen Controller für sichtbare Ansichten ausgeblendet.

Mit diesen beiden Methoden

navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
navigationController?.navigationBar.setValue(false, forKey: "hidesShadow")

In viewWillDisappear tritt das Blinken immer noch auf, jedoch nur, wenn das Schattenbild erneut angezeigt wird und nicht die Navigationsleiste selbst.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // 1. hide the shadow image in the current view controller you want it hidden in
    navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
    navigationController?.navigationBar.layoutIfNeeded()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)

    // 2. show the shadow image when pushing or popping in the next view controller. Only the shadow image will blink
    navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
    navigationController?.navigationBar.setValue(false, forKey: "hidesShadow")
    navigationController?.navigationBar.layoutIfNeeded()
}

1

für den swift3 solltest du etwas anders schreiben:

 self.navigationController?.navigationBar.setBackgroundImage(UIImage(),
    for: UIBarMetrics.default)
   self.navigationController?.navigationBar.shadowImage = UIImage()

1

Dies ist eine optimierte Version von Gaurav Chandaranas Antwort.

extension UINavigationBar {

    func hideShadow(_ value: Bool = true) {
        setValue(value, forKey: "hidesShadow")
    }
}

1

App-Delegat

UINavigationBar.appearance().setBackgroundImage(UIImage(), for: UIBarMetrics.default)
UINavigationBar.appearance().shadowImage = UIImage()

1

Wenn Sie nur die unterste Zeile entfernen und die Volltonfarbe der Navigationsleiste beibehalten möchten, fügen Sie diese Codezeilen in viewDidLoad: Swift 3, 4: hinzu.

navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = false

Frieden!


0

Die Grenzlinie ist eine UIImageView. Wenn Sie eine Unteransicht entfernen, bei der es sich um eine Bildansicht handelt, werden barButtonItems mit UIImageView entfernt. Der folgende Code hilft Ihnen beim Entfernen. Hoffe, das hilft jemandem, der mit einem Problem wie mir konfrontiert war.

for parent in self.navigationController!.navigationBar.subviews {
        for childView in parent.subviews {
            if childView.frame.height == 0.5 {
                childView.removeFromSuperview()
            }
        }
    }

Der Rand UIImageView hat nur eine Höhe von 0,5, sodass dieser Code nur diesen entfernt.


Dies verursachte Abstürze für mich. Ich denke, Eltern- und Kinderansichten müssen ausgepackt werden, falls sie gleich Null sind, bevor sie überprüft werden. Ich verwende jedoch einen benutzerdefinierten UINavigationController, sodass dies bei anderen Benutzern mit einer Standardleiste möglicherweise nicht der Fall ist.
Natalia

0

In AppDelegate hat dies das Format der NavBar global geändert und die untere Zeile / den Rand entfernt:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
    UINavigationBar.appearance().shadowImage = UIImage()
    UINavigationBar.appearance().tintColor = UIColor.whiteColor()
    UINavigationBar.appearance().barTintColor = UIColor.redColor()
    UINavigationBar.appearance().translucent = false
    UINavigationBar.appearance().clipsToBounds = false
    //UINavigationBar.appearance().backgroundColor = UIColor.redColor()
    UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : (UIFont(name: "FONT NAME", size: 18))!, NSForegroundColorAttributeName: UIColor.whiteColor()] }

Es ist mir nicht gelungen, auf einem bestimmten VC etwas anderes zu implementieren, aber dies wird 90% der Menschen helfen


UINavigationBar.appearance (). BackgroundColor = UIColor.redColor () wird nicht benötigt.
Sabiland

0

Dies ist die Antwort in schneller 3 Basis der Nate Cook Antwort

   self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    self.navigationController?.navigationBar.shadowImage = UIImage()

0

iOS 11 und Swift 4 Sie sollten versuchen, Folgendes zu befolgen, wenn Sie den Rand entfernen möchten, die Navigationsleiste jedoch nicht durchscheinend machen möchten
self.navigationBar.shadowImage = UIImage()


0

Fügen Sie in Ihrem benutzerdefinierten Navigationscontroller die folgenden Zeilen hinzu:

self.navigationBar.setBackgroundImage(UIImage(), for:.default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.layoutIfNeeded()

Wichtige Notiz

Die letzte Zeile ist wichtig, wenn Sie die viewDidLoad () -Methode in der ersten Zeile verwenden, da navigationController die Navigationsleiste neu zeichnen sollte. Sie können diese jedoch problemlos ohne layoutIfNeeded () in der viewWillAppear () -Methode verwenden, bevor die Navigationsleiste gezeichnet wird


0

Schnellere Methode von Jack Chen:

extension UINavigationController {

    var isHiddenHairline: Bool {
        get {
            guard let hairline = findHairlineImageViewUnder(navigationBar) else { return true }
            return hairline.isHidden
        }
        set {
            if let hairline = findHairlineImageViewUnder(navigationBar) {
                hairline.isHidden = newValue
            }
        }
    }

    private func findHairlineImageViewUnder(_ view: UIView) -> UIImageView? {
        if view is UIImageView && view.bounds.size.height <= 1.0 {
            return view as? UIImageView
        }

        for subview in view.subviews {
            if let imageView = self.findHairlineImageViewUnder(subview) {
                return imageView
            }
        }

        return nil
    }
}

Verwenden von:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.isHiddenHairline = true
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.isHiddenHairline = false
    }

0
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.