Search code examples
iosswiftuinavigationitemuitapgesturerecognizertitleview

titleview dissapears when a subview is added?


This is new to me so forgive me if I'm not asking the right question.

I'm following a tutorial where we are creating a few subviews inside of a titleview for the navigation bar so that a picture and username displays. When I create the intial titleview with a red background, it shows up as expected. However, when I add a container subview to place the text and image, the red titleview disappears. I finished the tutorial and the text shows up in the right place, but it doesn't allow me to add a tap gesture, since the titleview isn't there anymore to tap?

I'll add my code for this function- hopefully there's a stupid mistake that I'm missing.

func setupNavBarWithUser(user: User) {

    let titleView = UIView()
    titleView.frame = CGRect(x: 0, y: 0, width: 130, height: 35)
    titleView.backgroundColor = UIColor.red

    let containerView = UIView()
    containerView.translatesAutoresizingMaskIntoConstraints = false
    containerView.backgroundColor = UIColor.blue
    titleView.addSubview(containerView)

    let profileImageView = UIImageView()
    profileImageView.translatesAutoresizingMaskIntoConstraints = false
    profileImageView.contentMode = .scaleAspectFill
    profileImageView.layer.cornerRadius = 20
    profileImageView.clipsToBounds = true

    if let profileImageUrl = user.profileImageUrl {
        profileImageView.loadImageUsingCacheWithUrlString(urlString: profileImageUrl)
    }

    containerView.addSubview(profileImageView)

    profileImageView.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
    profileImageView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
    profileImageView.widthAnchor.constraint(equalToConstant: 35).isActive = true
    profileImageView.heightAnchor.constraint(equalToConstant: 35).isActive = true

    let nameLabel = UILabel()


    containerView.addSubview(nameLabel)

    nameLabel.text = user.name
    nameLabel.translatesAutoresizingMaskIntoConstraints = false

    nameLabel.leftAnchor.constraint(equalTo: profileImageView.rightAnchor, constant: 8).isActive = true
    nameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
    nameLabel.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
    nameLabel.heightAnchor.constraint(equalToConstant: 40).isActive = true

    containerView.centerXAnchor.constraint(equalTo: titleView.centerXAnchor).isActive = true
    containerView.centerYAnchor.constraint(equalTo: titleView.centerYAnchor).isActive = true

    self.navigationItem.titleView = titleView

    titleView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(showChatController)))
    titleView.isUserInteractionEnabled = true

}

Solution

  • Replace setupNavBarWithUser method with this:

    func setupNavBarWithUser(user: User) {
    
            let titleView = UIView()
            titleView.frame = CGRect(x: 0, y: 0, width: 130, height: 45)
            titleView.backgroundColor = UIColor.red
    
            let containerView = UIView()
            containerView.translatesAutoresizingMaskIntoConstraints = false
            containerView.backgroundColor = UIColor.blue
            self.navigationItem.titleView = titleView
    
            titleView.addSubview(containerView)
    
            containerView.topAnchor.constraint(equalTo: titleView.topAnchor, constant: 0).isActive = true
            containerView.bottomAnchor.constraint(equalTo: titleView.bottomAnchor, constant: 0).isActive = true
            containerView.leadingAnchor.constraint(equalTo: titleView.leadingAnchor, constant: 0).isActive = true
            containerView.trailingAnchor.constraint(equalTo: titleView.trailingAnchor, constant: 0).isActive = true
    
            let profileImageView = UIImageView()
            profileImageView.translatesAutoresizingMaskIntoConstraints = false
            profileImageView.contentMode = .scaleAspectFill
            profileImageView.layer.cornerRadius = 20
            profileImageView.clipsToBounds = true
    
            if let profileImageUrl = user.profileImageUrl {
                profileImageView.loadImageUsingCacheWithUrlString(urlString: profileImageUrl)
            }
    
            containerView.addSubview(profileImageView)
    
            profileImageView.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
            profileImageView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
            profileImageView.widthAnchor.constraint(equalToConstant: 35).isActive = true
            profileImageView.heightAnchor.constraint(equalToConstant: 35).isActive = true
    
            let nameLabel = UILabel()
    
            containerView.addSubview(nameLabel)
    
            nameLabel.text = user.name
            nameLabel.translatesAutoresizingMaskIntoConstraints = false
    
            nameLabel.leftAnchor.constraint(equalTo: profileImageView.rightAnchor, constant: 8).isActive = true
            nameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
            nameLabel.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
            nameLabel.heightAnchor.constraint(equalToConstant: 40).isActive = true
    
    
            self.navigationItem.titleView = titleView
    
            titleView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(showChatController)))
            titleView.isUserInteractionEnabled = true
    
        }
    

    You can compare the codes. As you can see you have to add subview in a proper order to set your constraints.