Bagaimana cara menghapus perbatasan bar navigasi dengan cepat?

131

Saya telah mencoba untuk menghapus perbatasan navigationBars tanpa hasil. Saya telah meneliti dan orang-orang tampaknya mengatakan untuk menyetel shadowImage dan BackgroundImage ke nihil, tetapi ini tidak berfungsi dalam kasus saya.

Kode saya

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

ilustrasi:

masukkan deskripsi gambar di sini

Peter Pik
sumber

Jawaban:

309

Masalahnya adalah dengan dua baris ini:

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

Karena Anda tidak memiliki gambar tanpa nama, UIImage(named: "")kembali nil, yang berarti perilaku default dimulai:

Jika tidak nihil, gambar bayangan kustom akan ditampilkan, bukan gambar bayangan default. Agar bayangan khusus ditampilkan, gambar latar belakang khusus juga harus disetel dengan -setBackgroundImage: forBarMetrics: (jika gambar latar default digunakan, gambar bayangan default akan digunakan).

Anda membutuhkan gambar yang benar-benar kosong, jadi lakukan inisialisasi dengan UIImage():

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
Nate Cook
sumber
2
Jawaban ini benar-benar berhasil. Karena jika menggunakan jawaban yang diterima (kode), itu menghapus imageView toolbar ke.
Sergey Krasiuk
1
Ini harus menjadi jawaban yang diterima. Juga berfungsi saat menyetel dari UINavigationBar.appearance ()
Heinrisch
1
Ini harus menjadi jawaban yang diterima untuk Swift 3. Jawaban yang diterima bekerja untuk saya di Swift 2, tetapi tidak di Swift 3
ColinMasters
1
untuk swift3 Anda harus menulis dengan cara yang sedikit berbeda: self.navigationController? .navigationBar.setBackgroundImage (UIImage (), untuk: UIBarMetrics.default) self.navigationController? .navigationBar.shadowImage = UIImage ()
Chetan Dobariya
5
Metode ini bertentangan dengan judul besar di iOS 11
SteffenK
53

Cepat 4 & Cepat 5

Menghapus perbatasan:

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

Mengembalikan perbatasan:

self.navigationController?.navigationBar.setBackgroundImage(nil, for:.default)
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.layoutIfNeeded()
Sazzad Hissain Khan
sumber
2
Jawaban sempurna :)
PJR
Apakah kita membutuhkan layoutIfNeeded () di sini?
korgx9
1
Ya korgx9, kami membutuhkannya. Jika tidak, warna tidak akan berubah sampai undian berikutnya.
Sazzad Hissain Khan
37

ini akan menghapus gambar bayangan sama sekali

for parent in self.navigationController!.navigationBar.subviews {
 for childView in parent.subviews {
     if(childView is UIImageView) {
         childView.removeFromSuperview()
     }
 }
}
Steve Payne
sumber
1
Bisakah Anda menjelaskannya?
Kmeixner
1
Juga bagi saya solusi ini berfungsi, sementara jawaban @Nate Cook tidak berfungsi. : S
Luca Davanzo
2
Astaga !! Setelah semua pencarian, ini adalah SATU-SATUNYA hal yang berhasil.
Tuan Anh Vu
itu berfungsi, tetapi saya juga memiliki ikon menu di bilah navigasi dan menghilang: / Saya hanya ingin batasnya dihapus. BANTUAN: /
Stephy Samaniego
Ini berhasil bagi saya, tetapi setelah mendorong ViewController baru, ia menghapus garis dari sana ke. Bagaimana saya bisa mencegahnya dari itu?
Anirudha Mahale
36

Dengan Swift 2, Anda dapat melakukannya dengan cara ini:

AppDelegate

Di dalam func application (..., didFinishLaunchingWithOptions launchOptions: ...)

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

untuk Swift 3:

UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
Jorge Casariego
sumber
Jawaban yang benar.
Ed.
Inilah jawaban lengkapnya!
madeny
Lebih baik menulis default berguna seperti itu di Appdelegate daripada menuliskannya di tempat-tempat ganjil. Jawaban Benar :)
Md Rais
35

Tulis saja ini di ekstensi UINavigationBar

