Làm cách nào để xóa đường viền của navigationBar trong swift?


131

Tôi đã cố gắng loại bỏ đường viền navigationBars mà không gặp may. Tôi đã nghiên cứu và mọi người dường như bảo phải đặt ShadowImage và BackgroundImage thành không, nhưng điều này không hoạt động trong trường hợp của tôi.

Mã của tôi

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

hình minh họa:

nhập mô tả hình ảnh ở đây

Câu trả lời:


309

Vấn đề là với hai dòng này:

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

Vì bạn không có hình ảnh không có tên, UIImage(named: "")trả về nil, có nghĩa là hành vi mặc định bắt đầu:

Khi không phải là số không, hình ảnh bóng tùy chỉnh sẽ hiển thị thay vì hình ảnh bóng mặc định. Để hiển thị bóng tùy chỉnh, hình nền tùy chỉnh cũng phải được đặt với -setBackgroundImage: forBarMetrics: (nếu sử dụng hình nền mặc định, hình ảnh bóng mặc định sẽ được sử dụng).

Bạn cần một hình ảnh thực sự trống, vì vậy chỉ cần khởi tạo với UIImage():

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

2
Câu trả lời này thực sự hoạt động. Bởi vì nếu sử dụng câu trả lời được chấp nhận (mã), thanh công cụ của nó sẽ loại bỏ hình ảnh.
Sergei Krasniuk

1
Đây phải là câu trả lời được chấp nhận. Cũng hoạt động khi cài đặt từ
UINavestionBar.appparent

1
Đây phải là câu trả lời được chấp nhận cho Swift 3. Câu trả lời được chấp nhận có hiệu quả với tôi trong Swift 2, nhưng không phải trong Swift 3
ColinMasters

1
cho swift3 bạn nên viết theo cách hơi khác nhau: self.navigationController .navigationBar.setBackgroundImage (UIImage (), cho: UIBarMetrics.default)? self.navigationController .navigationBar.shadowImage = UIImage ()
Chetan Dobariya

5
Phương pháp này mâu thuẫn với tiêu đề lớn trong iOS 11
SteffenK

54

Swift 4 & Swift 5

Xóa đường viền:

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

Khôi phục đường viền:

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

2
Câu trả lời hoàn hảo :)
PJR

Chúng ta có cần layout IfNeeded () ở đây không?
korgx9

1
Có korgx9, chúng tôi cần nó. Nếu không, nó sẽ không thay đổi màu sắc cho đến lần vẽ tiếp theo.
Sazzad Hissain Khan

37

điều này sẽ loại bỏ hình ảnh bóng hoàn toàn

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

1
Bạn có thể giải thích?
Kmeixner

1
Ngoài ra đối với tôi hoạt động giải pháp này, trong khi câu trả lời của @Nate Cook không hoạt động. : S
Luca Davanzo

2
Thần thánh !! Sau khi tìm kiếm, đây là điều DUY NHẤT đã hoạt động.
Tuấn Anh Vũ

nó hoạt động, nhưng tôi cũng có một biểu tượng menu trong thanh điều hướng và nó biến mất: / tôi chỉ muốn đường viền bị xóa. TRỢ GIÚP: /
Stephy Samaniego

Điều này làm việc cho tôi nhưng sau khi đẩy ViewContoder mới, nó sẽ xóa dòng từ đó sang. Làm thế nào tôi có thể ngăn chặn nó từ đó?
Anirudha Mahale

36

Với Swift 2 bạn có thể làm theo cách này:

Tập tin AppDelegate

Bên trong ứng dụng func (..., didFinishLaunchingWithOptions launchOptions: ...)

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

cho Swift 3:

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

Câu trả lời chính xác.
Ed.

Đây là câu trả lời toàn diện!
madeny

Tốt hơn là viết mặc định hữu ích như vậy tại Appdelegate hơn là viết chúng ở những nơi kỳ lạ. Câu trả lời đúng :)
Md Rais

35

Chỉ cần viết điều này trong phần mở rộng của UINavestionBar

