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