Search code examples
iosarraysswift3uitableviewuiswitch

How to change an array that is inserted on a TableCell from information I have in another ViewController?


I need your help! I don´t know how to change an array that is inserted on a TableCell from information I have in another ViewController. It’s a little bit messed up, but I’m gonna show you by my code.

Here I have a ViewController conformed by many switches that correspond to different categories of coupons, this is the code:

class FiltersViewController: UIViewController {

    @IBOutlet weak var restaurantsSwitch: UISwitch!

    @IBOutlet weak var sportsSwitch: UISwitch!



  override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func returnHome(_ sender: Any) {
        let vc = self.storyboard!.instantiateViewController(withIdentifier: "home") as! HomeViewController
        self.present(vc, animated: false, completion: nil)
    }


    @IBAction func restaurants(_ sender: UISwitch) {
        if restaurantsSwitch.isOn == true{
            tuxtlaSwitch.isOn = false
            sevillaSwitch.isOn = false
            coapaSwitch.isOn = false
            coyoacanSwitch.isOn = false
            universidadSwitch.isOn = false
            polancoSwitch.isOn = false
        }
    }

    @IBAction func sports(_ sender: UISwitch) {
        if sportsSwitch.isOn == true{
            tuxtlaSwitch.isOn = false
            sevillaSwitch.isOn = false
            coapaSwitch.isOn = false
            coyoacanSwitch.isOn = false
            universidadSwitch.isOn = false
            polancoSwitch.isOn = false
        }
    }

}

I’ve only show you two switches at the example with the purpose of not filling this with many code, but there are like 15 switches.

And in the other ViewController, which is connected to this one, the HomeViewController, contains coupons that comes from a JSON, and conforms an array of ten items displayed on a TableViewCell, the code:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var data : NSArray = []

    var mainData : NSArray = []

    var couponsImg : [UIImage] = []

    var couponsTitle : [String] = []

    var couponsDesc : [String] = []

    var couponsCat : [String] = []



    func getCoupons(){

        let miURL = URL(string: RequestConstants.requestUrlBase)

        let request =  NSMutableURLRequest(url: miURL!)

        request.httpMethod = "GET"

        if let data = try? Data(contentsOf: miURL! as URL) {

            do {

                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary

                let parseJSON = json

                let object = parseJSON?["object"] as! NSDictionary

                let mainCoupon = object["mainCoupon"] as! NSArray

                let coupons = object["coupons"] as! NSArray

                self.mainData = mainCoupon

                self.data = coupons

                self.couponImg1 = (mainCoupon[0] as AnyObject).value(forKey: "urlImage") as! String

                self.couponImg2 = (mainCoupon[1] as AnyObject).value(forKey: "urlImage") as! String

                self.couponTitle1 = (mainCoupon[0] as AnyObject).value(forKey: "nameStore") as! String

                self.couponTitle2 = (mainCoupon[1] as AnyObject).value(forKey: "nameStore") as! String

                self.couponDesc1 = (mainCoupon[0] as AnyObject).value(forKey: "promoDescription") as! String

                self.couponDesc2 = (mainCoupon[1] as AnyObject).value(forKey: "promoDescription") as! String

                self.couponCat1 = (mainCoupon[0] as AnyObject).value(forKey: "category") as! String

                self.couponCat2 = (mainCoupon[1] as AnyObject).value(forKey: "category") as! String               

                self.couponsImg = [couponImage1!, couponImage2!, couponImage3!, couponImage4!, couponImage5!, couponImage6!, couponImage7!, couponImage8!, couponImage9!, couponImage10!]

                self.couponsTitle = [couponTitle1, couponTitle2, couponTitle3, couponTitle4, couponTitle5, couponTitle6, couponTitle7, couponTitle8, couponTitle9, couponTitle10]

                self.couponsDesc = [couponDesc1, couponDesc2, couponDesc3, couponDesc4, couponDesc5, couponDesc6, couponDesc7, couponDesc8, couponDesc9, couponDesc10]

                self.couponsCat = [couponCat1, couponCat2, couponCat3, couponCat4, couponCat5, couponCat6, couponCat7, couponCat8, couponCat9, couponCat10]

            } catch {

                let error = ErrorModel()

                error.phrase = "PARSER_ERROR"

                error.code = -1

                error.desc = "Parser error in get Notifications action"

            }

        }    

    }



    @IBAction func showFilters(_ sender: Any) {

        let vc = self.storyboard!.instantiateViewController(withIdentifier: "filters") as! FiltersViewController

        self.present(vc, animated: false, completion: nil)

            }



    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell

        cell.couponImg.image = couponsImg[indexPath.row]

        cell.couponTitle.text = couponsTitle[indexPath.row]

        cell.couponDescription.text = couponsDesc[indexPath.row]

        cell.couponCategory.text = couponsCat[indexPath.row]

    return cell

    }

