微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何点击 TableView Cell 并导航到下一个 ViewController本地 JSON 文件中的另一个 TableView

如何解决如何点击 TableView Cell 并导航到下一个 ViewController本地 JSON 文件中的另一个 TableView

我在我的 Xcode 项目中本地保存了以下 JSON 文件

{
  "mealPlan": [
    {
      "title": "Meal One","instructions": [
        "This is step number 1 for Meal One.","This is step number 2 for Meal One.","This is step number 3 for Meal One.","This is step number 4 for Meal One."
      ]
    },{
      "title": "Meal Two","instructions": [
        "This is step number 1 for Meal Two.","This is step number 2 for Meal Two.","This is step number 3 for Meal Two.","This is step number 4 for Meal Two."
      ]
    }
  ]
}

以下是我的 MealPlanMealPlanService 结构:

struct MealPlan: Decodable {
    
    var title:String?
    var instructions:[String]?
    
}
struct MealPlanService: Decodable {
    
    var mealPlan:[MealPlan]?
    
}

在我的第一个 ViewController 中,我已经通过 UITableViewCell 的自定义子类成功地显示一个带有我的膳食计划标题(例如“膳食一”和“膳食二”)的 TableView。

class MealPlanCell: UITableViewCell {
    
    @IBOutlet weak var titleLabel: UILabel!
    
    var mealPlanTodisplay:MealPlan?
    
    func displayMealPlan(_ mealPlan:MealPlan) {
        
        // Keep a reference to the mealPlan
        mealPlanTodisplay = mealPlan
        
        // Set the titleLabel
        titleLabel.text = mealPlan.title
        
    }

在 ViewController 中:

class ViewController: UIViewController {
    
    var model = MealPlanModel()
    var mealPlan = [MealPlan]()
    
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set ViewController as the datasource and delegate of the tableView
        tableView.delegate = self
        tableView.dataSource = self
        
        // Use MealPlanModel to get the mealPlans from the JSON File
        model.delegate = self
        model.getMealPlans()
        
    }
    
    override func prepare(for segue: UIStoryboardSegue,sender: Any?) {
        
        // Detect the indexPath the user selected
        let indexPath = tableView.indexPathForSelectedRow
        
        guard indexPath != nil else {
            // The user hasn't selected anything
            return
        }
        
        // Get the mealPlan the user selected
        let mealPlanSelected = mealPlan[indexPath!.row]
        
        // Get a reference to the InstructionViewController
        let instructionVC = segue.destination as! InstructionViewController
        
    }
    
}

extension ViewController: UITableViewDelegate,UITableViewDataSource {
    
    func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        return mealPlan.count
    }
    
    func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        // Get a cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "MealPlanCell",for: indexPath) as! MealPlanCell
        
        // Get the mealPlan that the tableView is asking about
        let mealPlanInTable = mealPlan[indexPath.row]
        
        // Customize the cell
        cell.displayMealPlan(mealPlanInTable)
        
        // Return the cell
        return cell
        
        
    }
    
    func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
        
        
        
    }
    
}

extension ViewController: MealPlanProtocol {
    
    func mealPlansRetrieved(_ mealPlans: [MealPlan]) {
        
        print("MealPlan retrieved from model (ViewController).")
        
        // Set the mealPlans property of the ViewController to the mealPlans passed back from the model
        self.mealPlan = mealPlans
        
        // Refresh the tableView
        tableView.reloadData()
        
    }
    
}

有两件事我花了很多时间搜索/尝试但仍然无法弄清楚。

  1. 如何将我的 instructions 数组中的项目显示到表格中

我使用相同的模型来显示一个 ViewController 中的 mealPlan 和第二个 ViewController 中的 instructions

protocol MealPlanProtocol {
    
    func mealPlansRetrieved(_ mealPlans:[MealPlan])
    
}

class MealPlanModel {
    
    var delegate:MealPlanProtocol?
    
    func getMealPlans() {
        
        // Fetch mealPlans from MealPlansData.json
        getLocalJsonFile()
        
    }
    
    func getLocalJsonFile() {

        // Get bundle path to the MealPlansData.json
        let path = Bundle.main.path(forResource: "MealPlansData",ofType: "json")

        // Double check that the path isn't nil
        guard path != nil else {
            print("Could not find MealPlansData.json.")
            return
        }

        // Create URL object from the path
        let url = URL(fileURLWithPath: path!)

        do {

            // Get the data from the URL
            let data = try Data(contentsOf: url)

            // Attempt to parse MealPlansData.json into objects
            let decoder = JSONDecoder()
            let mealPlanService = try decoder.decode(MealPlanService.self,from: data)
            
            // Get the Meal Plans
            let mealPlans = mealPlanService.mealPlan!
            
            // Get the Instructions
            let instructions = [MealPlan().instructions]
            
            // Notify the delegate of the parsed mealPlanService objects
            dispatchQueue.main.async {
                self.delegate?.mealPlansRetrieved(mealPlans)
            }
            

        }

        catch {

            // Error: Could not download the data at that URL
            print("Could not download the data at that URL.")
        }
    }
}

