Swift - 使用自定义过滤器返回tableView中的数组数据

时间:2017-04-25 05:18:53

标签: swift uitableview

我在UIViewController中有一个UITableView,用于加载用户的排名。只有一个排名列表有点太有限,所以我添加了一个自定义栏来加载不同的排名(每周,每月和每年)。我选择这样做的原因是因为它给了我很多控制我的布局约束 - 分段控制没有。

目前的问题是我根本不知道如何根据菜单栏中的选定选项卡返回正确的数组。截至目前,当选择选项卡时,我使用第四个空数组来复制其他三个数据中的一个,但是如何将此数据发送回我的初始视图,以便我可以在tableView的numberOfRowsInSection中返回计数? / p>

ViewController& TableViewController

class Rank: NSObject{
    var name: String
    var points: Int

init(name: String, points: Int) {
      self.name = name
      self.points = points
    }
}

var rankingArrayWeek = [Rank]()
var rankingArrayMonth = [Rank]()
var rankingArrayTotal = [Rank]()
var filteredRanking = [Rank]()

class RankingController: UIViewController, UITableViewDelegate {

weak var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    setupMenuBar()

    tableView?.delegate = self

    rankingArrayWeek = [
        Rank(name: "Name1", points: 200)
    ]

    rankingArrayMonth = [
        Rank(name: "Name1", points: 300),
        Rank(name: "Name2", points: 200),
    ]

    rankingArrayTotal = [
        Rank(name: "Name1", points: 500),
        Rank(name: "Name2", points: 400),
        Rank(name: "Name3", points: 300),
    ]

    let rankingTableViewController = RankingTableViewController()

    self.addChildViewController(rankingTableViewController)
    rankingTableViewController.view.translatesAutoresizingMaskIntoConstraints = false

    view.addSubview(rankingTableViewController.view)

    rankingTableViewController.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
    rankingTableViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 10).isActive = true
    rankingTableViewController.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    rankingTableViewController.view.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
}

lazy var menuBar: MenuBar = {
    let menuBar = MenuBar()
    menuBar.rankingController = self
    return menuBar
}()

private func setupMenuBar() {
    navigationController?.hidesBarsOnSwipe = true

    view.addSubview(menuBar)
    view.addConstraintsWithFormat("H:|[v0]|", views: menuBar)
    view.addConstraintsWithFormat("V:|[v0(50)]", views: menuBar)
   }
}

 // MARK: TableViewController
class RankingTableViewController: UITableViewController {

  let cellId = "cellId"

  override func viewDidLoad() {
      super.viewDidLoad()

      tableView?.register(RankCell.self, forCellReuseIdentifier: cellId)
      tableView?.tableFooterView = UIView(frame: CGRect.zero)
      tableView?.rowHeight = 60
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return filteredRanking.count
  }
}

我的自定义菜单栏

class MenuBar: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

lazy var collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
    collectionView.isScrollEnabled = false
    collectionView.backgroundColor = .white
    collectionView.dataSource = self
    collectionView.delegate = self
    return collectionView
}()

let cellId = "cellId"
let names = ["Week", "Month", "Total"]

var rankingController: RankingController?

override init(frame: CGRect) {
    super.init(frame: frame)

    collectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)

    addSubview(collectionView)
    addConstraintsWithFormat("H:|[v0]|", views: collectionView)
    addConstraintsWithFormat("V:|[v0]|", views: collectionView)

    let selectedIndexPath = NSIndexPath(item: 2, section: 0)
    collectionView.selectItem(at: selectedIndexPath as IndexPath, animated: false, scrollPosition: .centeredHorizontally)

    setupHorizontalBar()
}

var horizontalBarLeftAnchorConstraint: NSLayoutConstraint?

func setupHorizontalBar() {
    let horizontalBarView = UIView()
    horizontalBarView.backgroundColor = Constants.MAIN_THEME_COLOR
    horizontalBarView.translatesAutoresizingMaskIntoConstraints = false
    addSubview(horizontalBarView)

    horizontalBarLeftAnchorConstraint = horizontalBarView.leftAnchor.constraint(equalTo: self.leftAnchor)
    horizontalBarLeftAnchorConstraint?.isActive = true
    horizontalBarView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    horizontalBarView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1/3).isActive = true
    horizontalBarView.heightAnchor.constraint(equalToConstant: 4).isActive = true
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let x = CGFloat(indexPath.item) * frame.width / 3
    horizontalBarLeftAnchorConstraint?.constant = x

    UIView.animate(withDuration: 0.75, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { self.layoutIfNeeded()
        }, completion: nil)

    if indexPath.item == 0 {
        filteredRanking = rankingArrayWeek
        print(filteredRanking.count)
    } else if indexPath.item == 1 {
        filteredRanking = rankingArrayMonth
        print(filteredRanking.count)
    } else {
        filteredRanking = rankingArrayTotal
        print(filteredRanking.count)
    }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell

    cell.buttonView.text = "\(names[indexPath.item])"
    cell.buttonView.textColor = Constants.MAIN_THEME_COLOR

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: frame.width / 3, height: frame.height)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}
}

更新代码:

要预先选择第一行,我还将其添加到我的cellForItemAt indexPath

if (cell.isSelected == false) {
        didSelect?(kinds[0])
    }

1 个答案:

答案 0 :(得分:2)

建议您在菜单栏上添加一个回调,说明选择了哪种等级。您也可以使用此“种类”来驱动菜单栏的显示。

enum RankKind: String {
    case week = "Week"
    case month = "Month"
    case total = "Total"
}

class MenuBar {

    let kinds = [RankKind.week, .month, .total]

    var didSelect: ((RankKind)->())?

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return kinds.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        cell.buttonView.text = kinds[indexPath.item].rawValue)
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        didSelect?(kinds[indexPath.item])
    }
}

然后RankingController可以自己设置以了解菜单何时更改了类型。

class RankingController {

    func viewDidLoad() {

        menuBar.didSelect = { kind in
            rankingTableViewController.rankingArray = self.rankingArrayFor(kind: kind)
        }

    }

    func rankingArrayFor(kind: RankKind) -> [Rank] {
        switch kind {
        case .week: return rankingArrayWeek
        case .month: return rankingArrayMonth
        case .total:return rankingArrayTotal
        }
    }
}

最后,RankingTableViewController公开其模型(数组),并在重置该模型时重新加载其tableview。

class RankingTableViewController: UITableViewController {

    var rankingArray: [Rank] = [] {
        didSet {
            self.tableView.reloadData()
        }
    }
}

上面的代码是为了简洁而存在的原始问题代码的附加代码,即它不是独立的。