如何将Table View Controller与多个子类别一起使用

时间:2019-06-27 08:13:16

标签: arrays swift xcode uitableview

我有一个UITableView,我想添加几个类别。

我的数据看起来像这样:

  • 主要类别A
    • 子类别红色
      • SubSubCategory X
        • SubSubSubCategory
      • SubSubCategory Y
    • 子类别蓝色
  • 主要类别B
    • 子类别红色
      • SubSubCategory X
      • SubSubCategory Y
    • 子类别蓝色
      • SubSubCategory X
    • 子类别绿色

第一个屏幕应显示所有MainCategories,然后单击A,它应显示SubCategory红色和蓝色,依此类推...

我到处搜索,但是找不到解决方案。

我应该如何构造我的数据,这样才能正常工作? cellForRowAt仅使您可以选择提供第一组子类别的数据。我将其余的数据放在哪里?

3 个答案:

答案 0 :(得分:1)

enter image description here

创建具有标题和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)

enter image description here

创建带有标题和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根据需要显示不同的类别。

enter image description here