신속하게 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

문제는 다음 두 줄에 있습니다.

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

1
이것은 받아 들여진 대답이어야합니다. UINavigationBar.appearance ()에서 설정하는 경우 또한 작동
Heinrisch

1
이것은 허용 대답은 스위프트 2에서 나를 위해 일한 스위프트 (3)에 대한 허용 대답 할 수 있지만 스위프트 3한다
ColinMasters

1
swift3의 경우 약간 다른 방식으로 작성해야합니다. self.navigationController? .navigationBar.setBackgroundImage (UIImage (), for : UIBarMetrics.default) self.navigationController? .navigationBar.shadowImage = UIImage ()
Chetan Dobariya

5
이 방법은 iOS 11의 큰 제목과 충돌합니다
SteffenK 2017 년

53

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 칸

37

이렇게하면 그림자 이미지가 모두 제거됩니다.

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

1
자세히 설명해 주시겠습니까?
Kmeixner 2015 년

1
또한 나를 위해이 솔루션을 작동하지만 @Nate Cook의 답변은 작동하지 않았습니다. : S
Luca Davanzo 2015 년

2
이런 sheist !! 모든 검색 후, 이것이 효과가 있었던 유일한 것입니다.
Tuan Anh Vu

작동하지만 내비게이션 바에 메뉴 아이콘이 있고 사라졌습니다 : / 테두리를 지우고 싶습니다. 도움말 : /
Stephy 사 마니 에고

이것은 나를 위해 일했지만 새로운 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에서 쓰는 것이 좋습니다. 정답 :
메릴랜드 라이스

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를 전달하십시오.


이것은 훌륭하게 작동하지만 탐색 스택의 모든 vcs에 대해 숨겨집니다. vc1에서 사용하고 vc1에서 vc2로 푸시 할 수 있으면 vc2에서도 숨겨집니다. vc2에서 그림자를 표시하려면 viewDidLoad에서 false로 설정해야합니다. 문제는 vc1로 돌아 가면 vc2에서 재설정 되었기 때문에 다시 표시된다는 것입니다. 가치가 없을 수도있는 논리를 사용하여 앞뒤로 이동해야합니다. 당신이 전혀 VCS에 게재 그림자 이미지를하지 않으 그러나 경우 다음이 갈 수있는 가장 쉬운 방법입니다
랜스 사마리아

5 개의 viewController가있는 viewController 스택이 있다고 가정 해 봅시다 (그리고 우리는 첫 번째 것에서 그림자를 숨겼습니다). 이제 세 번째 viewController에 대해서만 그림자를 숨기고 싶지 않습니다. 따라서 viewWillAppear에서 FALSE를 사용하고 세 번째 viewController의 viewWillDisappear에서 TRUE를 사용하여이 메서드를 호출합니다. 그게 전부입니다!
Gaurav Chandarana

당신의 절대적으로 정확하고 좋은 생각! 매우 간결하고 효율적이기 때문에 내가 당신의 대답을 두 드렸다고 생각하지 마십시오. 나는 그것을 제거하고 오류 메시지를 위해 navBar를 사용합니다. 내가 찾은 문제는 vc1에서 제거했지만 vc2를 표시 할 때 vc2에 오류가 있으면 viewWillDisappear에서 제거하면 작동하지 않을 수 있습니다. 그러나 이것은 매우 독특한 상황입니다. 일반적인 사례 사용에 대한 viewWillDisappear 아이디어가 마음에 들며 답변에 추가해야합니다. 코드가 작동하더라도 그림자를 제거하는 쉬운 방법입니다! 👍🏿👍🏿
Lance Samaria

매력처럼 작동합니다. 이것이 개인 설정이 아닌지 확인하고 싶습니까?
inokey

2
이것은 훌륭한 대답입니다! 코드를 간소화하는 답변을 추가했습니다.
Scott Gardner

13

색조를 설정 barStyle하기 .Black전에로 설정 :

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

이것이 실제로 작동하는 것이 다소 무작위입니까? 아니면 지나치게 생각하고 있습니까?
joe

@joe 잘 여기에서 일하고 있습니다 :-) 그것은 당신을 위해 작동하지 않습니까?
gpbl

그게 바로 작동합니다. 왜 barStyle을 검은 색으로 바꾸고 전체 barTintColor를 파란색으로 바꾸는 지에 대한 설명이 있는지 궁금합니다. :)
joe

검은 색과 불투명으로 설정하면 navigationBar에서 일부 레이어 /보기가 꺼집니다.
gpbl

나는 이것을 사용해 보았습니다. 그러나 그것은 흰색의 바 색조를 사용하면 제목이 보이지 않습니다 : /
RileyDev

11

스위프트 5

setBackgroundImage / shadowImage를 사용하여 헤어 라인을 숨기면 약간의 지연이 있습니다. 이 방법은 지연을 제거합니다. Chameleon Framework에 대한 크레딧 . 이것이 그들이 사용하는 방법입니다 (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에서는 작동하지 않습니다. iOS 10 이하에서 작동하도록 변경했습니다.

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()on the line은 iOS 10에서 작동하지 않으므로 알파를 0으로 설정하여이 통화가 모든 곳에서 호환됩니다.


탐색하는 동안 일부 viewController에서 그림자를 표시하거나 숨기는 방법이 있습니까?
Ashkan.H

차라리 height >= 1.0. 3x 레티 나 화면 (예 : 8 Plus, XR ...)이있는 iPhone 모델에서 헤어 라인의 높이는 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 를 하면 현재 보이는 뷰 컨트롤러에서 섀도우 바가 숨겨집니다.

이 두 가지 방법 사용

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

이것은 Gaurav Chandarana 의 대답을 간소화 한 버전입니다 .

extension UINavigationBar {

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

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에 불과하므로이 코드는이를 제거합니다.


이것은 나를 위해 충돌을 일으켰습니다. 나는 부모와 childViews가 각각을 확인하기 전에 nil 인 경우를 대비하여 풀어야한다고 생각합니다. 그래도 사용자 지정 UINavigationController를 사용하고 있으므로 표준 막대가있는 다른 사용자에게는 해당되지 않을 수 있습니다.
Natalia

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 ()가 필요하지 않습니다.
sabiland

0

이것은 Nate Cook 답변의 신속한 3 기반의 답변입니다.

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

0

iOS 11 및 Swift 4 테두리를 제거하고 싶지만 navigitonbar를 반투명하게 만들지 않으려면 다음을 시도해야합니다.
self.navigationBar.shadowImage = UIImage()


0

사용자 정의 navigationController에 다음 줄을 추가하십시오.

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

중요 사항

첫 번째 줄 viewDidLoad () 메서드를 사용하는 경우 마지막 줄이 중요합니다. navigationController는 탐색 모음을 다시 그려야하기 때문이지만 탐색 모음을 그리기 전에 viewWillAppear () 메서드에서 layoutIfNeeded ()없이 쉽게 사용할 수 있습니다.


0

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

사용 :

    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.