extension UINavigationBar {

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

Dan di viewController Anda ...

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

Dan untuk membatalkan ini untuk viewController apa pun, cukup berikan false.

Gaurav Chandarana
sumber
Ini berfungsi dengan baik TAPI menyembunyikan jika untuk SEMUA vcs di tumpukan nav. Jika Anda menggunakannya di vc1 dan vc1 dapat mendorong ke vc2 maka itu akan disembunyikan di vc2 juga. Untuk menampilkan bayangan di vc2 Anda harus menyetelnya ke false di viewDidLoad. Masalahnya adalah ketika Anda kembali ke vc1, itu akan ditampilkan lagi karena disetel ulang di vc2. Anda harus menggunakan logika untuk bolak-balik yang mungkin tidak sepadan. Namun jika Anda tidak ingin gambar bayangan muncul di vcs apa pun, maka ini adalah cara termudah untuk pergi
Lance Samaria
Katakanlah kita memiliki tumpukan viewControllers dengan 5 viewControllers (Dan kita telah menyembunyikan bayangan di yang pertama). Sekarang untuk viewController ke-3 saja, saya TIDAK ingin menyembunyikan bayangan. Jadi, saya akan memanggil metode itu dengan FALSE di viewWillAppear dan dengan TRUE di viewWillDisappear dari viewController ke-3. Hanya itu yang diperlukan!
Gaurav Chandarana
pemikiran Anda yang benar-benar benar dan baik! Jangan berpikir saya mengetuk jawaban Anda karena sangat ringkas dan efisien, saya juga memilihnya. Saya menggunakannya untuk menghapusnya & navBar untuk pesan kesalahan. Masalah yang saya temukan adalah saat menghapusnya di vc1 tetapi menampilkannya vc2 tetapi jika ada kesalahan di vc2 maka menghapusnya di viewWillDisappear mungkin tidak berfungsi. Tetapi sekali lagi ini adalah situasi yang sangat unik. Saya suka ide viewWillDisappear untuk penggunaan kasus umum dan Anda harus menambahkannya ke jawaban Anda. Terlepas dari kode Anda berfungsi dan ini adalah cara mudah untuk menghapus bayangan! πŸ‘πŸΏπŸ‘πŸΏ
Lance Samaria
Bekerja seperti pesona. Hanya ingin memastikan ini bukan pengaturan pribadi?
inokey
2
Ini jawaban yang bagus! Saya telah menambahkan jawaban yang menyederhanakan kode.
Scott Gardner
13

Atur barStyleke .Blacksebelum mengatur warna:

self.navigationController?.navigationBar.translucent = false
self.navigationController?.navigationBar.barStyle = .Black
self.navigationController?.navigationBar.barTintColor = UIColor.blueColor()
gpbl
sumber
apakah ini benar-benar berfungsi secara acak? atau apakah saya terlalu banyak berpikir?
joe
@ Joe bekerja dengan baik di sini :-) apakah ini tidak bekerja untuk Anda?
gpbl
itu masalahnya, itu TIDAK berhasil. Saya hanya ingin tahu apakah ada penjelasan mengapa mengubah gaya menjadi hitam kemudian mengubah seluruh barTintColor menjadi biru :)
joe
mungkin mengaturnya menjadi hitam dan buram, itu mematikan beberapa lapisan / tampilan di navigationBar ...
gpbl
Saya mencoba menggunakan ini, dan itu menghapus intinya namun jika menggunakan warna bar putih judul tidak terlihat: /
RileyDev
11

Cepat 5

Saat menggunakan setBackgroundImage / shadowImage untuk menyembunyikan garis rambut, akan terjadi sedikit penundaan. Metode ini menghilangkan penundaan. Penghargaan untuk Chameleon Framework . Ini adalah metode yang mereka gunakan (di 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
    }
}
Jack Chen
sumber
1
FWIW, ini adalah satu-satunya solusi yang berhasil untuk saya di iOS 13.4 ...
kevinstueber
9

Jawaban Luca Davanzo bagus, tetapi tidak berfungsi di iOS 10. Saya mengubahnya agar berfungsi di iOS 10 dan yang lebih lama.

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
            }
        }
    }
}

Anda juga dapat memperluas UINavigationController dan membatalkannya. removeFromSuperview()di telepon tidak akan berfungsi di iOS 10, jadi saya hanya menyetel alpha ke 0 sehingga panggilan ini kompatibel di mana saja.

