【问题标题】:Passing Index of a selected row to another ViewController将选定行的索引传递给另一个 ViewController
【发布时间】:2021-05-09 06:19:35
【问题描述】:

我有一个关于将索引 (myIndex) 从 TableView 传递到另一个 ViewController 的问题。 我已经发布了下面的代码。好消息:当我运行代码时,一个索引被传递给另一个 Viewcontroller。坏消息:这不是我预期的指数。 (当我在 Viewcontroller 中使用 TableView 打印出 myindex 时,一切正常。如果我将 myIndex 传递给另一个 ViewController,则索引会混淆...

目标:我的 TableView 包含 18 行(每个孔一行)。当我单击一行时,将打开另一个 Viewcontroller。在此 VieController 中,所选行的名称应显示在顶部。 我的想法是将每一行的索引传递给另一个 Viewcontroller,但这不能正常工作。

谁能帮帮我?

import UIKit
var holes = ["Hole 1","Hole 2","Hole 3","Hole 4","Hole 5","Hole 6","Hole 7","Hole 8", "Hole 9","Hole 10","Hole 11","Hole 12","Hole 13","Hole 14","Hole 15","Hole 16","Hole 17","Hole 18"]
var myIndex = 0

class OverViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    // Label
    @IBOutlet weak var BackButton: UIButton!
    @IBOutlet weak var ScoreButton: UIButton!
    @IBOutlet weak var OverviewLabel: UILabel!
    

    @IBOutlet weak var tableView: UITableView!
    

    override func viewDidLoad() {
           super.viewDidLoad()
    }
    
    
    @IBAction func BackToStartScreen(_ sender: UIButton) {
        performSegue(withIdentifier: "BackToStart", sender: self)
    }
    
    @IBAction func GoToResultScreen(_ sender: UIButton) {
        performSegue(withIdentifier: "GoToResult", sender: self)
    }
    
        
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return holes.count
    }
        
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = holes[indexPath.row]
            return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        myIndex = indexPath.row
        performSegue(withIdentifier: "GoToScore", sender: self)
        
    }
  
}

还有 ScoreViewController:

import UIKit



class ScoreViewController: UIViewController {
    var score = 0
    var fairwayhits = 0
    var greeninregulation = 0
    var putts = 0
    var text = ""
        
    // Variable Deklaration
    var CurrentScore = 0
    var CurrentFairwayHits = 0
    var CurrentGreenInRegulations = 0
    var CurrentPutts = 0

    
    
    // Bar Label
    @IBOutlet weak var BackLabel: UIButton!
    @IBOutlet weak var TitleLabel: UILabel!
    
    // Score Elements
    @IBOutlet var ScoreLabel: UILabel!
    @IBOutlet var ScoreStepper: UIStepper!
    @IBOutlet var ScoreResultLabel: UILabel!
    @IBOutlet var ScoreFrameLabel: UILabel!
    
    // Fairway Elements
    @IBOutlet var FairwayLabel: UILabel!
    @IBOutlet var FairwaySwitch: UISwitch!
    @IBOutlet var FairwayResultLabel: UILabel!
    @IBOutlet var FairwayFrameLabel: UILabel!
    
    // Green Elements
    @IBOutlet var GreenLabel: UILabel!
    @IBOutlet var GreenSwitch: UISwitch!
    @IBOutlet var GreenResultLabel: UILabel!
    @IBOutlet var GreenFrameLabel: UILabel!
    
    // Putt Elements
    @IBOutlet var PuttLabel: UILabel!
    @IBOutlet var PuttStepper: UIStepper!
    @IBOutlet var PuttResultLabel: UILabel!
    @IBOutlet var PuttFrameLabel: UILabel!
    
    // Save Button
    @IBOutlet var SaveButton: UIButton!
    
    // Back Button
    @IBAction func BackButtonPressed(_ sender: UIButton) {
        performSegue(withIdentifier: "BackToOverview", sender: self)
    }
    
    // Score Stepper
    @IBAction func ScoreStepperPressed(_ sender: UIStepper) {
        ScoreResultLabel.text = Int(sender.value).description
    }
    