(Again I’ve only showed you two coupons for the example). The thing is that I need to apply some filters to the coupons on the TableCell. The first time the view appear it shows the 10 coupons correctly, but when I go to the filters an put it some of them ON it doesn’t make a difference, the method I was trying to use was something like this, first have an instance of the FiltersViewController class:

var filters = FilterViewController()

if filters.isMovingToParentViewController == true {
            if filters.restaurantsSwitch.isOn == false {
                self.couponsImg.remove(at: 0)
                self.couponsImg.remove(at: 1)
                self.couponsImg.remove(at: 2)
            }

            if filters.sportsSwitch.isOn == false {
                self.couponsImg.remove(at: 3)
                self.couponsImg.remove(at: 4)
                self.couponsImg.remove(at: 5)
            }
        }

In the example bellow I’m trying to say that if a have the restaurant switch off, I’m going to delete the corresponding coupons of the restaurant category, and the same with the sports switch. But first of all I don’t know where to include this logic, in which method? And also I don’t know if this instruction is correct for my purposes. Can somebody give me a hand please???


Solution

  • Your logic is not working because you're instantiating a new FilterViewController, different from the FilterViewController associated with you screen.

    You can solve this using delegate.

    First, create the delegate:

    protocol FilterDelegate {
        func updateTable() } 
    

    Then, In your FilterViewController add this line:

    weak var delegate:FilterDelegate?
    

    You HomeViewController have to conform with this delegate, so:

    class HomeViewController: FilterDelegate ... {

    func updateTable() {
    /* GET THE DATA FILTERED HERE */
    tableview.reloadData() 
    }
    

    In your FilterViewController:

       @IBAction func returnHome(_ sender: Any) {
            let vc = self.storyboard!.instantiateViewController(withIdentifier: "home") as! HomeViewController
            self.delegate = vc
            self.present(vc, animated: false, completion: nil)
            delegate?.updateTable() 
        }
    

    I think that should work.

    EDIT:

    Another approach is to create a segue between these two vcs and pass the which filters are active using the "prepare" function . Then you can take this information in your HomeVC and load your table based on the filters in the viewDidLoad function.

    1 - Create a object Filters:

    class Filters {
             var tuxtlaSwitchIsOn: Bool
             var sevillaSwitchIsOn: Bool
             ...
             init(tuxtlaSwitchIsOn: Bool, sevillaSwitchIsOn: Bool, ...) {
                 self.tuxtlaSwitchIsOn = tuxtlaSwitchIsOn
                 self.sevillaSwitchIsOn = sevillaSwitchIsOn
                 ...
             }
    }
    

    2 - Add a attribute Filters to your HomeVC

    class HomeViewController : ... {
    ...
    var filtersActive: Filters?
    ...
    }
    

    3 - In your FilterViewController instantiate a Filter object indicating which filters are on

    4 - In your FilterViewController prepare funs pass the Filter object to HomeVC

    5 - In your HomeVC, get the Filter object and filter your data based on it.