David Baez
sumber
Tangkapan bagus, cara apa saja untuk menampilkan / menyembunyikan bayangan di beberapa viewControllers saat menavigasi?
Ashkan.H
Anda sebaiknya memeriksa ketinggian yang memiliki a height >= 1.0. Pada model iPhone yang memiliki layar retina 3x (mis. 8 Plus, XR ...) garis rambut memiliki tinggi 0,33.
fl034
7

Untuk menghapus batas dari UINavigationBar di Swift 3+, gunakan:

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

untuk cepat 3

dalam viewDidLoadmetode

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

Hanya ini yang berhasil untuk saya,

self.navigationController?.navigationBar.shadowImage = UIImage()

Ref

Mohammad Zaid Pathan
sumber
4

Diperbarui untuk Swift 4 jika ada yang bertanya-tanya

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

Ini bahkan lebih tidak bertele-tele sekarang.

Mauricio Chirino
sumber
2

Inilah caranya jika Anda ingin melakukannya tanpa mengubah warna latar belakang:

// 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()
        }
    }
}

CATATAN: Ini mungkin macet pada aplikasi produksi. Rupanya NavigationBar tidak suka pandangannya menghilang

Yariv Nissim
sumber
2

Jawaban yang diterima bekerja untuk saya tetapi saya perhatikan ketika saya ingin gambar bayangan muncul kembali ketika muncul kembali atau mendorong maju ke vc lain, ada kedipan yang terlihat di bilah navigasi.

Menggunakan metode ini navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") di viewWillAppear bilah bayangan disembunyikan di pengontrol tampilan yang terlihat saat ini.

Menggunakan 2 metode ini

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

di viewWillDisappear kedipan masih terjadi tetapi hanya ketika gambar bayangan muncul kembali dan bukan bilah navigasi itu sendiri.

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()
}
Lance Samaria
sumber
1

untuk swift3 Anda harus menulis dengan cara yang sedikit berbeda:

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

Ini adalah versi sederhana dari jawaban Gaurav Chandarana .

extension UINavigationBar {

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

Delegasi aplikasi

UINavigationBar.appearance().setBackgroundImage(UIImage(), for: UIBarMetrics.default)
UINavigationBar.appearance().shadowImage = UIImage()
CSE 1994
sumber
1

Jika Anda hanya ingin menghapus garis bawah dan mempertahankan warna solid navigationBar, tambahkan baris kode berikut di viewDidLoad: Swift 3, 4:

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

Perdamaian!

Mihail Salari
sumber
0

Garis pembatas adalah UIImageView dan menghapus subview yang merupakan imageView akan menghapus barButtonItems dengan UIImageView. Kode di bawah ini akan membantu Anda menghapusnya. Semoga ini bisa membantu seseorang yang menghadapi masalah seperti saya.

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

Tinggi batas UIImageView hanya 0,5 jadi kode ini hanya menghapus itu.

bachman
sumber
Ini menyebabkan crash bagi saya. Saya rasa parent dan childView perlu dibuka jika tidak ada sebelum memeriksa masing-masing. Saya menggunakan UINavigationController kustom, jadi ini mungkin tidak terjadi pada pengguna lain dengan bilah standar.
Natalia
0

Dalam AppDelegate , ini telah mengubah format NavBar secara global dan menghapus garis bawah / batas:

 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()] }

Belum berhasil menerapkan sesuatu yang berbeda pada VC tertentu, tetapi ini akan membantu 90% orang

David West
sumber
UINavigationBar.appearance (). BackgroundColor = UIColor.redColor () tidak diperlukan.
sabiland
0

ini adalah jawaban dalam 3 basis cepat dari jawaban Nate Cook

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

iOS 11 dan Swift 4 Anda harus mencoba mengikuti jika Anda ingin menghapus perbatasan tetapi jangan membuat bilah navigasi tembus cahaya
self.navigationBar.shadowImage = UIImage()

BilalReffas
sumber
0

di navigationController kustom Anda, tambahkan baris berikut:

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

Catatan penting

baris terakhir penting jika Anda menggunakan metode baris pertama viewDidLoad () karena navigationController harus menggambar ulang bilah navigasi, tetapi dengan mudah Anda dapat menggunakan ini tanpa layoutIfNeeded () dalam metode viewWillAppear () sebelum menggambar bilah navigasi

Tuan Zee
sumber
0

Metode yang lebih licik dari 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
    }
}

Menggunakan:

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

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.isHiddenHairline = false
    }
Mickael Belhassen
sumber
0
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
GIJoeCodes
sumber