Boundary Problem: Thin Line / Seperator Between Navigation Bar & Search Bar in iOS Swift

an image is worth a thousand word, please see the attached image. This is a mobile app that I am developing. There is visually that thin line between the navigation bar and search bar, but I have tried everything I can think of, as well as everything that ChatGPT suggested but I still can’t remove that line. Any out-of-the-box idea what I might be overlooking? How can I remove that thin line?

Edited: (Since some of you asked me of the codes, here they are, although as I said they are quite lengthy so I am not sure if that’s helpful…)

On AppDelegate (this method is called on each view controller under viewDidAppear):

extension UINavigationController{

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>func setupWhiteTintColor(){
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = UIColor(hex: "#4CAF50")
appearance.shadowColor = UIColor.clear
appearance.shadowImage = UIImage()
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,.font : UIFont.boldSystemFont(ofSize: 20)]
navigationBar.standardAppearance = appearance;
navigationBar.scrollEdgeAppearance = appearance;
navigationBar.compactAppearance = appearance;
navigationBar.tintColor = UIColor.white
navigationBar.setGradientBackground(colors: [UIColor(hex: "#388E3C"), UIColor(hex: "#4CAF50")], startPoint: .topLeft, endPoint: .bottomRight)
} else {
self.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,.font : UIFont.boldSystemFont(ofSize: 20)]
self.navigationBar.tintColor = UIColor.white
self.navigationBar.barTintColor = UIColor(hex: "#4CAF50")
self.navigationBar.isTranslucent = false
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
}
}
</code>
<code>func setupWhiteTintColor(){ if #available(iOS 13.0, *) { let appearance = UINavigationBarAppearance() appearance.configureWithDefaultBackground() appearance.backgroundColor = UIColor(hex: "#4CAF50") appearance.shadowColor = UIColor.clear appearance.shadowImage = UIImage() appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,.font : UIFont.boldSystemFont(ofSize: 20)] navigationBar.standardAppearance = appearance; navigationBar.scrollEdgeAppearance = appearance; navigationBar.compactAppearance = appearance; navigationBar.tintColor = UIColor.white navigationBar.setGradientBackground(colors: [UIColor(hex: "#388E3C"), UIColor(hex: "#4CAF50")], startPoint: .topLeft, endPoint: .bottomRight) } else { self.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,.font : UIFont.boldSystemFont(ofSize: 20)] self.navigationBar.tintColor = UIColor.white self.navigationBar.barTintColor = UIColor(hex: "#4CAF50") self.navigationBar.isTranslucent = false self.navigationBar.setBackgroundImage(UIImage(), for: .default) self.navigationBar.shadowImage = UIImage() } } </code>
func setupWhiteTintColor(){
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithDefaultBackground()
        appearance.backgroundColor = UIColor(hex: "#4CAF50")
        appearance.shadowColor = UIColor.clear
        appearance.shadowImage = UIImage()
        appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,.font : UIFont.boldSystemFont(ofSize: 20)]
        navigationBar.standardAppearance = appearance;
        navigationBar.scrollEdgeAppearance = appearance;
        navigationBar.compactAppearance = appearance;
        navigationBar.tintColor = UIColor.white
        navigationBar.setGradientBackground(colors: [UIColor(hex: "#388E3C"), UIColor(hex: "#4CAF50")], startPoint: .topLeft, endPoint: .bottomRight)
    } else {
        self.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,.font : UIFont.boldSystemFont(ofSize: 20)]
        self.navigationBar.tintColor = UIColor.white
        self.navigationBar.barTintColor = UIColor(hex: "#4CAF50")
        self.navigationBar.isTranslucent = false
        self.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationBar.shadowImage = UIImage()
    }
}

}

