Removing Border Line between Navigation Bar & Section Header

So I am in a mildly complicated situation,

The issue: There is a thin blue line that goes across my Custom UITableViewSectionHeader only when under navigation bar that I do not know where is coming from:

I have:

  • A tableview nested inside a UIViewController

  • A GradientView (inherits UIView) directly under my NavigationBar

  • A TableView that overlaps my GradientView
  • A Custom TableViewSectionHeader Class (Subclass UITableViewCell)

[example of issue[1]

My theory:

That border line is either from: - The bottom border of navigation bar - The top border of tableview - Maybe a separator from the Section header (but seems unlikely) - A bottom border from the GradientView

mainstoryboard

Anybody have an idea what could be causing that line?

I have tried to remove it with: ViewController:

override func viewDidLoad() {
      //  self.tableview.separatorStyle = .none
    //    self.tableview.layer.borderWidth = 0
      //  self.view.layer.borderWidth = 0
}

GradientView:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.layer.borderWidth = 0
}

SectionHeader:

        self.separatorInset.left = 1000
        self.layer.borderWidth = 0

Any thoughts?

1 answer

  • answered 2018-01-11 21:18 Khalid Afridi

    Navigation bars has an image view with a line which is somewhere between less than or equals to 1px you have to loop through NavigationController navigationBar to find that imageView and set that to hidden.

    You can directly loop on navigationBar and find all subViews or if you want to have a reference to the view then here how I would have done it.

    var lineImageView: UIImageView? = { [unowned self] in
       // guard is great try to use it whenever you can 
        guard let navigationBar = self.navigationController?.navigationBar else {
            return nil
        }
    
        return self.findLineImageView(for: navigationBar)
    }()
    

    now add this function which loops through till it finds an imageView and return it back to our lineImageView

    // remember even **navigationBar** is a UI remember **UINavigationBar**
    func findLineImageView(for view: UIView) -> UIImageView? {
        // as I said above the line is not more than 1px so we look for a view which is less than or equals to 1px in height
        if view is UIImageView && view.bounds.size.height <= 1 {
            return (view as! UIImageView)
        }
        // we loop till we find the line image view and return it
        for subview in view.subviews {
            if let imageView = findLineImageView(for: subview) {
                return imageView
            }
        }
        // if there is no imageView with that height we return nil that's why we return an optional UIImageView
        return nil
    }
    

    Now the magic part. in viewWillApear set the lineImageView to hidden

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // remember as I said the lineImageView we returned an optional that's why it has question mark which means we are safe
        lineImageView?.isHidden = true
    }