extension UINavigationBar {

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

Và trong viewControll của bạn ...

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

Và để hoàn tác điều này cho bất kỳ viewContoder nào, chỉ cần truyền sai.


Điều này hoạt động rất tốt NHƯNG nó ẩn nếu cho TẤT CẢ vcs trên ngăn xếp điều hướng. Nếu bạn sử dụng nó trong vc1 và vc1 có thể đẩy lên vc2 thì nó cũng sẽ bị ẩn trên vc2. Để hiển thị bóng trong vc2, bạn sẽ phải đặt nó thành false trong viewDidLoad. Vấn đề là khi bạn bật lại vc1, nó sẽ hiển thị lại vì nó được đặt lại trong vc2. Bạn phải sử dụng logic để qua lại mà có thể không đáng. Tuy nhiên nếu bạn không muốn hình ảnh bóng tối hiển thị trên bất kỳ vcs ​​nào thì đây là cách dễ nhất để đi
Lance Samaria

Giả sử chúng ta có một chồng viewControllers với 5 viewControllers (Và chúng ta đã ẩn bóng trong cái đầu tiên). Bây giờ chỉ dành cho viewContaptor thứ 3, tôi không muốn che giấu bóng tối. Vì vậy, tôi sẽ gọi phương thức đó bằng FALSE trong viewWillAppear và với TRUE trong viewWillDisappear của view viewControll. Đó là tất cả!
Gaurav Chandarana

bạn hoàn toàn chính xác, suy nghĩ tốt! Đừng nghĩ rằng tôi đã gõ câu trả lời của bạn bởi vì nó rất ngắn gọn và hiệu quả, tôi cũng đã bình chọn nó. Tôi sử dụng nó để loại bỏ nó & navBar cho các thông báo lỗi. Vấn đề tôi tìm thấy là khi gỡ bỏ nó trong vc1 nhưng hiển thị nó là vc2 nhưng nếu có lỗi trong vc2 thì xóa nó trong viewWillDisappear có thể không hoạt động. Nhưng một lần nữa, đó là một tình huống rất độc đáo. Tôi thích ý tưởng viewWillDisappear cho trường hợp sử dụng chung và bạn nên thêm nó vào câu trả lời của mình. Bất kể mã của bạn hoạt động và đó là một cách dễ dàng để loại bỏ bóng! 👍🏿👍🏿
Lance Samaria

Hoạt động như một lá bùa. Chỉ muốn đảm bảo rằng đây không phải là cài đặt riêng tư?
inokey

2
Đây là một câu trả lời tuyệt vời! Tôi đã thêm một câu trả lời hợp lý hóa mã.
Scott Gardner

13

Đặt barStylethành .Blacktrước khi cài đặt màu:

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

Là nó ngẫu nhiên mà điều này thực sự hoạt động? hoặc tôi đang suy nghĩ quá mức?
joe

@joe tốt nó đang làm việc ở đây :-) nó không làm việc cho bạn?
gpbl

đó là điều, nó làm việc Tôi chỉ tự hỏi liệu có một lời giải thích nào về lý do tại sao biến thanhStyle thành màu đen sau đó biến toàn bộ thanhTintColor thành màu xanh không :)
joe

có thể đặt nó thành màu đen và mờ đục, nó sẽ tắt một số lớp / chế độ xem trong điều
hướngBar

Tôi đã thử sử dụng tính năng này và nó sẽ xóa dòng dưới cùng tuy nhiên nếu sử dụng thanh màu trắng thì tiêu đề không hiển thị: /
RileyDev

11

Swift 5

