1

I have a UIBarButtonItem assigned to navigationItem.rightBarButtonItems, and I would like the user to be able to tap all the way over to the right edge and have it respond. The Apple Notes app does this. The area I would like to be able to receive touches is in green below.

I have tried a custom view with trailing constraints beyond the superview, and it shows the view in that area, but does not respond to touches there. I have also tried creating a button overriding point(inside:,with:) to look for touches in a larger frame, but that does not respond to touches in that area either.

enter image description here

2 Answers 2

2

I added the button in the following unsophisticated way to the navigationBar and pressing it works.

class ViewController2: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .blue
        navigationController?.navigationBar.backgroundColor = .red
        navigationItem.rightBarButtonItems = [UIBarButtonItem(image: .add, style: .done, target: nil, action: nil)]
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .green
        button.addTarget(self, action: #selector(buttonDidTap), for: .touchUpInside)
        guard let navigationController else { return }
        navigationController.navigationBar.addSubview(button)
        NSLayoutConstraint.activate([
            button.topAnchor.constraint(equalTo: navigationController.navigationBar.topAnchor),
            button.bottomAnchor.constraint(equalTo: navigationController.navigationBar.bottomAnchor),
            button.trailingAnchor.constraint(equalTo: navigationController.navigationBar.trailingAnchor),
            button.widthAnchor.constraint(equalToConstant: 10)
        ])
    }
    
    @objc func buttonDidTap() {
        print("TAP")
    }
}

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

That works! Thank you
I did run into some problems with this when navigating to another viewController and coming back. The solution is to call this from viewDidAppear, and first remove the button, then add it again. I'll post my solution in another answer.
I also ran into problems when rotating to landscape. I added a constant parameter to account for the safe area insets. See my answer.
0

This builds on @pogos answer, making sure you don't get errors when navigating to another viewController, which needs the same button. I remove the button, if it exists, before adding it. And do it in viewWillAppear instead of viewDidLoad. Also, must take into account the safeArea for the navigationBar, otherwise this doesn't work in landscape. I added the constant parameter to that constraint for that.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    configureNavigationBarButton()
}

private func configureNavigationBarButton() {
    guard let navigationController else { return }
    let tag = 1000
    navigationController.navigationBar.subviews.first(where: { $0.tag == tag })?.removeFromSuperview()
    let button = UIButton()
    button.tag = tag
    button.translatesAutoresizingMaskIntoConstraints = false
    navigationController.navigationBar.addSubview(button)
    NSLayoutConstraint.activate([
        button.topAnchor.constraint(equalTo: navigationController.navigationBar.topAnchor),
        button.bottomAnchor.constraint(equalTo: navigationController.navigationBar.bottomAnchor),
        button.trailingAnchor.constraint(equalTo: navigationController.navigationBar.trailingAnchor, constant: -navigationController.navigationBar.safeAreaInsets.right),
        button.widthAnchor.constraint(equalToConstant: 58)
    ])
    button.addTarget(self, action: #selector(openMenu), for: .touchUpInside)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.