Swift TableView 使用错误的索引路径转至新的 ViewController(倒数第二个选择)

Swift TableView segue to new ViewController with wrong index path (penultimate selection)

我有一个奇怪的问题。 我有两个 TableView,一个用于显示项目,一个用于显示所有团队成员。对于两个 TableView,我都有同样的错误。

当用户单击项目/团队成员时,我想显示它的详细信息。

奇怪的是,当 运行 应用程序和我 select 第一次成为项目/团队成员时,没有任何反应。当我然后 select 另一个时,它显示了前一个 selected 的细节。 我希望有人可以帮助我。

同样奇怪的是,条目 "Sarra Fezzani" 已从 Firebase 数据库中删除,应用程序是干净的构建,但它仍然显示了几次...

因为这两个代码非常相似,所以我只 post ProjetTableViewController 的代码,没有其他文件。

//
//  TeamViewController.swift
//  ProLabArtv2
//

import UIKit

class TeamViewController: UIViewController {


// MARK: - Properties


    @IBOutlet weak var memberTableView: UITableView!
    @IBOutlet weak var addTeamMember: UIButton!

    var members = [TeamMember]()
    var textToBeSent: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpElements()

        UserService.members(for: User.current) { (members) in
              self.members = members
              self.memberTableView.reloadData()
          }

    }

// MARK: - Element Style
    func setUpElements() {
         // Mark: Style the elements
        Utilities.addShadowtoButton(addTeamMember)
    }


    func configureTableView() {
        // remove separators for empty cells
        memberTableView.tableFooterView = UIView()
        // remove separators from cells
        memberTableView.separatorStyle = .none
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toMemberDetails" {
            let destVC = segue.destination as! TeamMemberDetailsViewController
            destVC.member = sender as? TeamMember
        }
    }
}


// MARK: - UITableViewDataSource

extension TeamViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {

        let member = members[indexPath.row]

        let cell = memberTableView.cellForRow(at: indexPath)

        print(members)

        performSegue(withIdentifier: "toMemberDetails", sender: member)
    }

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


//    func numberOfSections(in tableView: UITableView) -> Int {
//        return members.count
//    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       let member = members[indexPath.row]

            let cell = memberTableView.dequeueReusableCell(withIdentifier: "TeamMemberCell") as! TeamMemberCell
        cell.jobLabel.text = members[indexPath.row].memberJob
        cell.nameLabel.text = members[indexPath.row].memberName


            return cell
        }
    }


// MARK: - UITableViewDelegate

extension TeamViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
     return 80
    }
}

import UIKit

class TeamMemberCell: UITableViewCell {


// MARK: - Properties

    @IBOutlet weak var nameLabel: UILabel!
   @IBOutlet weak var jobLabel: UILabel!



static let height: CGFloat = 78

   override func awakeFromNib() {
       super.awakeFromNib()
       // Initialization code
   }

   override func setSelected(_ selected: Bool, animated: Bool) {
       super.setSelected(selected, animated: animated)

       // Configure the view for the selected state
   }

}

import Foundation
import UIKit
import FirebaseDatabase.FIRDataSnapshot




class TeamMember {

//      Next let's add properties to store all the additional information we need. Add the following to your post class.
    var key: String?
        let memberName: String
        let memberJob: String
        let memberLanguage: String
        let memberPrice: String
        let memberSpecification: String




//    You'll get some compiler errors for not having any initializers or default values for certain properties. Let's go ahead and fix that:

    init(memberName: String, memberJob: String, memberLanguage: String, memberPrice: String, memberSpecification: String) {
        self.memberName = memberName
        self.memberJob = memberJob
        self.memberLanguage = memberLanguage
        self.memberPrice = memberPrice
        self.memberSpecification = memberSpecification


    }

    var dictValue: [String : Any] {


        return ["memberName" : memberName,
                "memberJob" : memberJob,
                "memberLanguage" : memberLanguage,
                "memberPrice" : memberPrice,
                "memberSpecification" : memberSpecification]

    }
    init?(snapshot: DataSnapshot) {
        guard let dict = snapshot.value as? [String : Any],
            let memberName = dict["memberName"] as? String,
            let memberJob = dict["memberJob"] as? String,
            let memberLanguage = dict["memberLanguage"] as? String,
            let memberPrice = dict["memberPrice"] as? String,
            let memberSpecification = dict["memberSpecification"] as? String






            else { return nil }

        self.key = snapshot.key
        self.memberName = memberName
        self.memberJob = memberJob
        self.memberLanguage = memberLanguage
        self.memberPrice = memberPrice
        self.memberSpecification = memberSpecification

    }
}
import Foundation
import FirebaseAuth.FIRUser
import FirebaseDatabase
import FirebaseUI
import FirebaseAuth


