Передать данные (метку) из TableViewCell в другой ViewController

Я хочу передать метку из TableViewCell в ViewController, когда я нажимаю на ячейку. В конце концов, это должно быть похоже на твиттер: если вы щелкнете по ячейке с меткой, вы получите элемент 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"
}
}

3 ответа

Решение

Быстрое решение:

  1. + Изменить performSegue(withIdentifier: "yourSegueIdentifer", sender: self) в performSegue(withIdentifier: "yourSegueIdentifer", sender: valueToPass)

2. Ваша подготовка к Segue метод должен выглядеть следующим образом:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     if segue.identifier == "yourSegueIdentifer" {
         let destinationViewController = segue.destination as!   AnotherViewController
             destinationViewController.valueToPass = sender as? String
    }
}
  1. На 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)
}

На DestinationController:

class DestinationController: UIViewController {

var valuteToPass: String = ""

  override func viewDidLoad() {
    super.viewDidLoad()
   jobLabel.text = valueToPass
   }

}

EDIT2

JobTableViewController

  1. удалять var valueToPass:String!

+ Изменить let valueToPass = jobs[indexPath.row].text вместо let valueToPass = currentCell.textLabel?.textЯ проверил это изменение в вашем коде, это будет работать.

Вы не должны использовать ячейки для хранения данных. У вас должна быть модель данных, представляющая данные, которые вы показываете в ячейках, и вы должны использовать indexPath выбранной ячейки для поиска данных в вашей модели данных.

Привет, я не могу комментировать, но я использую ответ @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)!
        }
    }

Я бы не использовал глобальную переменную для передачи данных в контроллер представления назначения. Отложите поиск, пока не будете готовы передать данные.

И избегайте принудительного развертывания, это приводит к сбоям во время выполнения.

Вместо этого используйте что-то вроде этого:

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)
}
Другие вопросы по тегам