budiDino
budiDino

Reputation: 13527

How to remove the line under the UISearchController on iOS 11?

How can I remove the line under the UISearchController on iOS 11?

I've added the UISearchController using this code:

navigationItem.searchController = searchController

but after doing that there is a weird line under it:

enter image description here

Any advice on how to remove the line or at least choose its color would be greatly appreciated.

Upvotes: 3

Views: 1247

Answers (4)

Giang
Giang

Reputation: 2729

in iOS11

@interface UISearchController (Additions)
- (void)hideHairLineView;
@end
@implementation UISearchController (Additions)
- (void)hideHairLineView{
    UIView *barBackgroundView = self.searchBar.superview.subviews.firstObject;
    for(UIView *v in barBackgroundView.subviews) {
        if ([v isKindOfClass:[UIImageView class]]) {
            UIImageView *imgView= (UIImageView *)v;
            if (imgView.frame.size.height <= 1.0) {
                [imgView setHidden:YES];
            }
        }
    }
}

In viewWillLayoutSubviews

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    [self.navigationItem.searchController hideHairLineView];
}

in iOS13

from viewDidLoad add [self.navigationController setDelegate:self];

#pragma mark - UINavigationControllerDelegate

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [viewController.navigationController.navigationBar.viewForLastBaselineLayout setBackgroundColor:[UIColor clearColor]];
}

Upvotes: 0

aji
aji

Reputation: 671

If you added it as a subview, you will found a glitch when press back or go forward to another page. This could improve your solution @budidino

let lineView = UIView(frame: .zero)
lineView.backgroundColor = .white
searchController.searchBar.addSubview(lineView)

lineView.translatesAutoresizingMaskIntoConstraints = false
lineView.leadingAnchor.constraint(equalTo: searchController.searchBar.leadingAnchor).isActive = true
lineView.trailingAnchor.constraint(equalTo: searchController.searchBar.trailingAnchor).isActive = true
lineView.bottomAnchor.constraint(equalTo: searchController.searchBar.bottomAnchor, constant: 1).isActive = true
lineView.heightAnchor.constraint(equalToConstant: 1).isActive = true

Upvotes: 0

Vin Gazoil
Vin Gazoil

Reputation: 2020

Here is another solution, a weak one but it could be useful in specific use-case.

extension UISearchController {

    var hairlineView: UIView? {
        guard let barBackgroundView = self.searchBar.superview?.subviews.filter({ String(describing: type(of: $0)) == "_UIBarBackground" }).first
        else { return nil }

        return barBackgroundView.subviews.filter({ $0.bounds.height == 1 / self.traitCollection.displayScale }).first
    }
}

With that extension, you only have to write the following code in the viewWillLayoutSubviews method of your view controller:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    // Remove hairline from the searchBar.
    self.navigationItem.searchController?.hairlineView?.isHidden = true
}

Important:

Please note that this solution is really weak and can break with future iOS updates.
Furthermore, $0.bounds.height == 1 / self.traitCollection.displayScale is unsafe and I advise you to use a proper float comparison method.

Upvotes: 5

budiDino
budiDino

Reputation: 13527

A hacky solution, but the best I have for now, is adding a white line view overlapping the dark line:

let lineView = UIView(frame: CGRect(x: 0, y: searchController.searchBar.frame.height-4, width: view.bounds.width, height: 1))
lineView.backgroundColor = .white
searchController.searchBar.addSubview(lineView)

Upvotes: 2

Related Questions