如何根据我在另一个 ViewController 中的信息更改插入到 TableCell 的数组?
How to change an array that is inserted on a TableCell from information I have in another ViewController?
我需要你的帮助!我不知道如何根据我在另一个 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 中,首页 ViewController 包含来自 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 张优惠券,但是当我进入过滤器并将其中的一些打开时它并没有什么区别,我尝试使用的方法是这样的,首先有一个过滤器实例ViewController 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)
}
}
在下面的示例中,我想说的是,如果餐厅关闭,我将删除餐厅类别的相应优惠券,体育开关也是如此。但首先我不知道在哪里包含这个逻辑,在哪个方法中?而且我也不知道这条指令是否适合我的目的。有人可以帮我一下吗???
您的逻辑不工作,因为您正在实例化一个新的 FilterViewController,它不同于与您的屏幕关联的 FilterViewController。
你可以使用委托来解决这个问题。
首先,创建委托:
protocol FilterDelegate {
func updateTable() }
然后,在您的 FilterViewController 中添加这一行:
weak var delegate:FilterDelegate?
你的 HomeViewController 必须符合这个委托,所以:
class 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()
}
我认为这应该可行。
编辑:
另一种方法是在这两个 vc 之间创建一个 segue,并使用 "prepare" 函数传递哪些过滤器处于活动状态。然后你可以在你的 HomeVC 中获取这些信息并根据 viewDidLoad 函数中的过滤器加载你的table。
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 中准备 funs 将 Filter 对象传递给 HomeVC
5 - 在您的 HomeVC 中,获取 Filter 对象并根据它过滤您的数据。
当然,这就是您需要的。所以你有一组充满数据的数组,你想对它们应用过滤器。首先,您需要为过滤结果创建另一个数组。这是因为当用户删除过滤器时,您仍然希望显示完整列表。为简化起见,假设您只有一个数组 Foo: [String]
。因此,您需要创建另一个名为 FooFiltered: [String]
的数组来保存搜索结果。加载视图控制器时,您可以将其留空。
接下来,在你的过滤部分,建议使用像这样的数组过滤技术,但如果你想按你的方式做也没关系。所以你需要做的就是从 Foo
数组中获取符合特定条件的元素并将它们复制到 FooFiltered
数组中。这里让我给你看一个手动过滤的例子
func filter() {
FooFiltered = [String]() //Clean up every time before search
for str in Foo {
if str == "criteria" {
FooFiltered.append(str)
}
}
}
现在您有一个过滤项目列表。您需要一个标志来告诉 table 视图要显示哪组数组。假设您有一个名为 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
}
}
您还需要将此标志更新到所有 table 视图委托方法,例如 numberOfRowsInSection
等
最后,使用这些代码,您的 table 视图被配置为根据标志显示完整结果或过滤结果,并且您在 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()
}
我需要你的帮助!我不知道如何根据我在另一个 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 中,首页 ViewController 包含来自 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 张优惠券,但是当我进入过滤器并将其中的一些打开时它并没有什么区别,我尝试使用的方法是这样的,首先有一个过滤器实例ViewController 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)
}
}
在下面的示例中,我想说的是,如果餐厅关闭,我将删除餐厅类别的相应优惠券,体育开关也是如此。但首先我不知道在哪里包含这个逻辑,在哪个方法中?而且我也不知道这条指令是否适合我的目的。有人可以帮我一下吗???
您的逻辑不工作,因为您正在实例化一个新的 FilterViewController,它不同于与您的屏幕关联的 FilterViewController。
你可以使用委托来解决这个问题。
首先,创建委托:
protocol FilterDelegate {
func updateTable() }
然后,在您的 FilterViewController 中添加这一行:
weak var delegate:FilterDelegate?
你的 HomeViewController 必须符合这个委托,所以:
class 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()
}
我认为这应该可行。
编辑:
另一种方法是在这两个 vc 之间创建一个 segue,并使用 "prepare" 函数传递哪些过滤器处于活动状态。然后你可以在你的 HomeVC 中获取这些信息并根据 viewDidLoad 函数中的过滤器加载你的table。
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 中准备 funs 将 Filter 对象传递给 HomeVC
5 - 在您的 HomeVC 中,获取 Filter 对象并根据它过滤您的数据。
当然,这就是您需要的。所以你有一组充满数据的数组,你想对它们应用过滤器。首先,您需要为过滤结果创建另一个数组。这是因为当用户删除过滤器时,您仍然希望显示完整列表。为简化起见,假设您只有一个数组 Foo: [String]
。因此,您需要创建另一个名为 FooFiltered: [String]
的数组来保存搜索结果。加载视图控制器时,您可以将其留空。
接下来,在你的过滤部分,建议使用像Foo
数组中获取符合特定条件的元素并将它们复制到 FooFiltered
数组中。这里让我给你看一个手动过滤的例子
func filter() {
FooFiltered = [String]() //Clean up every time before search
for str in Foo {
if str == "criteria" {
FooFiltered.append(str)
}
}
}
现在您有一个过滤项目列表。您需要一个标志来告诉 table 视图要显示哪组数组。假设您有一个名为 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
}
}
您还需要将此标志更新到所有 table 视图委托方法,例如 numberOfRowsInSection
等
最后,使用这些代码,您的 table 视图被配置为根据标志显示完整结果或过滤结果,并且您在 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()
}