    // Fairway Switch
    @IBAction func FairwaySwitchPressed(_ sender: UISwitch) {
        if FairwaySwitch.isOn {
            CurrentFairwayHits = 1
            FairwayResultLabel.text = "X"
        } else {
            CurrentFairwayHits = 0
            FairwayResultLabel.text = "-"
        }
    }
    
    // Green Switch
    @IBAction func GreenSwitchPressed(_ sender: UISwitch) {
        if GreenSwitch.isOn {
            CurrentGreenInRegulations = 1
            GreenResultLabel.text = "X"
        } else {
            CurrentGreenInRegulations = 0
            GreenResultLabel.text = "-"
        }
    }
    

    // Putt Stepper
    @IBAction func PuttStepperPressed(_ sender: UIStepper) {
        PuttResultLabel.text = Int(sender.value).description
    }
    
    
    // Save Button
    @IBAction func SaveButtonPressed(_ sender: UIButton) {
        if Int(PuttResultLabel.text!)! >= Int(ScoreResultLabel.text!)! {
            showAlert()
        } else {
        score = score + Int(ScoreResultLabel.text!)!
        fairwayhits = fairwayhits + CurrentFairwayHits
        greeninregulation = greeninregulation + CurrentGreenInRegulations
        putts = putts + Int(PuttResultLabel.text!)!
        
        print(score)
        print(fairwayhits)
        print(greeninregulation)
        print(putts)
            
        performSegue(withIdentifier: "ShowResult", sender: self)
        }
    }
    
    
    func showAlert() {
        let alert = UIAlertController(title: "Ops, something went wrong", message: "The number of putts must be smaller than your score!", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: { action in print("tapped Dismissed")}))
        
        present(alert, animated: true)
    }

    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if SaveButton.isTouchInside,
           let resultVC = segue.destination as? ResultViewController
            {

            CurrentScore = score /// get the current cell's text
            CurrentPutts = putts
            resultVC.score = resultVC.score + String((resultVC.ScoreResultLabel.text!))
            resultVC.fairway = String(fairwayhits)
            resultVC.green = String(greeninregulation)
            resultVC.putt = String(putts)
            
            
               }
    }
    
    

    override func viewDidLoad() {
        
        super.viewDidLoad()

        ScoreStepper.wraps = true
        ScoreStepper.autorepeat = true
        ScoreStepper.minimumValue = 1
        ScoreStepper.maximumValue = 20
        
        PuttStepper.wraps = true
        PuttStepper.autorepeat = true
        PuttStepper.minimumValue = 0
        PuttStepper.maximumValue = 20
        

        TitleLabel.text = text
    
    }
}

结果视图控制器:



class ResultViewController: UIViewController {
    
    var score = ""
    var fairway = ""
    var green = ""
    var putt = ""
    

    @IBOutlet weak var TitleLabel: UILabel!
    @IBOutlet weak var BackButton: UIButton!
    @IBOutlet weak var ShareButton: UIButton!
    
    // Score Label
    @IBOutlet weak var ScoreLabel: UILabel!
    @IBOutlet weak var ScoreResultLabel: UILabel!
    @IBOutlet weak var ScoreFrameLabel: UILabel!
    
    // Fairway Label
    @IBOutlet weak var FairwayLabel: UILabel!
    @IBOutlet weak var FairwayResultLabel: UILabel!
    @IBOutlet weak var FairwayFrameLabel: UILabel!
    
    // Green Label
    @IBOutlet weak var GreenLabel: UILabel!
    @IBOutlet weak var GreenResultLabel: UILabel!
    @IBOutlet weak var GreenFrameLabel: UILabel!
    
    // Putt Label
    @IBOutlet weak var PuttLabel: UILabel!
    @IBOutlet weak var PuttResultLabel: UILabel!
    @IBOutlet weak var PuttFrameLabel: UILabel!
    
