NavigationBarの境界線をすばやく削除する方法は?


131

運が悪いので、navigationBarsの境界線を削除しようとしています。私は調査したところ、人々はshadowImageとBackgroundImageをnilに設定するように言っているようですが、これは私の場合には機能しません。

私のコード

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

図:

ここに画像の説明を入力してください

回答:


309

問題は次の2行です。

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

名前のない画像がないため、UIImage(named: "")が返されますnil。これは、デフォルトの動作が有効になることを意味します。

非nilの場合、デフォルトの影の画像の代わりに表示するカスタムの影の画像。カスタムシャドウを表示するには、-setBackgroundImage:forBarMetrics:を使用してカスタムバックグラウンドイメージも設定する必要があります(デフォルトのバックグラウンドイメージが使用されている場合は、デフォルトのシャドウイメージが使用されます)。

本当に空の画像が必要なので、次のように初期化するだけUIImage()です:

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

2
この答えは本当にうまくいきます。受け入れられた回答(コード)を使用する場合、そのツールバーのimageViewsを削除するためです。
Sergey Krasiuk、2016

1
これは受け入れられる答えになるはずです。UINavigationBar.appearance()から設定する場合にも機能します
Heinrisch

1
これはSwift 3の承認された回答であるはずです。承認された回答はSwift 2では機能しましたが、Swift 3では機能しませんでした
ColinMasters '26 / 09/26

1
swift3では、少し異なる方法で記述する必要があります。self.navigationController?.navigationBar.setBackgroundImage(UIImage()、for:UIBarMetrics.default)self.navigationBar.shadowImage = UIImage()
Chetan Dobariya

5
この方法は、iOS 11の大きなタイトルと競合します
SteffenK

54

Swift 4およびSwift 5

境界線を削除:

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

ボーダーの復元:

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

2
完璧な答え:)
PJR

ここにlayoutIfNeeded()が必要ですか?
korgx9

1
はい、korgx9が必要です。それ以外の場合は、次の描画まで色を変更しません。
Sazzad Hissain Khan

37

これで影の画像が完全に削除されます

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

1
詳しく説明してもらえますか?
Kmeixner

1
私にとってもこの解決策は機能しますが、@ Nate Cookの回答は機能しませんでした。:S
Luca Davanzo '19年

2
聖なる強盗!! すべての検索の後、これが機能した唯一のものです。
Tuan Anh Vu

それは動作しますが、ナビゲーションバーにメニューアイコンがあり、それが消えました:/境界線を消去したいだけです。ヘルプ:/
ステフィーサマニエゴ2016年

これは私にとってはうまくいきましたが、新しいViewControllerをプッシュした後、そこから行を削除します。それを防ぐにはどうすればよいですか?
Anirudha Mahale 2016

36

Swift 2では、次のように実行できます。

AppDelegateファイル

funcアプリケーションの内部(...、didFinishLaunchingWithOptions launchOptions:...)

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

Swift 3の場合:

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

正解。
Ed。

これが包括的な答えです!
Madeny

Appdelegateでこのような便利なデフォルトを作成する方が、奇妙な場所で作成するよりも優れています。正解:)
Md Rais

35

UINavigationBarの拡張にこれを書くだけです

extension UINavigationBar {

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

そしてあなたのviewControllerで...

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

そして、任意のviewControllerでこれを元に戻すには、falseを渡します。


これはうまく機能しますが、ナビゲーションスタック上のすべてのvcの場合は非表示になります。vc1で使用し、vc1がvc2にプッシュできる場合、vc2でも非表示になります。vc2でシャドウを表示するには、viewDidLoadでシャドウをfalseに設定する必要があります。問題は、vc1にポップバックすると、vc2でリセットされたため、再び表示されます。あなたはそれを価値がないかもしれない前後に行くためにロジックを使わなければなりません。ただし、すべてのvcsにシャドウイメージを表示したくない場合は、これが最も簡単な方法です
Lance Samaria

5つのviewControllersを持つviewControllersのスタックがあるとしましょう(そして最初の1つで影を隠しました)。ここで、3番目のviewControllerについてのみ、シャドウを非表示にしたくないので、3番目のviewControllerのviewWillAppearにFALSEを指定し、viewWillDisappearにTRUEを指定して、このメソッドを呼び出します。それだけです!
Gaurav Chandarana

あなたの絶対に正しい、良い考え!非常に簡潔で効率的であるため、私があなたの回答をノックしたとは思わないでください。私も投票しました。私はそれを使用してそれとエラーメッセージのnavBarを削除します。私が見つけた問題は、vc1で削除したときにvc2を表示したときでしたが、vc2でエラーが発生した場合、viewWillDisappearで削除しても機能しない可能性があります。しかし、これも非常にユニークな状況です。私は、viewWillDisappearのアイデアを一般的なケースで使用するのが好きなので、それを回答に追加する必要があります。コードが機能するかどうかに関係なく、それは影を取り除く簡単な方法です!👍🏿👍🏿–
ランスサマリア

魅力のように機能します。これがプライベート設定ではないことを確認したいだけですか?
inokey 2017年

2
これは素晴らしい答えです!コードを合理化する回答を追加しました。
スコットガードナー、

13

色合いを設定barStyleする.Black前にに設定します。

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

これが実際に機能するのはちょっとランダムですか?または私は考えすぎていますか?
joe '29

@joeよく動作します:-)動作しませんか?
gpbl 2015

