Search code examples
iosswiftuisegmentedcontrol

IOS Segmented Control: Can't Change Selected Segment


I created a segmented control in my storyboard that looks like this:

enter image description here

Then I created an IBAction for when the control's value changes:

@IBAction func segmentValChanged(_ sender: UISegmentedControl) {
    print("touched")
    if (sender.selectedSegmentIndex == 0) {
        sender.selectedSegmentIndex = 1;
    }
    else{
        sender.selectedSegmentIndex = 0;
    }
}

The only issue is that this function is never called! When I click the Jokes (Beta) button, nothing happens.

However, when I created an IBOutlet for the control and tried to change the selected segment in my viewDidLoad(), it worked:

segmentedController.selectedSegmentIndex = 1

I know I probably missed something obvious, since I've never used a segmented control before. Thanks so much if anyone can point out what this is. Cheers!

import UIKit
import Alamofire

class ViewController: UIViewController {

    var currentImage: CurrentImage!

    var parameters: Parameters!

    @IBOutlet weak var segmentedController: UISegmentedControl!


    @IBAction func segmentValChanged(_ sender: UISegmentedControl) {
        print("touched")
        if (sender.selectedSegmentIndex == 0) { // switch to 1
            sender.selectedSegmentIndex = 1;
        }
        else{
            sender.selectedSegmentIndex = 0;
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        segmentedController.selectedSegmentIndex = 1
        self.segmentedController.addTarget(self, action: #selector(segmentValChanged(_:)), for: .valueChanged)
    }
}

And this is what it looks like when I right click the view: enter image description here


Solution

  • Whenever I see this it is almost always the same problem... If the segmented control is being drawn outside of its parent view, then it will not respond to taps. This is most likely the problem you are having. (This can also happen with UIButtons.)

    Ways to test if this is the problem:

    1. set clipsToBounds of the segmented control's parent to true. If the control no longer shows on the screen, then it is being drawn outside of it's parent view. segmentedControl.superview?.clipsToBounds = true

    2. add a border to the segmented control's parent. If the control is being drawn outside the border then there you go. segmentedControl.superview?.layer.borderWidth = 1

    Solve the problem by expanding the size of the parent view so the control is being drawn within it.


    On a side note, your IBAction is incorrect. When the value changed action is called, the segmented control will already have changed its value and the new segment will be highlighted. You don't have to do it manually. This is another indicator that your control isn't being drawn in the bounds of its parent view.