Search code examples
iosswiftuisegmentedcontrol

Load segmented views in ViewController but UISegmentControl is in UIView class


I have created a UIView class (SegmentControl.swift) and added the UISegmentControl using an xib. I have another viewcontroller where I refer this UIView class to add the segment control.

My question here is since I have the UISegmentControl in another UIView class, how will I update the index and load the respective containerViews in the ViewController?

@IBAction func didChangeIndex(_ sender: UISegmentedControl) { } will work only if I have Segment control in ViewController.

Please provide your suggestions on how can I load the containerviews when the UIControlSegment is in another class.

This is the code I have:

SegmentControl.swift

class SegmentControl: UIView {

  @IBOutlet weak var segmentView: UISegmentedControl!
  // Loading nibs are there.. just that I didn't include here

  func create(titles: [String]) {
       items.enumerated().forEach { (index, item) in
           segmentView.setTitle(item, forSegmentAt: index)
       }
   }   
}

ViewController.swift

func showSegmentControl() {
    let segmentedView = GenericSegmentedView.create(items: ["A", "B"])
    stackView.addArrangedSubView(segmentedView)
}

Two container views --> aInfoView and bInfoView are intialised in View Controller.

How will I load them on switching the segments since they are in UIView class. I couldnt find any answers here. Please help!

Thank you!!


Solution

  • You can add a target to the segmented control even if it's contained within another view. The segmented control is an accessible property on your SegmentControl class. From the SegmentControl's parent view controller add the target action to the your SegmentControl's child segmentView.

    func showSegmentControl() {
        let segmentedView = GenericSegmentedView.create(items: ["A", "B"])
        stackView.addArrangedSubView(segmentedView)
        segmentedView.segmentView.addTarget(self, action: #selector(segmentControlChanged(_:)), for: .valueChanged)
    }
    // Function will be called when value changed on the SegmentControl's segmentView
    @objc func segmentControlChanged(_ sender: UISegmentedControl) {
        print(sender.selectedSegmentIndex)
    }
    

    Something as aside, interchanging segmentControl and segmentView can be confusing to people not familiar with your code. Maybe a more descriptive name for the SegmentControl like SegmentControlContainer or something would help make the distinction.