それでうまくいきます。それはその後、青:)に全体barTintColorをオン黒にbarStyleを回す理由として説明があれば、私はただ思ったんだけど
ジョー・

多分それを黒と不透明に設定すると、navigationBarの一部のレイヤー/ビューがオフになります...
gpbl 2015

私はこれを使ってみましたが、それは一番下の行を削除しますが、白のバーティントを使用すると、タイトルが表示されません:/
RileyDev

11

スウィフト5

setBackgroundImage / shadowImageを使用して生え際を非表示にすると、若干の遅延が発生します。このメソッドは遅延を取り除きます。カメレオンフレームワークの功績。これは彼らが使用する方法です(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、これはiOS 13.4で私のために働いた唯一の解決策です...
kevinstueber

9

Luca Davanzoの答えは素晴らしいですが、iOS 10では動作しません。iOS10以下で動作するように変更しました。

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

UINavigationControllerを拡張して、これを呼び出すこともできます。removeFromSuperview()この回線ではiOS 10では機能しないため、アルファを0に設定するだけで、この1つの呼び出しはどこでも互換性があります。


良いキャッチ、ナビゲート中に一部のviewControllersで影を表示/非表示にする方法はありますか?
Ashkan.H 2017年

を持っている高さを確認する必要がありheight >= 1.0ます。網膜画面が3倍のiPhoneモデル(8 Plus、XRなど)では、ヘアラインの高さは0.33です。
fl034

7

Swift 3以降でUINavigationBarから境界線を削除するには、次のようにします。

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

5

迅速3

viewDidLoad方法

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


4

誰かが疑問に思っている場合に備えて、Swift 4用に更新されました

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

今はさらに冗長ではありません。


2

これは、背景色を変更せずに行う場合の方法です。

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

注:これは製品版アプリでクラッシュする可能性があります。どうやらNavigationBarはそのビューが消えるのが嫌いです


2

受け入れられた回答は私にとってはうまくいきましたが、別のvcにポップバックまたはプッシュしたときにシャドウイメージを再表示したいときに、ナビゲーションバーに目立つ点滅があったことに気付きました。

このメソッドnavigationController?.navigationBar.setValue(true, forKey: "hidesShadow") をviewWillAppearで使用すると、現在表示されているビューコントローラーでシャドウバーが非表示になります。

これら2つの方法を使用する

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

viewWillDisappearでも点滅は発生しますが、ナビゲーションバー自体ではなく影の画像が再表示された場合にのみ発生します。

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

swift3の場合、少し異なる方法で記述する必要があります。

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


1

アプリの委任

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

1

一番下の行だけを削除し、navigationBarの純色を維持したい場合は、viewDidLoadに次のコード行を追加します:Swift 3、4:

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

平和!


0

境界線はUIImageViewであり、imageViewであるサブビューを削除すると、UIImageViewでbarButtonItemsが削除されます。以下のコードは、それを削除するのに役立ちます。これが私のような問題に直面した人に役立つことを願っています。

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

ボーダーUIImageViewの高さはわずか0.5なので、このコードはそれだけを削除します。


これは私にクラッシュを引き起こしました。parentViewとchildViewsは、nilの場合に備えて、それぞれをチェックする前にアンラップする必要があると思います。ただし、カスタムUINavigationControllerを使用しているため、標準バーを使用する他のユーザーにはこれが当てはまらない場合があります。
ナタリア

0

AppDelegate内で、これによりNavBarのフォーマットがグローバルに変更され、一番下の行/境界線が削除されます。

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

特定のVCに何かを実装することはできませんでしたが、これは人々の90%を助けます


UINavigationBar.appearance()。backgroundColor = UIColor.redColor()は不要です。
サビランド

0

これはネイトクックの回答の迅速な3の答えです。

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

0

iOS 11とSwift 4境界線を削除したいが、ナビゲーションバーを半透明にしたくない場合は、以下を試してください。
self.navigationBar.shadowImage = UIImage()


0

カスタムのnavigationControllerに次の行を追加します。

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

重要な注意点

最初の行のviewDidLoad()メソッドを使用する場合、最後の行は重要です。これは、navigationControllerがナビゲーションバーを再描画する必要があるためです。ナビゲーションバーを描画する前に、viewWillAppear()メソッドでlayoutIfNeeded()を使用しなくても簡単に使用できます。


0

ジャックチェンのスウィフティ法:

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

使用:

    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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.