我有一个tableview,它有两种类型的单元格。一个与图像和其他通常只有文本。当用户选中其中一行时,tableview向下钻取并打开一个新的tableview(就像iOS上的设置一样)。我有以下数据模型,但它只适用于一页。如何使用MVVC实现嵌套的。我搜索了很多MVVC教程,但无法弄清楚我的情况。我的意思是例如一行称为“文档”,当我选择文档时,我想列出所有文档,如“First Doc”,“Second Doc”等,这个过程对所有行都是相同的。
protocol SameCell{
var type: CellType { get }
}
struct LeftMenuSimpleCellData: SameCell{
let cellText: String
let haveIndicator: Bool
let sub: subTable?
let type: CellType
}
struct LeftMenuCarCellData: SameCell{
let carImage: String
let plateText: String
let modelText: String
let haveIndicator: Bool
let sub: subTable?
let type: CellType
}
struct subTable{
let cellText: String
let haveIndicator: Bool
}
enum CellType{
case LeftMenuSimpleCellData
case LeftMenuCarCellData
}
class LeftMenuDataModel{
var optionsData: [SameCell] = []
let carData: [LeftMenuCarCellData] = []
init(){
}
func populateOptionsData(){
optionsData.append(LeftMenuCarCellData(carImage: "icon", plateText: "Car", modelText: "Model Name", haveIndicator: true,sub: nil, type: .LeftMenuCarCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Hello", haveIndicator: false, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Hello", haveIndicator: true, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Hello", haveIndicator: true, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "HEllo", haveIndicator: true, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Hello", haveIndicator: true, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Hello", haveIndicator: true, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Hello", haveIndicator: false, sub: nil,type: .LeftMenuSimpleCellData))
optionsData.append(LeftMenuSimpleCellData(cellText: "Exit", haveIndicator: false, sub: nil,type: .LeftMenuSimpleCellData))
}
编辑:当我搜索时,“Key:Value”数组可以正常工作。但是在代码下方,“LeftMenuSimpleCellData”不符合协议“Hashable”错误。
var optionsData: [LeftMenuSimpleCellData: [LeftMenuSimpleCellData] ]?
编辑2:我可以将结构改为递归吗?
struct LeftMenuSimpleCellData{
let cellText: String
let haveIndicator: Bool
let subMenu: LeftMenuSimpleCellData
}
编辑3:我编辑了我的代码。它现在特别有效。但我还没有实现第二个子菜单。
答案 0 :(得分:0)
所以根据你的问题和你的意见,这是我最后修改的答案,我创建了一个虚拟的ViewModel
结构。请参考此参考并尝试制作您自己的ViewModel。
所以我们走了......
class LeftMenuSimpleCellData{
let cellText: String
let haveIndicator: Bool
var nextVM : ViewModel?
init(_ text : String , indicator : Bool = true ) {
self.cellText = text
self.haveIndicator = indicator
}
}
class ViewModel : NSObject
{
private override init() {
}
init(data : [LeftMenuSimpleCellData])
{
self.cellData = data
}
private var cellData = [LeftMenuSimpleCellData]()
var count : Int {return cellData.count}
func cellData(at index : Int) -> LeftMenuSimpleCellData {
return cellData[index]
}
}
现在获得RootNode ViewModel
,我已经写了这个函数
func getVM(for detail : [[String : Any]]) -> ViewModel {
let leftCellMenu = detail.map {[weak self] (det) -> LeftMenuSimpleCellData in
let leftCellData = LeftMenuSimpleCellData.init(det["name"] as! String)
if let arr = det["Sub Menu"] as? [[String : Any]] , !arr.isEmpty {
leftCellData.nextVM = self?.getVM(for: arr)
}
else
{
leftCellData.nextVM = nil
}
return leftCellData
}
return ViewModel(data: leftCellMenu)
}
以下是 detail : [[String : Any]]
[
{
"name" : "Wi Fi",
"Sub Menu" : [
{
"name" : "Wi Fi1",
"Sub Menu" : [
]
},
{
"name" : "Wi Fi2",
"Sub Menu" : [
]
}
]
},
{
"name" : "Blutooth",
"Sub Menu" : [
{
"name" : "Blutooth1",
"Sub Menu" : [
]
},
{
"name" : "Blutooth2",
"Sub Menu" : [
]
}
]
},
{
"name" : "General",
"Sub Menu" : [
{
"name" : "About",
"Sub Menu" : [
{
"name" : "Name",
"Sub Menu" : [
]
},
{
"name" : "Network",
"Sub Menu" : [
]
}
]
},
{
"name" : "Accessibility",
"Sub Menu" : [
{
"name" : "VoiceOver",
"Sub Menu" : [
]
},
{
"name" : "Speech",
"Sub Menu" : [
{
"name" : "Speech Selection",
"Sub Menu" : [
]
}
]
}
]
}
]
}
]
这将为mainViewController提供rootVM。
现在mainViewController tableView
数据源方法
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let subMenu = vm.cellData(at: indexPath.row)
cell.textLabel?.text = subMenu.cellText
cell.accessoryType = subMenu.nextVM == nil ? .none : .disclosureIndicator
return cell
}
对于tableView
委托方法
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let subMenu = vm.cellData(at: indexPath.row)
guard subMenu.nextVM != nil else {
return
}
let mainVC = self.storyboard?.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
mainVC.vm = subMenu.nextVM!
navigationController?.pushViewController(mainVC, animated: true)
}
我希望现在这会帮助你实现你想要的。如果您有任何疑问,请发表评论。