Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What is going on with this article?
@KikurageChan

iOS11.0でUINavigationControllerのTitleViewのタッチイベントが呼ばれない現象について

More than 3 years have passed since last update.

はじめに

こんにちは :leaves:
UINavigationControllerにはTitleViewというプロパティがあります。
私はNavigationBarの中央に来るようTitleViewUIButtonを含む独自のカスタムViewをxibで作成して以下のように利用していました。

Group.png

iOS11.0以前ではこのボタンは押すことができ、問題なく動作するのですが、
以降ではTouchEventがどうやら反応しないようです。

※ コードでTitleViewを作成している場合、TitleViewの大きさを十分に取っていればiOS11.0でも以前と変わらずTouchEventは呼ばれます

group2.png

MainViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()
    let button = UIButton()
    button.setTitle("Button", for: .normal)
    button.frame.size = CGSize(width: 60, height: 30)
    button.addTarget(self, action: #selector(MainViewController.buttonAction), for: .touchUpInside)
    let titleView = UIView()
    titleView.backgroundColor = UIColor.cyan
    //十分な大きさを確保
    titleView.frame.size = CGSize(width: 120, height: 44)
    titleView.addSubview(button)
    button.frame.origin = CGPoint(x: titleView.frame.size.width * 0.5 - button.frame.size.width * 0.5,
                                  y: titleView.frame.size.height * 0.5 - button.frame.size.height * 0.5)
    self.navigationItem.titleView = titleView
}

解決方法

TitleViewにあてるカスタムViewのintrinsicContentSizeを設定すると
iOS11.0以前と同じくTouchEventが呼ばれるようです。

TopBarView.swift
override var intrinsicContentSize: CGSize {
    return CGSize(width: 134, height: 33)
}

試してみたこと

  • iOS11.0でisUserInteractionEnabledのデフォルト値が変わったのかと考え、 UINavigationBar等をtrueにしてみる
//デフォルトでtrueなので結果は ×
navigationItem.titleView?.isUserInteractionEnabled = true
//デフォルトでtrueなので結果は ×
navigationController?.navigationBar.isUserInteractionEnabled = true
  • UITapGestureRecognizerを設定してみる
//結果は ×
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MainViewController.topBarTap))
self.navigationItem.titleView?.addGestureRecognizer(tapGesture)

サンプルコード

一応サンプルのコードを書いておきます。
独自に作成したView(TopBarView)は別途xibファイルでも作成しています。

MainViewController.swift
import UIKit

class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.titleView = TopBarView.instantiate()
    }
}
TopBarView.swift
import UIKit

class TopBarView: UIView {

    @IBOutlet weak var button: UIButton!

    override func awakeFromNib() {
        button.setTitle("Button", for: .normal)
    }

    static func instantiate(withOwner ownerOrNil: Any? = nil) -> TopBarView {
        let nib = UINib(nibName: "TopBarView", bundle: nil)
        return nib.instantiate(withOwner: ownerOrNil, options: nil)[0] as! TopBarView
    }

    private override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override var intrinsicContentSize: CGSize {
        return CGSize(width: 134, height: 33)
    }

    @IBAction func buttonAction(_ sender: Any) {
        print("ボタンが押されました")
    }
}

さいごに

iOS11.0になりUINavigationControllerにLargeTitleが追加されたり、NavigationBarの高さ分がUIScrollViewなどで自動計算されたりと混乱してしまいますが、少しずつ慣れていけたらと思います。

参考にさせていただいた記事

見て頂いてありがとうございます。

15
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
KikurageChan
見て頂いてありがとうございます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
15
Help us understand the problem. What is going on with this article?