Khi sử dụng setBackgroundImage / ShadowImage để ẩn đường chân tóc, sẽ có một chút chậm trễ. Phương pháp này loại bỏ sự chậm trễ. Tín dụng cho Chameleon Framework . Đây là phương pháp họ sử dụng (trong 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, đây là giải pháp duy nhất phù hợp với tôi trên iOS 13.4 ...
kevinstueber

9

Câu trả lời của Luca Davanzo là tuyệt vời, nhưng nó không hoạt động trong iOS 10. Tôi đã thay đổi nó để hoạt động trong iOS 10 trở xuống.

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

Bạn cũng có thể mở rộng UINavestionControll và gọi nó ra khỏi đó. removeFromSuperview()trên đường dây sẽ không hoạt động trên iOS 10, vì vậy tôi chỉ đặt alpha thành 0 để cuộc gọi này tương thích ở mọi nơi.


Bắt tốt, có cách nào để hiển thị / ẩn bóng trong một số viewControllers trong khi điều hướng không?
Ashkan.H

Bạn nên kiểm tra độ cao có a height >= 1.0. Trên các mẫu iPhone có màn hình retina 3x (ví dụ 8 Plus, XR ...), đường chân tóc có chiều cao 0,33.
fl034

7

Để xóa đường viền khỏi UINavestionBar trong Swift 3+, hãy sử dụng:

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

5

cho nhanh 3

trong viewDidLoadphương pháp

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


4

Cập nhật cho Swift 4 trong trường hợp ai đó đang thắc mắc

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

Bây giờ thậm chí còn ít dài dòng hơn.


2

Đây là cách nếu bạn muốn làm mà không thay đổi màu nền:

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

LƯU Ý: Điều này có thể sụp đổ trên một ứng dụng sản xuất. Rõ ràng NavigationBar không giống như chế độ xem của nó biến mất


2

Câu trả lời được chấp nhận có tác dụng với tôi nhưng tôi nhận thấy khi tôi muốn hình ảnh bóng xuất hiện trở lại khi bật lại hoặc đẩy về phía trước một vc khác, có một nháy mắt đáng chú ý trong thanh điều hướng.

Sử dụng phương pháp này navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") trong viewWillAppear thanh bóng được ẩn trong bộ điều khiển xem hiển thị hiện tại.

Sử dụng 2 phương pháp này

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

trong viewWillDisappear, nháy mắt vẫn xảy ra nhưng chỉ khi hình ảnh bóng xuất hiện trở lại và không phải là thanh điều hướng.

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

Đối với swift3 bạn nên viết cách hơi khác:

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

1

Đây là phiên bản hợp lý của câu trả lời của Gaurav Chandarana .

extension UINavigationBar {

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

1

Đại biểu ứng dụng

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

1

Nếu bạn muốn chỉ xóa dòng dưới cùng và giữ nguyên màu của navigationBar, hãy thêm các dòng mã này vào viewDidLoad: Swift 3, 4:

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

Sự thanh bình!


0

Đường viền là UIImageView và xóa một khung nhìn phụ là imageView sẽ xóa barButtonItems bằng UIImageView. Mã dưới đây sẽ giúp bạn loại bỏ nó. Hy vọng điều này sẽ giúp một người phải đối mặt với một vấn đề như tôi.

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

Đường viền UIImageView chỉ có chiều cao 0,5 nên mã này chỉ loại bỏ điều đó.


Điều này gây ra tai nạn cho tôi. Tôi nghĩ rằng phụ huynh và trẻ em cần phải được mở khóa trong trường hợp chúng không có trước khi kiểm tra từng cái. Tôi đang sử dụng một UINavestionControll tùy chỉnh, vì vậy điều này có thể không xảy ra đối với những người dùng khác có thanh tiêu chuẩn.
Natalia

0

Trong AppDelegate , điều này đã thay đổi toàn cầu định dạng của NavBar và xóa dòng / đường viền dưới cùng:

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

Không quản lý để thực hiện bất cứ điều gì khác nhau trên một VC cụ thể, nhưng điều này sẽ giúp 90% mọi người


UINavulationBar.appparent (). BackgroundColor = UIColor.redColor () là không cần thiết.
Sontand

0

đây là câu trả lời trong 3 câu trả lời nhanh chóng của Nate Cook

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

0

iOS 11 và Swift 4 Bạn nên thử làm theo nếu bạn muốn xóa đường viền nhưng không làm cho navigitonbar mờ
self.navigationBar.shadowImage = UIImage()


0

trong điều hướng tùy chỉnh của bạn, thêm các dòng sau:

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

Lưu ý quan trọng

dòng cuối cùng rất quan trọng nếu bạn sử dụng phương thức viewDidLoad () dòng đầu tiên bởi vì navigationContoder nên vẽ lại thanh điều hướng nhưng bạn có thể dễ dàng sử dụng nó mà không cần layout IfNeeded () trong phương thức viewWillAppear () trước khi nó vẽ thanh điều hướng


0

Phương pháp nhanh hơn của 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
    }
}

Sử dụng:

    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()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.