Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-使用自定义筛选器返回tableView中的数组数据_Swift_Uitableview - Fatal编程技术网

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

Swift-使用自定义筛选器返回tableView中的数组数据,swift,uitableview,Swift,Uitableview,我在UIViewController中有一个UITableView,用于加载用户排名。只有一个排名列表有点太有限了,所以我添加了一个自定义栏来加载不同的排名(每周、每月和每年)。我之所以选择这样做,是因为它给了我很多对布局约束的控制——分段控制没有 当前的问题是,我不知道如何根据菜单栏中选定的选项卡返回正确的数组。现在,我使用第四个空数组在选择选项卡时复制其他三个数组中的一个的数据,但是如何将这些数据发送回初始视图,以便在tableView的numberOfRowsInSection中返回计数

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

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

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
}
}
我的自定义菜单栏

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

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

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

上述代码是为了简洁而存在的原始问题代码的补充,即它不是独立的。

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

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

上述代码是对原始问题代码的补充,其存在是为了简洁,即它不是独立的。

非常高兴我能提供帮助:DJohn,你能再帮我一件事吗?当我启动应用程序并转到“排名”选项卡时,所有表格最初都是空的。tableview仅在我点击其中一个菜单栏项时返回数据。由于第一个菜单栏项是“week”,我想立即加载该列表。其他的则可以,因为它们将由菜单的选定状态处理。谢谢你的支持:D非常高兴我能帮忙:DJohn,你能再帮我一件事吗?当我启动应用程序并转到“排名”选项卡时,所有表格最初都是空的。tableview仅在我点击其中一个菜单栏项时返回数据。由于第一个菜单栏项是“week”,我想立即加载该列表。其他的则可以,因为它们将由菜单的选定状态处理。谢谢你的支持:D