58

Until now I still can't figure how to switch multiple views in one view controller. My storyboard is like this one.

enter image description here

Right now I want to embed two views inside my view controller.

enter image description here

My code for segmented control to switch two views in one view controller so far.

import UIKit

class PopularHistoryViewController: UIViewController {

    @IBOutlet weak var segmentedControl: UISegmentedControl!

    @IBAction func indexChanged(sender: UISegmentedControl) {
        switch segmentedControl.selectedSegmentIndex
        {
        case 0:
            NSLog("Popular selected")
            //show popular view
        case 1:
            NSLog("History selected")
            //show history view
        default:
            break; 
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }


}

Another thing, If I put two views inside my controller, what is best practice to differentiate it?

7 Answers 7

55

If you want to do UI layout in Xcode for the two overlapping subviews, a better solution is to use two UIContainerViewController, and use the same way of setting the hidden property as suggested in the above answer.

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

@IBAction func segmentSelectedAction(sender: AnyObject) { switch sender.selectedSegmentIndex { case 0 : firstContainer.hidden = false secodeContainer.hidden = true case 1: firstContainer.hidden = true secodeContainer.hidden = false default: break; } }
Question: how do you link the container view to 2 view controller? I have 1 container view and 2 table view I would like it to link to. I somehow can only link to 1 table view in storyboard.
What's the difference between this approach and the accepted answer?
@vichhai. I used this solution in my case. But, I have unresponsive navigation bar button items in my child controllers. stackoverflow.com/questions/40101381/…
This should be the answer
49

You can use the isHidden property of the UIView to show/hide your required views. First you have to link both views to IBOutlets through the Interface builder

@IBOutlet weak var historyView: UIView!
@IBOutlet weak var popularView: UIView!

@IBAction func indexChanged(_ sender: UISegmentedControl) {
    switch segmentedControl.selectedSegmentIndex {
    case 0:
        historyView.isHidden = true
        popularView.isHidden = false
    case 1:
        historyView.isHidden = false
        popularView.isHidden = true
    default:
        break;
    }
}

Note: it was named hidden in Swift 1 and 2.

2 Comments

Hey, How do you physically do that in the storyboard? how do you put historyView ON PopularView?
need to add break on every case end
6

First of all create two outlets and connect hose to the views in your ViewController.

@IBOutlet weak var firstView: UIView!
@IBOutlet weak var secondView: UIView!

And Change the code like:

@IBAction func indexChanged(sender: UISegmentedControl)
{
    switch segmentedControl.selectedSegmentIndex
    {
    case 0:
        firstView.hidden = false
        secondView.hidden = true
    case 1:
        firstView.hidden = true
        secondView.hidden = false
    default:
        break; 
    }
}

If you don't want to create Outlets, assign the views individual tags (Say 101 and 102) and you can do it like:

@IBAction func indexChanged(sender: UISegmentedControl)
{
    switch segmentedControl.selectedSegmentIndex
    {
    case 0:
        self.view.viewWithTag(101)?.hidden = false
        self.view.viewWithTag(102)?.hidden = true
    case 1:
        self.view.viewWithTag(101)?.hidden = true
        self.view.viewWithTag(102)?.hidden = false
    default:
        break; 
    }
}

Comments

1

Add both views to the view controller in the story board and set one of them to be hidden = yes or alpha = 0. When your index changed function gets called set the current view on screen to hidden = yes/alpha of 0 and set the previously hidden view to hidden = no/alpha = 1. This should achieve what you want.

Comments

0

If it is a simple view, not a part of the screen, you can indeed use isHidden property of two subviews of your view controller view. But I don't like this approach because it's hard to understand latter what is going on with your nib when all of the subviews are in one pile. I would add and remove those two views as child view controllers programmatically. It's the cleanest way there is, in my opinion. But even if you decided to go with just views, don't put them directly on view controller's view. Use nibs, preferably with owner class. And in many cases consider adding and constraint them programmatically. It's more code, but also cleaner and conserves resources.

Comments

0
@IBAction func acSegmentAction(_ sender: Any) {

    switch acSegmentedControl.selectedSegmentIndex {
        case 0:
           // print("addressview selected")
            addressView.isHidden = false
            contactProviderView.isHidden = true
        case 1:
            //print("contact provider selected")
            addressView.isHidden = true
            contactProviderView.isHidden = false
        default:
            break;
    }
}

Comments

-1

So what is written above does not work for me, so I figured out myself in Xcode 11 with Swift 5. (view1 = historyView, view2 = popularView)

@IBOutlet weak var view1: UITableView!
@IBOutlet weak var view2: UITableView!

@IBAction func segmentedControlChanged(_ sender: Any) {

    func showView1() {
        view1.isHidden = false
        view2.isHidden = true
    }

    func showView2() {
        view1.isHidden = true
        view2.isHidden = false
    }

    guard let segmentedControl = sender as?
        UISegmentedControl else { return }
    if segmentedControl.selectedSegmentIndex == 0 {
        showView1()

    }
        else {
            showView2()
        }
    }

Maybe this helps anyone.

1 Comment

How did you write methods inside the method? :o

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.