struct UserService {


    static func members(for user: User, completion: @escaping ([TeamMember]) -> Void) {
        let ref = Database.database().reference().child("team").child(user.uid)

           ref.observeSingleEvent(of: .value, with: { (snapshot) in
               guard let snapshot = snapshot.children.allObjects as? [DataSnapshot] else {
                   return completion([])
               }

               let members = snapshot.reversed().compactMap(TeamMember.init)
               completion(members)
           })
       }

}

//
//  TeamMemberDetailsViewController.swift
//  ProLabArtv2
//
//  Created by Manu on 09.06.20.
//  Copyright © 2020 Manuel Knott. All rights reserved.
//

import UIKit
import FirebaseDatabase
import FirebaseAuth
import FirebaseStorage

class TeamMemberDetailsViewController: UIViewController {

// MARK: - Properties

    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var jobLabel: UILabel!
    @IBOutlet weak var specificationLabel: UILabel!
    @IBOutlet weak var languageLabel: UILabel!
    @IBOutlet weak var priceLabel: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!
    @IBOutlet weak var newScoreButton: UIButton!
    @IBOutlet weak var projectsPartButton: UIButton!


    var member: TeamMember?

    override func viewDidLoad() {
        super.viewDidLoad()

         setUI()

    }

    func setUI() {

        nameLabel.text = member?.memberName
        jobLabel.text = member?.memberJob
        specificationLabel.text = member?.memberSpecification
        languageLabel.text = member?.memberLanguage
        priceLabel.text = member?.memberPrice
//        scoreLabel.text = member?.
    }


}

这是 ProjectViewController 的那个,我在其中使用了 switch 语句...

//  HomeViewController.swift
//  ProLabArtv2
//

//

import UIKit
import Kingfisher
import Foundation
import FirebaseStorage
import FirebaseDatabase

class HomeViewController: UIViewController  {

    // MARK: - Properties

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var addProject: UIButton!


    var posts = [Post]()



    var textToBeSent: String = ""
    override func viewDidLoad() {
        super.viewDidLoad()

        UserService.posts(for: User.current) { (posts) in
            self.posts = posts
            self.tableView.reloadData()
        }

        Utilities.addShadowtoButton(addProject)

    }

    func configureTableView() {
        // remove separators for empty cells
        tableView.tableFooterView = UIView()
        // remove separators from cells
        tableView.separatorStyle = .none
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toDetails" {
            let destVC = segue.destination as! ShowProjectDetailsViewController
            destVC.post = sender as? Post
        }
    }

}

// MARK: - UITableViewDataSource

extension HomeViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        let post = posts[indexPath.row]
        performSegue(withIdentifier: "toDetails", sender: post)
    }

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

    func numberOfSections(in tableView: UITableView) -> Int {
        return posts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let post = posts[indexPath.section]

        switch indexPath.row {
        case 0:

            let cell = tableView.dequeueReusableCell(withIdentifier: "PostImageCell") as! PostImageCell
            let imageURL = URL(string: post.imageURL)
            cell.postImageView.kf.setImage(with: imageURL)

            return cell

        case 1:

            let cell = tableView.dequeueReusableCell(withIdentifier: "PostSubCell") as! PostSubCell
            cell.projectName.text = post.projectTitle



            return cell





        default:
            fatalError("Error: unexpected indexPath.")
        }
    }

}

// MARK: - UITableViewDelegate

extension HomeViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        switch indexPath.row {
        case 0:

           let post = posts[indexPath.section]
           return post.imageHeight

        case 1:

       return PostSubCell.height

        default:
            fatalError()
        }
    }
    }

希望有人能帮助我:)

这是我们在某些时候都犯过的错误之一,通常是因为没有仔细阅读自动完成。

您的密码是

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)

您使用的是 didDeselectRowAt 而不是 didSelectRowAt 方法。这意味着它会在该行失去焦点时运行它(当您单击另一行时)。

你需要

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        ...

您使用了错误的委托方法。在 selecting 而不是 deselecting a cell

上执行 segue
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let post = posts[indexPath.row]
    performSegue(withIdentifier: "toDetails", sender: post)
}