Terry B
Terry B

Reputation: 266

Extend tap area of UIBarButton Item to edge of screen

I have set up a custom UIBarButton that I would like to extend out to the edge of the screen, and I can't get it to happen.

I would like to extend the tappable area to the left edge of the screen if possible.

My code looks like this for the button:

    btn1.setImage(UIImage(named: "Back Arrow"), for: .normal)
    btn1.frame = CGRect(x: -100, y: 0, width: 150, height: 50)
    btn1.imageEdgeInsets.left = -100
    btn1.backgroundColor = UIColor.red
    btn1.clipsToBounds = false
    btn1.addTarget(self, action: #selector(self.segueToChooseScreen), for: .touchUpInside)
    let item1 = UIBarButtonItem(customView: btn1)
    self.navigationItem.setLeftBarButton(item1, animated: true)

I also tried to implement this, which works at first, but it goes away when I change the screen orientation:

    override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    // to remove navigation bar extra margin
    for view in (self.navigationController?.navigationBar.subviews)! {
        view.layoutMargins = UIEdgeInsets.zero
    }
}

My button still looks like this (in landscape mode for instance):

UIBarButtonItem

Is there a way I can extend it to the edge of the screen?

Thank you!

Upvotes: 1

Views: 652

Answers (1)

sweepez
sweepez

Reputation: 595

NOTE: You are accessing private api, and code may not work if structure of views or class names are changed. Also note I am making the change in viewDidAppear

LAST EDIT: PO wanted view at edge for both portrait/landscape. My actual recommendation would be to use a custom view behaving as a nav bar instead of the code below.

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
    myView.backgroundColor = .red
    navigationItem.leftBarButtonItem = UIBarButtonItem(customView: myView)
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let navController = navigationController {
        for subview in navController.navigationBar.subviews {
            if String(describing: subview).contains("ContentView") {

                if let guideToUpdate = subview.layoutGuides.first(where: { String(describing: $0).contains("LeadingBar") }),
                    let guideToUpdateOwningView = guideToUpdate.owningView {
                    guideToUpdate.leadingAnchor.constraint(equalTo: guideToUpdateOwningView.leadingAnchor).isActive = true

                }
            }
        }
    }
}

enter image description here

enter image description here

Upvotes: 1

Related Questions