但我为第二个 ViewController 使用了 UITableViewCell 的不同自定义子类。

class InstructionCell: UITableViewCell {
    
    @IBOutlet weak var instructionLabel: UILabel!
    
    var mealPlanTodisplay:MealPlan?
    let mealPlan = MealPlan()
    
    func displayInstruction(_ currentMealPlan:MealPlan) {
        
        // Keep a reference to the mealPlan
        mealPlanTodisplay = currentMealPlan
        
        // Get the instructions data
        var instruction = mealPlan.instructions
        
        // Set the instructionLabel
        instructionLabel.text = currentMealPlan.instructions![]
        
    }

这是我希望 instructions 在表格视图中显示的第二个 ViewController。

class InstructionViewController: UIViewController {

    var model = MealPlanModel()
    var mealPlan = [MealPlan]()
    var instructions = [MealPlan().instructions]
    var currentMealPlanIndex = 0
    var currentInstructionIndex = 0

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set InstructionViewController as the datasource and delegate of the tableView
        tableView.delegate = self
        tableView.dataSource = self
        
        // Use the InstructionModel to get the instructions from the JSON file
        model.delegate = self
        model.getMealPlans()
    }
}

extension InstructionViewController: UITableViewDelegate,UITableViewDataSource {

    func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {

        // Make sure the MealPlan array contains at least 1 instruction
        // Todo: - Get the instructions from the selected mealPlan
        let instructionsInMealPlan = instructions
        guard instructionsInMealPlan.count > 0 else {
            return 0
        }
        
        return instructionsInMealPlan.count

    }

    func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        // Get a cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "InstructionCell",for: indexPath) as! InstructionCell
        
        // Get the instruction that the tableView is asking about
        // Todo: - Specify the mealPlan that was selected in ViewController
        let instructionInTable = mealPlan[indexPath.row].instructions![indexPath.row]
        
        // Customize the cell
        cell.displayInstruction(mealPlan[0])
        
        // Return the cell
        return cell

    }

InstructionCell 中,我不确定如何从我的 JSON 文件获取 instructions 数据。我试图像在 mealPlan 中所做的一样获取 MealPlanCell 数据,但为了深入研究,我尝试调用 mealPlan.instructions。似乎我没有正确获得“数组的数组”(例如 instructions 数组的 mealPlan 数组)。

  1. 如何使用适当的 instructions 集填充表视图。例如,我想在第一个 ViewController 中点击 mealPlan[0] 以在第二个 ViewController 中给我 mealPlan[0].instructions。现在我有一个从第一个 ViewController 中的 TableView 单元格导航到第二个 ViewController 的一般过渡。我似乎应该使用 func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath)获取一组特定的说明,但我并不完全确定。

非常感谢任何帮助!

解决方法

我相信你应该这样做。

在第一个 ViewController(有饭桌视图的那个)中,像这样添加 didSelectRowAtMethod

func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
    
    let selectedMeal = mealPlan[indexPath.row] //this the mealPlan you selected
    let detailVC = storyboard?.instantiateViewController(withIdentifier: "VCIdentifier") as! InstructionViewController
    detailVC.meal = selectedMeal
    present(detailVC,animated: true,completion: nil)
}

您的detailViewcontroller(显示说明的那个)应该看起来与餐点ViewController非常相似。您需要一个 tableView 来显示单元格中指令数组中的每条指令。

详细视图控制器代码:

class DetailViewController: UIViewController{

weak var meal: MealPlan?
@IBOutlet weak var tableView: UITableView!

override func ViewDidLoad(){
    super.ViewDidLoad()
    tableView.delegate = self
    tableView.datasource = self
 }

}

extension DetailViewController: UITableViewDelegate,UITableViewDataSource{

func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
    return meal.instructions.count
}

func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCell(withIdentifier: "CellID") as! InstructionCell
    cell.instruction = meal.instruction[indexPath.row]
    cell.displayInstruction()
    return cell
}

}

快到了!! 最后一件事。您只需要将单个指令传递给指令单元。 像这样编辑指令单元代码

class InstructionCell: UITableViewCell {

@IBOutlet weak var instructionLabel: UILabel!

var instruction: String?

func displayInstruction() {
    
    
    // Set the instructionLabel
    instructionLabel.text = instruction
    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。