Swift TableView segue to new ViewController with wrong index path (倒数第二个选择)
Posted
技术标签:
【中文标题】Swift TableView segue to new ViewController with wrong index path (倒数第二个选择)【英文标题】:Swift TableView segue to new ViewController with wrong index path (penultimate selection) 【发布时间】:2020-06-09 16:13:27 【问题描述】:我有一个奇怪的问题。 我有两个 TableView,一个用于显示项目,一个用于显示所有团队成员。对于这两个 TableView,我有相同的错误。
当用户单击项目/团队成员时,我想显示它的详细信息。
奇怪的是,当我第一次运行应用程序并选择一个项目/团队成员时,什么都没有发生。然后当我选择另一个时,它会显示前一个选择的详细信息。 我希望有人可以帮助我。
还有一件奇怪的事情是,条目“Sarra Fezzani”已从 Firebase 数据库中删除,应用程序是干净构建的,但它仍然显示了好几次...
由于这两个代码非常相似,我将只发布 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()
希望有人可以帮助我:)
【问题讨论】:
【参考方案1】:这是我们都曾在某些时候犯过的错误之一,通常是由于没有仔细阅读自动完成。
你的代码是
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
您使用的是didDeselectRowAt
而不是didSelectRowAt
方法。这意味着它会在该行失去焦点时运行它(即当您单击另一行时)。
你需要
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
...
【讨论】:
【参考方案2】:您使用了错误的委托方法。在选择而不是de选择一个单元格
上执行seguefunc tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let post = posts[indexPath.row]
performSegue(withIdentifier: "toDetails", sender: post)
【讨论】:
谢谢大家!真的帮了我很多:)以上是关于Swift TableView segue to new ViewController with wrong index path (倒数第二个选择)的主要内容,如果未能解决你的问题,请参考以下文章
TableView 单元格,滑动操作和不同的 segues Swift 4
Swift 3 TableView Segue 到多个其他 TableViews
没有情节提要的 TableView Cell 的 iOS Swift Segue
使用动态tableView的tableViewCell中的动态collectionViewCell执行Segue With Identifier,swift