    // Back Button Action
    @IBAction func BackButtonPressed(_ sender: UIButton) {
        performSegue(withIdentifier: "BackToOverview", sender: self)
        
    }


        
    override func viewDidLoad() {
        super.viewDidLoad()

        ScoreResultLabel.text = "\(score)"
        FairwayResultLabel.text = "\(fairway)"
        GreenResultLabel.text  = "\(green)"
        PuttResultLabel.text = "\(putt)"
        
        
    }
    

 

}

【问题讨论】:

  • 保留您的var holesvar myIndex = 0 inside OverViewController。
  • 然后在您的另一个视图控制器中,有一个var text 并将其设置在prepare(for:sender:) 中,类似于if let nextViewController = segue.destination as? NextViewController { nextViewController.text = holes[myIndex] }
  • 你能详细解释一下你的建议吗?
  • 当然。你能发布你的 ScoreViewController/你正在打开的视图控制器的代码吗?
  • 好了,上面的ScoreViewController的代码我贴出来了。

标签: swift xcode indexpath


【解决方案1】:

第一件事:你不想在类之外有变量。当然,您可以从所有课程中访问它们。但是,这不是好的做法,您会遇到状态错误。

所以,替换

var holes = ["Hole 1","Hole 2","Hole 3","Hole 4","Hole 5","Hole 6","Hole 7","Hole 8", "Hole 9","Hole 10","Hole 11","Hole 12","Hole 13","Hole 14","Hole 15","Hole 16","Hole 17","Hole 18"]
var myIndex = 0

class OverViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

class OverViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var holes = ["Hole 1","Hole 2","Hole 3","Hole 4","Hole 5","Hole 6","Hole 7","Hole 8", "Hole 9","Hole 10","Hole 11","Hole 12","Hole 13","Hole 14","Hole 15","Hole 16","Hole 17","Hole 18"]
    var myIndex = 0

还有替换

var score = 0
var fairwayhits = 0
var greeninregulation = 0
var putts = 0

var text = ""

class ScoreViewController: UIViewController {

class ScoreViewController: UIViewController {
    var score = 0
    var fairwayhits = 0
    var greeninregulation = 0
    var putts = 0

    var text = ""

现在,我假设您想要这种行为:

  1. 在表格视图中按一个单元格
  2. 现在ScoreViewController 显示单元格的文本

你可以把它放在你的prepareForSegue func:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let selectedPath = tableView.indexPathForSelectedRow else { return }
    if 
        segue.identifier == "GoToScore",
        let scoreVC = segue.destination as? ScoreViewController
    {
        let currentText = holes[selectedPath.row] /// get the current cell's text
        scoreVC.text = currentText
    }
}

编辑:然后您可以将TitleLabel.text 设置为text 内的viewDidLoad 属性,如下所示:

class ScoreViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        TitleLabel.text = text /// right here!
    }   
}

您还应该将所有属性(包括TitleLabel 等插座)保持小写。这只是一种让其他人更容易阅读您的代码的约定。

@IBOutlet weak var backLabel: UIButton!
@IBOutlet weak var titleLabel: UILabel!

请记住,要更改出口的名称,您需要断开链接并从情节提要中重新链接。

【讨论】:

  • 好的,感谢您到目前为止的代码更正!最后一个问题,你能告诉我,我可以在代码中的哪个位置将“TitleLabel”(ScoreViewController) 的输出更改为 OverViewController 的选定行?
  • 完美运行!谢谢!在我的原始代码中,我将每个洞的得分、球道、果岭和推杆的值相加(就像一个计数器)。我将值存储在全局变量中。现在我没有任何全局变量了。如何在 func prepare 语句中使用计数器功能?
  • 你可以做scoreVC.score = scoreVC.score + Int(scoreVC.ScoreResultLabel.text!)!
  • 当我添加您的代码时,在您的代码建议行中出现“Unexpectedly found nil...”错误:“scoreVC.score = scoreVC.score + Int(scoreVC.ScoreResultLabel.text !)!”我该如何解决它。
  • 对不起,我忘了。那是因为 ScoreResultLabel 当时仍然为零。您应该只在 ScoreViewController 中执行计数器功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多