【问题标题】:Filtering UItableview Swift IOS过滤 UItableview Swift IOS
【发布时间】:2018-01-21 09:20:00
【问题描述】:

我正在尝试根据从另一个 VC 传回的变量过滤 UITableView,该 VC 是处理过滤器 UI 的 Eureka 表单。

我想根据这两个变量过滤表格视图:

 var filterByPrice: Float?

 var filteredRentalTypes: Set<String>?

我的价格过滤器工作正常,但我无法过滤租赁类型。可能有一种更有效的方法来做到这一点,但这是我到目前为止的代码。使用我当前的代码,租赁类型过滤器出现“索引超出范围”崩溃。

这是我的 TableViewVC:

class RentalTableViewVC: UIViewController, UITableViewDataSource, UITableViewDelegate  {

var rentalsArray = [Rental]()
var filteredArrary = [Rental]()
var myRentals = [String]()

var filterByPrice: Float?
var filteredRentalTypes: Set<String>?


static var imageCache: NSCache<NSString, UIImage> = NSCache()


@IBOutlet weak var tableView: UITableView!

var hidingBarMangar: HidingNavigationBarManager?


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toDetailVC" {
        let destination = segue.destination as? DetailVC
        let value = tableView.indexPathForSelectedRow?.row

        if filteredArrary.count != 0 {

            destination?.emailAdress = filteredArrary[value!].email!
            destination?.bond = filteredArrary[value!].bond!
            destination?.dateAval = filteredArrary[value!].dateAval!
            destination?.pets = filteredArrary[value!].pets!
            destination?.rent = filteredArrary[value!].price!
            destination?.rentalTitle = filteredArrary[value!].title!
            destination?.imageURL = filteredArrary[value!].imageURL!
            destination?.des = filteredArrary[value!].description!
            destination?.rentalType = filteredArrary[value!].rentalType!
            destination?.streetName = filteredArrary[value!].streetName!
            destination?.city = filteredArrary[value!].city!
            destination?.postcode = filteredArrary[value!].postcode!
        } else {
            destination?.emailAdress = rentalsArray[value!].email!
            destination?.bond = rentalsArray[value!].bond!
            destination?.dateAval = rentalsArray[value!].dateAval!
            destination?.pets = rentalsArray[value!].pets!
            destination?.rent = rentalsArray[value!].price!
            destination?.rentalTitle = rentalsArray[value!].title!
            destination?.imageURL = rentalsArray[value!].imageURL!
            destination?.des = rentalsArray[value!].description!
            destination?.rentalType = rentalsArray[value!].rentalType!
            destination?.streetName = rentalsArray[value!].streetName!
            destination?.city = rentalsArray[value!].city!
            destination?.postcode = rentalsArray[value!].postcode!
        }
    }
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if filteredArrary.count != 0 {
        return filteredArrary.count
    } else {
        return rentalsArray.count
    }

}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

  var rental = rentalsArray[indexPath.row]

    if self.filteredArrary.count != 0 {
        rental = filteredArrary[indexPath.row]
    }


    if let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? RentalCell {




        var rentalImage = ""

        if rental.imageURL != nil {
            rentalImage = rental.imageURL!
        }


        if let img = RentalTableViewVC.imageCache.object(forKey: rentalImage as NSString) {
            cell.configureCell(rental: rental, image: img)

            return cell
        } else {
            cell.configureCell(rental: rental, image: nil)

            return cell
        }

    } else {
        return RentalCell()
    }

}