class UINavigationBarGradientView: UIView {

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>enum Point {
case topRight, topLeft
case bottomRight, bottomLeft
case custom(point: CGPoint)
var point: CGPoint {
switch self {
case .topRight: return CGPoint(x: 1, y: 0)
case .topLeft: return CGPoint(x: 0, y: 0)
case .bottomRight: return CGPoint(x: 1, y: 1)
case .bottomLeft: return CGPoint(x: 0, y: 1)
case .custom(let point): return point
}
}
}
private weak var gradientLayer: CAGradientLayer!
convenience init(colors: [UIColor], startPoint: Point = .topLeft,
endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
self.init(frame: .zero)
let gradientLayer = CAGradientLayer()
gradientLayer.frame = frame
layer.addSublayer(gradientLayer)
self.gradientLayer = gradientLayer
set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
backgroundColor = .clear
}
func set(colors: [UIColor], startPoint: Point = .topLeft,
endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
gradientLayer.colors = colors.map { $0.cgColor }
gradientLayer.startPoint = startPoint.point
gradientLayer.endPoint = endPoint.point
gradientLayer.locations = locations
}
func setupConstraints() {
guard let parentView = superview else { return }
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true
leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true
parentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
parentView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}
override func layoutSubviews() {
super.layoutSubviews()
guard let gradientLayer = gradientLayer else { return }
gradientLayer.frame = frame
superview?.addSubview(self)
}
</code>
<code>enum Point { case topRight, topLeft case bottomRight, bottomLeft case custom(point: CGPoint) var point: CGPoint { switch self { case .topRight: return CGPoint(x: 1, y: 0) case .topLeft: return CGPoint(x: 0, y: 0) case .bottomRight: return CGPoint(x: 1, y: 1) case .bottomLeft: return CGPoint(x: 0, y: 1) case .custom(let point): return point } } } private weak var gradientLayer: CAGradientLayer! convenience init(colors: [UIColor], startPoint: Point = .topLeft, endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) { self.init(frame: .zero) let gradientLayer = CAGradientLayer() gradientLayer.frame = frame layer.addSublayer(gradientLayer) self.gradientLayer = gradientLayer set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations) backgroundColor = .clear } func set(colors: [UIColor], startPoint: Point = .topLeft, endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) { gradientLayer.colors = colors.map { $0.cgColor } gradientLayer.startPoint = startPoint.point gradientLayer.endPoint = endPoint.point gradientLayer.locations = locations } func setupConstraints() { guard let parentView = superview else { return } translatesAutoresizingMaskIntoConstraints = false topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true parentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true parentView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true } override func layoutSubviews() { super.layoutSubviews() guard let gradientLayer = gradientLayer else { return } gradientLayer.frame = frame superview?.addSubview(self) } </code>
enum Point {
    case topRight, topLeft
    case bottomRight, bottomLeft
    case custom(point: CGPoint)

    var point: CGPoint {
        switch self {
            case .topRight: return CGPoint(x: 1, y: 0)
            case .topLeft: return CGPoint(x: 0, y: 0)
            case .bottomRight: return CGPoint(x: 1, y: 1)
            case .bottomLeft: return CGPoint(x: 0, y: 1)
            case .custom(let point): return point
        }
    }
}

private weak var gradientLayer: CAGradientLayer!

convenience init(colors: [UIColor], startPoint: Point = .topLeft,
                 endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
    self.init(frame: .zero)
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = frame
    layer.addSublayer(gradientLayer)
    self.gradientLayer = gradientLayer
    set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
    backgroundColor = .clear
}

func set(colors: [UIColor], startPoint: Point = .topLeft,
         endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
    gradientLayer.colors = colors.map { $0.cgColor }
    gradientLayer.startPoint = startPoint.point
    gradientLayer.endPoint = endPoint.point
    gradientLayer.locations = locations
}

func setupConstraints() {
    guard let parentView = superview else { return }
    translatesAutoresizingMaskIntoConstraints = false
    topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true
    leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true
    parentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    parentView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}

override func layoutSubviews() {
    super.layoutSubviews()
    guard let gradientLayer = gradientLayer else { return }
    gradientLayer.frame = frame
    superview?.addSubview(self)
}

}

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>extension UINavigationBar {
func setGradientBackground(colors: [UIColor],
startPoint: UINavigationBarGradientView.Point = .topLeft,
endPoint: UINavigationBarGradientView.Point = .bottomLeft,
locations: [NSNumber] = [0, 1]) {
guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else {
let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint,
endPoint: endPoint, locations: locations)
backgroundView.addSubview(gradientView)
gradientView.setupConstraints()
return
}
gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
}
}
extension UITabBar {
func setGradientBackground(colors: [UIColor],
startPoint: UINavigationBarGradientView.Point = .topLeft,
endPoint: UINavigationBarGradientView.Point = .bottomLeft,
locations: [NSNumber] = [0, 1]) {
guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else {
let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint,
endPoint: endPoint, locations: locations)
backgroundView.addSubview(gradientView)
gradientView.setupConstraints()
return
}
gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
}
}
</code>
<code>extension UINavigationBar { func setGradientBackground(colors: [UIColor], startPoint: UINavigationBarGradientView.Point = .topLeft, endPoint: UINavigationBarGradientView.Point = .bottomLeft, locations: [NSNumber] = [0, 1]) { guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return } guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else { let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations) backgroundView.addSubview(gradientView) gradientView.setupConstraints() return } gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations) } } extension UITabBar { func setGradientBackground(colors: [UIColor], startPoint: UINavigationBarGradientView.Point = .topLeft, endPoint: UINavigationBarGradientView.Point = .bottomLeft, locations: [NSNumber] = [0, 1]) { guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return } guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else { let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations) backgroundView.addSubview(gradientView) gradientView.setupConstraints() return } gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations) } } </code>
extension UINavigationBar {
    func setGradientBackground(colors: [UIColor],
                               startPoint: UINavigationBarGradientView.Point = .topLeft,
                               endPoint: UINavigationBarGradientView.Point = .bottomLeft,
                               locations: [NSNumber] = [0, 1]) {
        guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
        guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else {
            let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint,
                                                           endPoint: endPoint, locations: locations)
            backgroundView.addSubview(gradientView)
            gradientView.setupConstraints()
            return
        }
        gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
    }
}

