【问题标题】:How to change an array that is inserted on a TableCell from information I have in another ViewController?如何根据我在另一个 ViewController 中的信息更改插入到 TableCell 上的数组?
【发布时间】:2017-12-03 10:54:34
【问题描述】:

我需要你的帮助!我不知道如何根据我在另一个 ViewController 中的信息更改插入到 TableCell 上的数组。有点乱,但我会通过我的代码向您展示。

我这里有一个ViewController,里面有很多开关对应不同类别的优惠券,代码如下:

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
        }
    }

}

我在示例中仅向您展示了两个开关,目的是不填充太多代码,但大约有 15 个开关。

在另一个与此相连的 ViewController 中,HomeViewController 包含来自 JSON 的优惠券,并符合在 TableViewCell 上显示的由十个项目组成的数组,代码:

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

    }

(再次,我只向您展示了示例中的两张优惠券)。问题是我需要对 TableCell 上的优惠券应用一些过滤器。第一次出现视图时,它正确显示了 10 张优惠券,但是当我转到过滤器并将其中的一些打开时,它并没有什么不同,我尝试使用的方法是这样的,首先有一个FiltersViewController 类的实例:

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)
            }
        }

在下面的示例中,我想说的是,如果关闭餐厅,我将删除餐厅类别的相应优惠券,与体育开关相同。但首先我不知道在哪里包含这个逻辑,在哪个方法中?而且我不知道这条指令是否适合我的目的。有人可以帮帮我吗???

【问题讨论】:

    标签: ios arrays swift3 tableviewcell uiswitch


    【解决方案1】:

    您的逻辑不起作用,因为您正在实例化一个新的 FilterViewController,与与您的屏幕关联的 FilterViewController 不同。

    您可以使用委托解决此问题。

    首先,创建委托:

    protocol FilterDelegate {
        func updateTable() } 
    

    然后,在你的 FilterViewController 中添加这一行:

    weak var delegate:FilterDelegate?
    

    你的 HomeViewController 必须符合这个委托,所以:

    类 HomeViewController: FilterDelegate ... {

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

    在您的 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() 
        }
    

    我认为这应该可行。

    编辑:

    另一种方法是在这两个 vcs 之间创建一个 segue,并使用“准备”功能传递哪些过滤器处于活动状态。然后你可以在你的 HomeVC 中获取这些信息,并根据 viewDidLoad 函数中的过滤器加载你的表。

    1 - 创建一个对象过滤器:

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

    2 - 向 HomeVC 添加属性过滤器

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

    3 - 在您的 FilterViewController 中实例化一个 Filter 对象,指示哪些过滤器处于打开状态

    4 - 在您的 FilterViewController 中准备乐趣,将 Filter 对象传递给 HomeVC

    5 - 在您的 HomeVC 中,获取 Filter 对象并根据它过滤您的数据。

    【讨论】:

    • 非常感谢,这是从 VC 到另一个交换数据的更好方法! ;)
    • 哦,非常感谢您上次的贡献,它对我帮助很大,现在我的解决方案完成了! :D
    【解决方案2】:

    当然,这就是您所需要的。所以你有一组充满数据的数组,你想对它们应用过滤器。首先,您需要为过滤结果创建另一个数组。这是因为当用户删除过滤器时,您仍然希望显示完整列表。为简化起见,假设您只有一个数组 Foo: [String]。因此,您需要创建另一个名为 FooFiltered: [String] 的数组来保存搜索结果。加载视图控制器时,您可以将其留空。

    接下来,在您的过滤器部分,建议使用this post 之类的数组过滤器技术,但如果您想按照自己的方式进行操作也可以。因此,您需要做的就是从Foo 数组中获取符合特定条件的元素并将它们复制到FooFiltered 数组中。下面我给大家举个手动过滤的例子

    func filter() {
        FooFiltered = [String]() //Clean up every time before search
        for str in Foo {
            if str == "criteria" {
                FooFiltered.append(str)
            }
        }
    }
    

    现在您有一个过滤项目列表。您需要一个标志来告诉表格视图要显示哪组数组。假设您有一个名为 showSearchResult 的标志,最初设置为 false。执行过滤器时,将其设置为 true。所以你的cellForRow 看起来像

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if showSearchResult {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
    
            cell.textField.text = FooFiltered[indexPath.row]
    
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
    
            cell.textField.text = Foo[indexPath.row]
    
            return cell
        }
    }   
    

    您还需要将此标志更新为您的所有表视图委托方法,例如numberOfRowsInSection 等。

    最后,通过这些代码,您的表格视图被配置为根据标志显示完整结果或过滤结果,并且您在 filter() 函数中设置该标志。最后要做的是让 tableView 在过滤器完成时重新加载数据。所以像这样修改你的过滤器功能,你应该已经准备好了。

    func filter() {
        FooFiltered = [String]() //Clean up every time before search
        showSearchResul = true
        for str in Foo {
            if str == "criteria" {
                FooFiltered.append(str)
            }
        }
        self.tableView.reloadData()
    }
    

    【讨论】:

    • 非常感谢您的解释,它是如此清晰和有帮助!对此,我真的非常感激! :D
    • @ZitaNoriegaEstrada 没问题,编码愉快:)
    猜你喜欢
    • 2019-06-25
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多