@IBAction func backPressed(_ sender: Any) {
    dismiss(animated: true, completion: nil)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    hidingBarMangar?.viewWillAppear(animated)
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    hidingBarMangar?.viewDidLayoutSubviews()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    hidingBarMangar?.viewWillDisappear(animated)
}
override func viewDidLoad() {
    super.viewDidLoad()



    tableView.dataSource = self
    tableView.dataSource = self

    //Firebase observer
    DataService.ds.DBrefRentals.observe(.value) { (snapshot) in

        self.rentalsArray = []
        self.filteredArrary = []

        if let snapshots = snapshot.children.allObjects as? [DataSnapshot] {
            for snap in snapshots {
                if let dicOfRentals = snap.value as? Dictionary<String,AnyObject> {

                    let key = snap.key

                    let rental = Rental(postID: key, userData: dicOfRentals)
                    self.rentalsArray.append(rental)

                    //Placing filtered items in the filtered array
                    if self.filterByPrice != nil {
                        let priceAsFloat = (rental.price! as NSString).floatValue

                        if self.filterByPrice! >= priceAsFloat {
                            self.filteredArrary.append(rental)
                        }
                    }

                    if self.filteredRentalTypes != nil {


                        for rentals in self.filteredRentalTypes! {
                        if rental.rentalType == rentals {
                            print("******hh\(String(describing: self.filteredRentalTypes))")
                            self.filteredArrary.append(rental)
                                }

                        }
                    }


                }
            }
            self.tableView.reloadData()
        }



    }
    addHidingBar()


}

override func viewDidAppear(_ animated: Bool) {
    print("**********\(String(describing: filterByPrice)))")
}



func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    rentalsArray[indexPath.row].incrimentViews()

    let postViewsToFB = DataService.ds.DBrefRentals.child(rentalsArray[indexPath.row].postID!)

    postViewsToFB.child("views").setValue(rentalsArray[indexPath.row].views)

     performSegue(withIdentifier: "toDetailVC" , sender: nil)
}





func addHidingBar() {


    let extensionView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 40))
    extensionView.layer.borderColor = UIColor.lightGray.cgColor
    extensionView.layer.borderWidth = 1
    extensionView.backgroundColor = UIColor(white: 230/255, alpha: 1)
    /*let label = UILabel(frame: extensionView.frame)
    label.text = "Extension View"
    label.textAlignment = NSTextAlignment.center
    extensionView.addSubview(label) */

    let btn = UIButton(frame: CGRect(x: 20, y: 15, width: 75, height: 10))
    btn.setTitle("Filter", for: .normal)
    let btnColour = UIColor(displayP3Red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0)
    btn.setTitleColor(btnColour, for: .normal)
    btn.titleLabel?.font = headerFont
    btn.addTarget(self, action: #selector(filterBtnPressed), for: .touchUpInside)

    extensionView.addSubview(btn)
    hidingBarMangar = HidingNavigationBarManager(viewController: self, scrollView: tableView)
    hidingBarMangar?.addExtensionView(extensionView)

}

@objc func filterBtnPressed() {
    performSegue(withIdentifier: "toFilterVC", sender: nil)
}


}

【问题讨论】:

  • 不相关,但从数组 (filteredArrary[value!]) 中获取并强制展开 12 次(!)相同的值是不必要的昂贵。这是很坏的习惯。如果集合类型(或字符串)为空,永远不会检查.count == 0。有一个优化的属性isEmpty。而且你使用了太多的问号和感叹号。
  • 感谢您的反馈 vadian,我将审查该代码。

标签: ios iphone swift uitableview filtering


【解决方案1】:

您可能会在 numberOfRows 中返回不同的数组,并且它们的大小可能不同,因此在索引任何数组之前检查计数,好像数组 count != 0 并不意味着您可以使用可能大于 0 的索引 path.row 对其进行索引,在 cellForRow 中更改这一行

   if self.filteredArrary.count != 0 {
    rental = filteredArrary[indexPath.row]
}

  if  indexPath.row < self.filteredArrary.count  {
    rental = filteredArrary[indexPath.row]
}

【讨论】:

  • 当我选择“整个房屋”过滤器时,我仍然有索引超出范围,并且选择其他筛选器不会更改TableView时。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 2018-06-04
相关资源
最近更新 更多