extension UITabBar {
    func setGradientBackground(colors: [UIColor],
                               startPoint: UINavigationBarGradientView.Point = .topLeft,
                               endPoint: UINavigationBarGradientView.Point = .bottomLeft,
                               locations: [NSNumber] = [0, 1]) {
        guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
        guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else {
            let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint,
                                                           endPoint: endPoint, locations: locations)
            backgroundView.addSubview(gradientView)
            gradientView.setupConstraints()
            return
        }
        gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
    }
}

On each View Controller the following function is run:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>func setupNavigationBarTitleView() {
let imageView = UIImageView(image: UIImage(named: "TransparentToyzone"))
imageView.contentMode = .scaleAspectFit
// Set the height constraint to 30 pixels
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.heightAnchor.constraint(equalToConstant: 30)
])
// Set the image view as the title view of the navigation bar
self.navigationItem.titleView = imageView
}
</code>
<code>func setupNavigationBarTitleView() { let imageView = UIImageView(image: UIImage(named: "TransparentToyzone")) imageView.contentMode = .scaleAspectFit // Set the height constraint to 30 pixels imageView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ imageView.heightAnchor.constraint(equalToConstant: 30) ]) // Set the image view as the title view of the navigation bar self.navigationItem.titleView = imageView } </code>
func setupNavigationBarTitleView() {
    let imageView = UIImageView(image: UIImage(named: "TransparentToyzone"))
    imageView.contentMode = .scaleAspectFit
    
    // Set the height constraint to 30 pixels
    imageView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        imageView.heightAnchor.constraint(equalToConstant: 30)
    ])
    
    // Set the image view as the title view of the navigation bar
    self.navigationItem.titleView = imageView
}

1

You will need to set the bar’s appearance using an instance of UINavigationBarAppearance. Specifically, you will want to set the shadowColor attribute to nil or .clear.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>override func viewDidLoad() {
super.viewDidLoad()
let appearance = UINavigationBarAppearance()
appearance.shadowColor = .clear
navigationController?.navigationBar.scrollEdgeAppearance = appearance
}
</code>
<code>override func viewDidLoad() { super.viewDidLoad() let appearance = UINavigationBarAppearance() appearance.shadowColor = .clear navigationController?.navigationBar.scrollEdgeAppearance = appearance } </code>
override func viewDidLoad() {
  super.viewDidLoad()
  let appearance = UINavigationBarAppearance()
  appearance.shadowColor = .clear
  navigationController?.navigationBar.scrollEdgeAppearance = appearance
}

There are other appearance properties on UINavigationBar that may apply depending on location of the navigation bar on the screen.

If you want to set this automatically for all navigation bars, do this early in your app launch

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>let appearance = UINavigationBarAppearance()
appearance.shadowColor = .clear
UINavigationBar.appearance().scrollEdgeAppearance = appearance
</code>
<code>let appearance = UINavigationBarAppearance() appearance.shadowColor = .clear UINavigationBar.appearance().scrollEdgeAppearance = appearance </code>
let appearance = UINavigationBarAppearance()
appearance.shadowColor = .clear
UINavigationBar.appearance().scrollEdgeAppearance = appearance

3

It turns out that the visual border comes from search bar instead, and for some reasons setting searchbar.layer.borderWidth = 0 does not help. however, by setting searchbar.layer.borderWidth = 1 and then also set the borderColor to be the same color as navigation bar and search bar, the border effectively disappear.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật