我有一个UITableView,我想添加几个类别。
我的数据看起来像这样:
第一个屏幕应显示所有MainCategories,然后单击A,它应显示SubCategory红色和蓝色,依此类推...
我到处搜索,但是找不到解决方案。
我应该如何构造我的数据,这样才能正常工作? cellForRowAt
仅使您可以选择提供第一组子类别的数据。我将其余的数据放在哪里?
答案 0 :(得分:1)
创建具有标题和Menu
对象数组的结构Menu
。
struct Menu {
var title: String
var subMenus: [Menu]?
}
使用UIScrollView
而不是表格视图,并添加嵌套的UIStackView
// ViewController.swift
class ViewController: UIViewController {
var menus:[Menu] = []
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let red1 = Menu(title: "SubCategory Red", subMenus: [Menu(title: "SubSubCategory X", subMenus: [Menu(title: "SubSubSubCategory", subMenus: nil)]),
Menu(title: "SubSubCategory Y", subMenus: nil)])
let blue1 = Menu(title: "SubCategory Blue", subMenus: nil)
let red2 = Menu(title: "SubCategory Red", subMenus: [Menu(title: "SubSubCategory X", subMenus: nil),
Menu(title: "SubSubCategory Y", subMenus: nil)])
let blue2 = Menu(title: "SubCategory Blue", subMenus: [Menu(title: "SubSubCategory X", subMenus: nil)])
let green2 = Menu(title: "SubCategory Green", subMenus: nil)
menus = [Menu(title: "MainCategory A", subMenus: [red1, blue1]), Menu(title: "MainCategory B", subMenus: [red2, blue2, green2])]
let scrollView = UIScrollView()
scrollView.backgroundColor = .white
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
let outerStackView = UIStackView()
outerStackView.axis = .vertical
outerStackView.alignment = .fill
outerStackView.distribution = .fillProportionally
outerStackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(outerStackView)
scrollView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[scrollView]|", options: [], metrics: nil, views: ["scrollView": scrollView]))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: [], metrics: nil, views: ["scrollView": scrollView]))
scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[outerStackView]|", options: [], metrics: nil, views: ["outerStackView": outerStackView]))
scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[outerStackView]|", options: [], metrics: nil, views: ["outerStackView": outerStackView]))
scrollView.widthAnchor.constraint(equalTo: outerStackView.widthAnchor).isActive = true
let height = scrollView.heightAnchor.constraint(equalTo: outerStackView.heightAnchor)
height.priority = .defaultLow
height.isActive = true
menus.forEach {
outerStackView.addArrangedSubview(MenuStackView(menu: $0, padding: 20))
}
}
}
// MenuStackView.swift
class MenuStackView: UIStackView {
convenience init(menu: Menu, padding: CGFloat) {
self.init()
axis = .vertical
alignment = .fill
distribution = .fillProportionally
let btn = UIButton(type: .custom)
btn.contentHorizontalAlignment = .left
btn.titleEdgeInsets = UIEdgeInsets(top: 0, left: padding, bottom: 0, right: 0)
btn.addTarget(self, action: #selector(toggle(_:)), for: .touchUpInside)
btn.setTitleColor(.black, for: .normal)
btn.setTitle(menu.title, for: .normal)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.heightAnchor.constraint(equalToConstant: 40).isActive = true
addArrangedSubview(btn)
menu.subMenus?.forEach {
let stackView = MenuStackView(menu: $0, padding: padding+20)
stackView.isHidden = true
self.addArrangedSubview(stackView)
}
}
@objc func toggle(_ sender: UIButton) {
self.arrangedSubviews.forEach {
if $0 is MenuStackView {
$0.isHidden = !$0.isHidden
}
}
}
}
答案 1 :(得分:1)
创建带有标题和Menu对象数组的结构菜单。
struct Menu {
var title: String
var subMenus: [Menu]?
}
在要启动菜单的视图控制器中添加菜单详细信息。并用菜单对象推动UITableViewController
。如果按下了子菜单,则用子菜单对象按UITableViewController
。
// ViewController.swift
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func startMenuAction(_ sender: UIButton) {
let red1 = Menu(title: "SubCategory Red", subMenus: [Menu(title: "SubSubCategory X", subMenus: [Menu(title: "SubSubSubCategory", subMenus: nil)]),
Menu(title: "SubSubCategory Y", subMenus: nil)])
let blue1 = Menu(title: "SubCategory Blue", subMenus: nil)
let red2 = Menu(title: "SubCategory Red", subMenus: [Menu(title: "SubSubCategory X", subMenus: nil),
Menu(title: "SubSubCategory Y", subMenus: nil)])
let blue2 = Menu(title: "SubCategory Blue", subMenus: [Menu(title: "SubSubCategory X", subMenus: nil)])
let green2 = Menu(title: "SubCategory Green", subMenus: nil)
let categories = [Menu(title: "MainCategory A", subMenus: [red1, blue1]), Menu(title: "MainCategory B", subMenus: [red2, blue2, green2])]
let mainMenu:Menu = Menu(title: "My Menu", subMenus: categories)
let menuVC = MenuVC()
menuVC.currentMenu = mainMenu
self.navigationController?.pushViewController(menuVC, animated: true)
}
}
// MenuVC.swift
class MenuVC: UITableViewController {
var currentMenu: Menu?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
title = currentMenu?.title
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (currentMenu?.subMenus?.count ?? 0)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier") ?? UITableViewCell(style: .default, reuseIdentifier: "reuseIdentifier")
if currentMenu?.subMenus?[indexPath.row].subMenus?.isEmpty ?? true {
cell.accessoryType = .none
} else {
cell.accessoryType = .disclosureIndicator
}
cell.textLabel?.text = currentMenu?.subMenus?[indexPath.row].title
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if !(currentMenu?.subMenus?[indexPath.row].subMenus?.isEmpty ?? true) {
let menuVC = MenuVC()
menuVC.currentMenu = currentMenu?.subMenus?[indexPath.row]
self.navigationController?.pushViewController(menuVC, animated: true)
}
}
}
答案 2 :(得分:0)
您可以从Github下载示例项目。在这种情况下,我使用UITableview根据需要显示不同的类别。