UISegmentedControl with UITableView example in Swift. Part 2.

In this video tutorial I am going to share with you how to create a UISegmentedControl with three tabs which will allow user to switch between three different list of elements: Private, Protected and Public. List of items displayed in each tab is loaded from a remote PHP script. I will include the source of PHP script below in this blog post.

If you would like to learn how to load list of items from a locally created(hard coded) array of elements, watch this video: UISegmentedControl with UITableView example in Swift. Part 1.

Source code of UIViewController:

import UIKit

class ViewController: UIViewController, UITableViewDataSource,UITableViewDelegate {

    @IBOutlet weak var mySegmentedControl: UISegmentedControl!
    @IBOutlet weak var myTableView: UITableView!
    @IBOutlet weak var myActivityIndicator: UIActivityIndicatorView!
    
    var privateList:[String] = []
    var friendsAndFamily:[String] = []
    var publicList:[String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
   
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        
       loadItems()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

  
    internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        var returnValue = 0
        
        switch(mySegmentedControl.selectedSegmentIndex)
        {
        case 0:
            returnValue = privateList.count
            break
        case 1:
            returnValue = friendsAndFamily.count
            break
            
        case 2:
            returnValue = publicList.count
            break
            
        default:
            break
            
        }
        
        return returnValue
        
    }
    
 
    internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let myCell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)
        
        switch(mySegmentedControl.selectedSegmentIndex)
        {
        case 0:
            myCell.textLabel!.text = privateList[indexPath.row]
            break
        case 1:
            myCell.textLabel!.text = friendsAndFamily[indexPath.row]
            break
            
        case 2:
            myCell.textLabel!.text = publicList[indexPath.row]
            break
            
        default:
            break
            
        }


        return myCell
    }
    
 

    @IBAction func refreshButtonTapped(sender: AnyObject) {
        loadItems()
    }
    
    @IBAction func segmentedControlActionChanged(sender: AnyObject) {
        switch(mySegmentedControl.selectedSegmentIndex)
        {
        case 0:
            
            if(privateList.count == 0)
            {
                loadItems()
            } else {
            
                 myTableView.reloadData()
             }
            break
            
        case 1:
            if(friendsAndFamily.count == 0)
            {
                loadItems()
            } else {
                myTableView.reloadData()
            }
            break
            
        case 2:
            if(publicList.count == 0)
            {
                loadItems()
            } else {
                myTableView.reloadData()
            }
            break
            
        default:
            break
            
        }
    }
   
    
    internal func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
    {
      return 0.0
    }
    
    
    func loadItems()
    {
        switch(mySegmentedControl.selectedSegmentIndex)
        {
        case 0:
      
            loadItemsNow("privateList")
            break
        case 1:
            loadItemsNow("protectedList")
            break
            
        case 2:
            loadItemsNow("publicList")
            break
            
        default:
            break
            
        }
  }

    func loadItemsNow(listType:String){
        myActivityIndicator.startAnimating()
    let listUrlString =  "http://swiftdeveloperblog.com/my-list-of-items?listType=" + listType + "&t=" + NSUUID().UUIDString
    let myUrl = NSURL(string: listUrlString);
    let request = NSMutableURLRequest(URL:myUrl!);
    request.HTTPMethod = "GET";
    
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
        
        if error != nil {
            print(error!.localizedDescription)
             dispatch_async(dispatch_get_main_queue(),{
               self.myActivityIndicator.stopAnimating()
             })

            return
        }
 
 
        do {
       
            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray
      
            if let parseJSON = json {
                
               if(listType == "privateList")
               {
                  self.privateList = parseJSON as! [String]
               } else if(listType == "protectedList")
               {
                  self.friendsAndFamily = parseJSON as! [String]
               } else {
                  self.publicList = parseJSON as! [String]
               }
 

            }
            
        } catch {
            print(error)
        
        }
        
        dispatch_async(dispatch_get_main_queue(),{
            self.myActivityIndicator.stopAnimating()
            self.myTableView.reloadData()
        })
        
        
    }
    
    task.resume()
 }

 
}

