Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
200 views
in Technique[技术] by (71.8m points)

swift - Passing Index of a selected row to another ViewController

I have a question concerning the passing of an index (myIndex) from a TableView to another ViewController. I have posted the code below. The good news: When I run the code, an Index is passed to the other Viewcontroller. The bad news: it is not the index I expected. (When I print out myindex in the Viewcontroller with TableView, everything works fine. If I pass myIndex to another ViewController, the index is mixed up...

Target: My TableView consists of 18 rows (each hole a row). When I click on a row, another Viewcontroller will open up. In this VieController, the name of the selected row should be displayed on top. My idea was to pass the index of each row to the other Viewcontroller but that is not working correctly.

Can anybody help me out?

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)
        
    }
  
}

And the 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
    
    }
}

And the Result view Controller:



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)"
        
        
    }
    

 

}
question from:https://stackoverflow.com/questions/66054268/passing-index-of-a-selected-row-to-another-viewcontroller

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First thing: You don't want to have variables outside of classes. Sure, you are able to access them from all your classes. But, this is not good practice, and you will run into state errors.

So, replace

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 {

with

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

And also replace

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

var text = ""

class ScoreViewController: UIViewController {

with

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

    var text = ""

Now, I assume you want this behavior:

  1. Press a cell on the table view
  2. Present ScoreViewController that shows the cell's text

You can put this in your 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
    }
}

Edit: You can then set the TitleLabel.text to the text property inside viewDidLoad, like this:

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

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

You should also keep all properties, including outlets like TitleLabel, lowercased. It's just a convention that makes it easier for other people to read your code.

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

Keep in mind that to change the name of an outlet, you need to break the link and re-link it again from the storyboard.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...