将数据(标签)从 TableViewCell 传递到另一个 ViewController
Pass Data (Label) from TableViewCell to another ViewController
我想在单击单元格时将标签从 TableViewCell 传递到 ViewController。最后它应该像 twitter 一样,如果您单击带有标签的单元格,您将获得具有相同标签初始化的 detailViewController。
我的代码不起作用,因为我只是从情节提要中获得了毯子标签...
import UIKit
import Firebase
class JobTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var valueToPass:String!
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
// Arvice return to count jobs
return jobs.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
let valueToPass = currentCell.textLabel?.text
print("value: \(valueToPass)")
performSegue(withIdentifier: "toDetails", sender: valueToPass)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "JobCell", for: indexPath) as! JobTableViewCell
let job = jobs[indexPath.row]
cell.job = job
//spacing
cell.contentView.backgroundColor = UIColor.clear
let whiteRoundedView : UIView = UIView(frame: CGRect(x: 10, y: 8, width: self.view.frame.size.width - 20, height: 120))
whiteRoundedView.layer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [0.36, 0.39, 0.40, 1.0])
whiteRoundedView.layer.masksToBounds = false
whiteRoundedView.layer.cornerRadius = 2.0
whiteRoundedView.layer.shadowOffset = CGSize(width: 0, height: 0)
whiteRoundedView.layer.shadowOpacity = 0.0
cell.contentView.addSubview(whiteRoundedView)
cell.contentView.sendSubview(toBack: whiteRoundedView)
cell.emojiLabel.text = cell.emojiString
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetails" {
let destinationViewController = segue.destination as! JobDetailViewController
destinationViewController.valueToPass = (sender as? String)!
}
}
我的手机:
import UIKit
import Firebase
class JobTableViewCell: UITableViewCell {
@IBOutlet weak var jobLabel: UILabel!
var job: Job! {
didSet {
jobLabel.text = job.text
}
}
}
Job.Swift:
import Foundation
import Firebase
class Job{
var text: String = ""
let ref: DatabaseReference!
init(text: String) {
self.text = text
ref = Database.database().reference().child("jobs").childByAutoId()
}
init(snapshot: DataSnapshot)
{
ref = snapshot.ref
if let value = snapshot.value as? [String : Any] {
text = value["text"] as! String
}
}
func save() {
ref.setValue(toDictionary())
}
func toDictionary() -> [String : Any]
{
return [
"text" : text,
]
}
}
在我的 DestinationController 中:
import UIKit
import Firebase
class JobDetailViewController: UIViewController {
@IBOutlet weak var jobDetail: RoundText!
var valueToPass: String = ""
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
jobDetail.text = valueToPass
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Jobinformation"
}
}
您不应该使用单元格来存储数据。您应该有一个数据模型来表示您在单元格中显示的数据,并且您应该使用所选单元格的 indexPath 来查找数据模型中的数据。
我会避免使用全局变量将数据传递到目标视图控制器。推迟查找,直到您准备好传递数据。
并且,避免使用强制展开,它会导致运行时崩溃。
改用这样的东西:
let segueIdentifier = "yourSegueIdentifer"
let labelDataSource: [String] = ["SomeText"]
func label(forIndexPath indexPath: IndexPath) -> String? {
let index = indexPath.row
guard labelDataSource.indices.contains(index) else { return nil }
return labelDataSource[index]
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: segueIdentifier, sender: indexPath)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard segue.identifier == segueIdentifier,
let indexPath = sender as? IndexPath,
let destinationViewController = segue.destination as? AnotherViewController else { return }
destinationViewController.valuePassed = label(forIndexPath: indexPath)
}
快速解决方案:
- 改变
performSegue(withIdentifier: "yourSegueIdentifer", sender: self)
到 performSegue(withIdentifier: "yourSegueIdentifer", sender: valueToPass)
2.Your 准备 Segue 方法应该如下所示:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourSegueIdentifer" {
let destinationViewController = segue.destination as! AnotherViewController
destinationViewController.valueToPass = sender as? String
}
}
- 在 AnotherViewController 上创建
var valuteToPass: String = ""
并设置你的 label.text = valueToPass
但我认为你不应该使用 currentCell.textLabel.text
值,而是使用原始值。 (比如如果您将 currentCell 设置为 cell.textLabel.cell = array[indexPath.row]
,您的 valueToPass 应该是 valueToPass = array[indexPath.row]
)
编辑:
您使用了 didDeselectRowAt 方法,而不是 didSelectRowAt。
将func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
改为
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
不要使用全局变量,在didSelectRowAt中创建。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
let valueToPass = currentCell.textLabel?.text
print("value: \(valuteToPass)")
performSegue(withIdentifier: "toDetails", sender: valueToPass)
}
On DestinationController:
class DestinationController: UIViewController {
var valuteToPass: String = ""
override func viewDidLoad() {
super.viewDidLoad()
jobLabel.text = valueToPass
}
}
EDIT2
JobTableViewController
- 删除
var valueToPass:String!
将let valueToPass = currentCell.textLabel?.text
改为let valueToPass = jobs[indexPath.row].text
我检查了您代码中的此更改,这将起作用。
嗨,我不能发表评论,但我正在使用@Dris 回答,我一直收到这个错误,上面写着
Could not cast value of type 'UITableViewCell' (0x115464e18) to 'NSString' (0x10fa594c8).
SIGABRT 目标行 destinationViewController.valueToPass = (sender as? String)!
这是为什么?
这基本上是我的代码
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Determine what to do when a cell in a particular section is selected.
print("did select: \(indexPath.row) ")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
valueToPass = currentCell.textLabel?.text
print("valueToPass: \(String(describing: valueToPass))")
performSegue(withIdentifier: "cellToView", sender: self)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if tableView == self.tableView {
let currentNotif = notificationList[indexPath.row]
cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell?.textLabel?.text = currentNotif.notifType
cell?.detailTextLabel?.text = "\(currentNotif.notifTime) \n\(currentNotif.notifContent)"
}
if tableView == self.tableViewAnnounce {
let currentAnnounce = announcementList[indexPath.row]
cell = tableView.dequeueReusableCell(withIdentifier: "cellAnn", for: indexPath) as UITableViewCell
cell?.textLabel?.text = currentAnnounce.annouceType
cell?.detailTextLabel?.text = "\(currentAnnounce.annouceTime) \n\(currentAnnounce.annouceContent)"
}
return cell!
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "cellToView" {
// perform custom segue operation.
let destinationViewController = segue.destination as! ExtendedAnnouncementViewController
destinationViewController.valueToPass = (sender as? String)!
}
}
我想在单击单元格时将标签从 TableViewCell 传递到 ViewController。最后它应该像 twitter 一样,如果您单击带有标签的单元格,您将获得具有相同标签初始化的 detailViewController。 我的代码不起作用,因为我只是从情节提要中获得了毯子标签...
import UIKit
import Firebase
class JobTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var valueToPass:String!
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
// Arvice return to count jobs
return jobs.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
let valueToPass = currentCell.textLabel?.text
print("value: \(valueToPass)")
performSegue(withIdentifier: "toDetails", sender: valueToPass)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "JobCell", for: indexPath) as! JobTableViewCell
let job = jobs[indexPath.row]
cell.job = job
//spacing
cell.contentView.backgroundColor = UIColor.clear
let whiteRoundedView : UIView = UIView(frame: CGRect(x: 10, y: 8, width: self.view.frame.size.width - 20, height: 120))
whiteRoundedView.layer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [0.36, 0.39, 0.40, 1.0])
whiteRoundedView.layer.masksToBounds = false
whiteRoundedView.layer.cornerRadius = 2.0
whiteRoundedView.layer.shadowOffset = CGSize(width: 0, height: 0)
whiteRoundedView.layer.shadowOpacity = 0.0
cell.contentView.addSubview(whiteRoundedView)
cell.contentView.sendSubview(toBack: whiteRoundedView)
cell.emojiLabel.text = cell.emojiString
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetails" {
let destinationViewController = segue.destination as! JobDetailViewController
destinationViewController.valueToPass = (sender as? String)!
}
}
我的手机:
import UIKit
import Firebase
class JobTableViewCell: UITableViewCell {
@IBOutlet weak var jobLabel: UILabel!
var job: Job! {
didSet {
jobLabel.text = job.text
}
}
}
Job.Swift:
import Foundation
import Firebase
class Job{
var text: String = ""
let ref: DatabaseReference!
init(text: String) {
self.text = text
ref = Database.database().reference().child("jobs").childByAutoId()
}
init(snapshot: DataSnapshot)
{
ref = snapshot.ref
if let value = snapshot.value as? [String : Any] {
text = value["text"] as! String
}
}
func save() {
ref.setValue(toDictionary())
}
func toDictionary() -> [String : Any]
{
return [
"text" : text,
]
}
}
在我的 DestinationController 中:
import UIKit
import Firebase
class JobDetailViewController: UIViewController {
@IBOutlet weak var jobDetail: RoundText!
var valueToPass: String = ""
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
jobDetail.text = valueToPass
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Jobinformation"
}
}
您不应该使用单元格来存储数据。您应该有一个数据模型来表示您在单元格中显示的数据,并且您应该使用所选单元格的 indexPath 来查找数据模型中的数据。
我会避免使用全局变量将数据传递到目标视图控制器。推迟查找,直到您准备好传递数据。
并且,避免使用强制展开,它会导致运行时崩溃。
改用这样的东西:
let segueIdentifier = "yourSegueIdentifer"
let labelDataSource: [String] = ["SomeText"]
func label(forIndexPath indexPath: IndexPath) -> String? {
let index = indexPath.row
guard labelDataSource.indices.contains(index) else { return nil }
return labelDataSource[index]
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: segueIdentifier, sender: indexPath)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard segue.identifier == segueIdentifier,
let indexPath = sender as? IndexPath,
let destinationViewController = segue.destination as? AnotherViewController else { return }
destinationViewController.valuePassed = label(forIndexPath: indexPath)
}
快速解决方案:
- 改变
performSegue(withIdentifier: "yourSegueIdentifer", sender: self)
到performSegue(withIdentifier: "yourSegueIdentifer", sender: valueToPass)
2.Your 准备 Segue 方法应该如下所示:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourSegueIdentifer" {
let destinationViewController = segue.destination as! AnotherViewController
destinationViewController.valueToPass = sender as? String
}
}
- 在 AnotherViewController 上创建
var valuteToPass: String = ""
并设置你的label.text = valueToPass
但我认为你不应该使用 currentCell.textLabel.text
值,而是使用原始值。 (比如如果您将 currentCell 设置为 cell.textLabel.cell = array[indexPath.row]
,您的 valueToPass 应该是 valueToPass = array[indexPath.row]
)
编辑:
您使用了 didDeselectRowAt 方法,而不是 didSelectRowAt。
将func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
改为
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
不要使用全局变量,在didSelectRowAt中创建。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
let valueToPass = currentCell.textLabel?.text
print("value: \(valuteToPass)")
performSegue(withIdentifier: "toDetails", sender: valueToPass)
}
On DestinationController:
class DestinationController: UIViewController {
var valuteToPass: String = ""
override func viewDidLoad() {
super.viewDidLoad()
jobLabel.text = valueToPass
}
}
EDIT2
JobTableViewController
- 删除
var valueToPass:String!
将let valueToPass = currentCell.textLabel?.text
改为let valueToPass = jobs[indexPath.row].text
我检查了您代码中的此更改,这将起作用。
嗨,我不能发表评论,但我正在使用@Dris 回答,我一直收到这个错误,上面写着
Could not cast value of type 'UITableViewCell' (0x115464e18) to 'NSString' (0x10fa594c8).
SIGABRT 目标行 destinationViewController.valueToPass = (sender as? String)!
这是为什么?
这基本上是我的代码
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Determine what to do when a cell in a particular section is selected.
print("did select: \(indexPath.row) ")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
valueToPass = currentCell.textLabel?.text
print("valueToPass: \(String(describing: valueToPass))")
performSegue(withIdentifier: "cellToView", sender: self)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if tableView == self.tableView {
let currentNotif = notificationList[indexPath.row]
cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell?.textLabel?.text = currentNotif.notifType
cell?.detailTextLabel?.text = "\(currentNotif.notifTime) \n\(currentNotif.notifContent)"
}
if tableView == self.tableViewAnnounce {
let currentAnnounce = announcementList[indexPath.row]
cell = tableView.dequeueReusableCell(withIdentifier: "cellAnn", for: indexPath) as UITableViewCell
cell?.textLabel?.text = currentAnnounce.annouceType
cell?.detailTextLabel?.text = "\(currentAnnounce.annouceTime) \n\(currentAnnounce.annouceContent)"
}
return cell!
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "cellToView" {
// perform custom segue operation.
let destinationViewController = segue.destination as! ExtendedAnnouncementViewController
destinationViewController.valueToPass = (sender as? String)!
}
}