Search code examples
iosswiftuinavigationbaruinavigationitem

Swift Change Position of UIBarButtonItem in UINavigationBar


I am doing custom a navigation bar with items which y positions are lower than default. I tried many methods:

  • setBackButtonBackgroundVerticalPositionAdjustment:
  • set CGRectOffset of custom view
  • UIBarButtonItem.appearance().setTitlePositionAdjustment(UIOffset.init(horizontal: X, vertical: Y), forBarMetrics: UIBarMetrics.Default)

They made the items appeared in right positions, but I couldn't fire any actions when I clicked/touched on them. I think because I didn't touch the bar items, they were only the appearances/ copy views/images of these item.

enter image description here

Could anybody help me to resolve this problem?

My code:

let lblTitle = UILabel(frame: CGRectMake(0, 0, 100, 28))
            lblTitle.text = FMLStringLocale("APP_name")
            lblTitle.textColor = UIColor.whiteColor()
            lblTitle.font = ROBOTO_THIN_24
            lblTitle.textAlignment = NSTextAlignment.Left
            lblTitle.backgroundColor = UIColor.clearColor()
            lblTitle.transform = CGAffineTransformMakeTranslation(6, 11)

            let lblTitleContainer = UIView(frame: lblTitle.frame)
            lblTitleContainer.addSubview(lblTitle)
            let leftTitle = UIBarButtonItem(customView: lblTitleContainer)
            navigationItem.leftBarButtonItem = leftTitle

            let rightView = UIView(frame: CGRectMake(0, 0, 134, 22))
            rightView.backgroundColor = UIColor.whiteColor()
            rightView.transform = CGAffineTransformMakeTranslation(0, 18)

            let imvUSFlag = UIImageView(image: UIImage(named: "icon_us"))
            imvUSFlag.frame = CGRectMake(0, 0, 19, 13)
            imvUSFlag.transform = CGAffineTransformMakeTranslation(-2, 20)

            rightView.addSubview(imvUSFlag)

            let switcher = UISwitch(frame: CGRectMake(imvUSFlag.frame.maxX - 5, 12, 31, 16))
            switcher.setOn(false, animated: false)
            switcher.addTarget(self, action: Selector("tapToChangeLanguage:"), forControlEvents: UIControlEvents.ValueChanged)
            switcher.transform = CGAffineTransformMakeScale(0.5, 0.5)

//            let switchContainer = UIView(frame: switcher.frame)
//            switchContainer.addSubview(switcher)

            rightView.addSubview(switcher)

            let imvFRFlag = UIImageView(image: UIImage(named: "icon_france"))
            imvFRFlag.frame = CGRectMake(switcher.frame.maxX + 6, 0, 19, 14)
            imvFRFlag.transform = CGAffineTransformMakeTranslation(0, 20)

            rightView.addSubview(imvFRFlag)

            let btnMenu = UIButton()
            btnMenu.setImage(UIImage(named : "icon_menu"), forState: .Normal)
            btnMenu.frame = CGRectMake(imvFRFlag.frame.maxX + 30, 0, 23, 21)
            btnMenu.addTarget(self, action: "tapToMenu:", forControlEvents: UIControlEvents.TouchUpInside)
            btnMenu.transform = CGAffineTransformMakeTranslation(0, 18)

            rightView.addSubview(btnMenu)
            rightView.transform = CGAffineTransformMakeTranslation(0, 18)

            let rightViewItem = UIBarButtonItem(customView: rightView)

            navigationItem.rightBarButtonItem = rightViewItem

            navigationController?.navigationBar.barStyle = .BlackTranslucent
            navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
            navigationController?.navigationBar.shadowImage = UIImage()

Solution

  • The reason why you can't tap your button btnMenu is that you have positioned btnMenu outside the frame of its superview rightView. A subview outside its superview cannot receive touches.