Search code examples
iosswiftuilabelsubclassuisegmentedcontrol

UiSegmentedControl as part of UILabel Subclass


I am trying to create a custom label that subclasses UILabel and has a UISegmentedControl property. Essentially, I am trying to create a custom button.

The views and constraints are added to the parent view fine, but the UISegmentedControl is not responsive to touch. Below is a code snippet of how I am trying to use this. I have tried to enable isUserInteractionEnabled as a sanity check, and nothing happens.

class CustomLabelWithSelector: CustomLabel {
    
    var selector: UISegmentedControl!
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override init(with title: String) {
        super.init(with: title)
        
        selector = UISegmentedControl(frame: .zero)
        selector.insertSegment(withTitle: "Off", at: 0, animated: true)
        selector.insertSegment(withTitle: "On", at: 1, animated: true)
        selector.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .normal)
        selector.selectedSegmentTintColor = .systemGray
        selector.backgroundColor = .tertiarySystemFill
        selector.selectedSegmentIndex = 0
        selector.translatesAutoresizingMaskIntoConstraints = false
        
        self.addSubview(selector)
        selectorConstraints()
    }
    
    private func selectorConstraints() {
        
        selector.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        selector.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -5).isActive = true
    }
}

class ViewController: UIViewController {
    var customLabelWithSelector: CustomLabelWithSelector!
    init() {
        self.setUpView()
    }

    func setupView() {
        customLabelWithSelector = CustomLabelWithSelector(with: "  Option")
        view.addSubview(customLabelWithSelector)
        // Label does not respond to touch, nor is the function called below
        customLabelWithSelector.selector.addTarget(self, action: #selector(selectOnOff(_:)), for: .valueChanged)
    }

    @objc func selectOnOff(_ segmentedControl: UISegmentedControl) {
            switch (segmentedControl.selectedSegmentIndex) {
              case 0:
                print("off selected")
                  break
              case 1:
                print("on selected")
                  break
              default:
                print("default")
                  break
          }
    } 
}

I have also subclassed my UISegmentedControl by itself and successfully added it as a subview to the parent UIView. It did respond to touch (switch from off to on) nor call the function.

Am I missing something? I may not understand the view hierarchy very well, but I have tried bringing the UISegmentedControl view to front as well and that also did not work.

Any suggestions on how to implement this?


Solution

  • You may need to

    self.isUserInteractionEnabled = true
    

    and set a frame for customLabelWithSelector

    customLabelWithSelector = CustomLabelWithSelector(with: "  Option")
    customLabelWithSelector.frame = //// set frame or constraints
    

    Btw you may need to use the segment directly without sub-classing label as it seems that you don't benefit from that