Source code of PHP script:

 
 header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
 header("Cache-Control: post-check=0, pre-check=0", false);
 header("Pragma: no-cache");

 
 if($_GET["listType"] == "privateList")
 {
  $private_list = array();
  $private_list[] = "Private item 1";
  $private_list[] = "Private item 3";
  echo json_encode($private_list);
  return;
 }  

 
 if($_GET["listType"] == "protectedList")
 {
  $protected_list = array();
  $protected_list[] = "Friend item 1";
  $protected_list[] = "Friend item 2";
  $protected_list[] = "Friend item 3";
  $protected_list[] = "Friend item 4";
  echo json_encode($protected_list);
  return;
 }
 
  
 if($_GET["listType"] == "publicList")
 {
 $public_list = array();
 $public_list[] = "Public item 1";
 $public_list[] = "Public item 2";
 $public_list[] = "Public item 3";
 $public_list[] = "Public item 4";
 $public_list[] = "Public item 5";
 echo json_encode($public_list);
 return; 
 } 
 
  • Fabio

    hello Sergey , the following code gives me this error , can you help me ? Best regards.

    • Hi Fabio! If you are not using Xcode 7 and Swift 2, then simply remove the “do {” and the “} catch { print(error) }” lines…. also you will need to remove the “try” in the line NSJSONSerialization.JSONObjectWithData….

      Please let me know if it helped.

      • Fabio

        Hi Sergey,
        i did as you told me, but now i get this error.
        I use XCODE 6.4 and SWIFT2.
        Thank you for the help.

        • Hi Fabio. I think I know what it is going on…. Please replace this line with this two lines:

          var err: NSError?

          var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary

          • Fabio

            Hi Sergey,
            it works !!!
            Best regards,

            Fabio

  • Riaz

    Hi Sergey,
    I just started to swift and I’m using a list of rows (with 3 columns: name, address, zipcode) from MySQL which I wanted to bring to UITableViewCell.

    PHP:

    So I get this
    [{“name”:”Albert”,”address”:”Phoenix”,”zip”:”12345″}, {“name”:”Robert”,”address”:”Paris”,”zip”:”12345″}]

    Do you mind, explain me how to bring this as dictionary and list in TableView? Really helpful 🙂

    • Sorry for delayed response. I am traveling this week and do not have access to the internet. Please have a look at this video tutorial. I execute mysql search and display JSON data returned in TableView. http://swiftdeveloperblog.com/case-insensitive-search-with-swift-php-and-mysql/

      • Riaz

        Thanks a lot.. It works great… Learning new things everyday. I subscribed to your YT channel and learning. Your videos are great and very helpful. Within a week I already started to build app. Thanks once again. ( :

        Also I watched your UIDatePicker to implement inline date but unable to figure it out. I have a TableView with UILabel of date and time for the user to enter the date and time and when the user tapped, I wanted to popup the DatePicker at the bottom of the screen.

        I tried searching your blog but unable to find it. Can you help on this please? Really appreciate.

        • Thank you for your message! I do not have a video on inline date picker and I think it would be very good to have one. I will try to find out some time to squeeze it in between of tasks I am currently working on. Stay tuned!

  • dancingbush

    Hi,

    I am geeting a exception thrown when trying to get array from the JSON :

    let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray;

    :App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.

    Cant see an option to change this in plist, i am using Xcode 7.

    Thanks

    PS Great tutorial, very clear and concise.

  • dancingbush

    actually just added this to info.plist:
    NSAppTransportSecurity

    NSAllowsArbitraryLoads

  • Karina

    Hello, if more items to your three lists and scroll down in the first one and then click on another segment , you will see that still in the same position as in the first list. I was supposed to start at zero cell in the second segment, be independent cells in the same table view, is that possible??? I can’t find the solution for this, do I have to use 3 tableviews to fix this issue?