如何从UITableView数据(UIImage和String)中提取到另一个ViewController

时间:2018-04-25 02:42:02

标签: ios swift uitableview swift4 xcode9

我想传递TableView中包含的存储数据并将其传递给另一个ViewController。我的customCell有一个UIImage和一个String。 当用户按下单元格时,我想显示一个"详细视图控制器"使用UIImage和包含所选单元格信息的标签。

这是我的代码:

import UIKit


class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var dataTableView: UITableView!

var myList = [dataList]()

var textToBeSent: String = ""

var selectedImage: UIImage?
var selectedLabel: String?

//Load Items To List

func loaditems(){
    let item1 = dataList(photoList: UIImage.self(), itemDescription: "Descripcion Aqui")
    let item2 = dataList(photoList: UIImage.self(), itemDescription: "Aqui tmb")

    myList += [item1,item2]
}

//var list = ["Documento 1", "Documento 2", "Documento 3"]

override func viewDidLoad() {
    super.viewDidLoad()

    if let savedData = loadSavedItems(){
        myList += savedData
    } else {

    loaditems()
    }


    //dataTableView.register(UITableViewCell.self, forCellReuseIdentifier: "reusablecell")


    // Do any additional setup after loading the view, typically from a nib.
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "prototype", for: indexPath) as! PrototypeCell

    let itemsinCell = myList[indexPath.row]

    cell.imageItem.image = itemsinCell.photoList
    cell.itemDescription.text = String(itemsinCell.itemDescription)

    return cell
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete{
        myList.remove(at: indexPath.row)
        dataTableView.reloadData()
    }

    saveToSavedData()
}

这是我要传递某个单元格数据的函数。 数据来自存储在" DataList"中的Swift文件。使用aDecoder NSCoder。

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


    print("Row \(indexPath.row) selected")
    selectedImage! = myList[indexPath.row].photoList
    selectedLabel! = myList[indexPath.row].itemdescription
    performSegue(withIdentifier: "selectedRowSegue", sender: myList[indexPath.row])
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if(segue.identifier == "selectedRowSegue"){
        let chosenRowViewController = segue.destination as! chosenRowViewController
        chosenRowViewController.image3 = selectedImage?.photoList
        chosenRowViewController.label3 = selectedLabel?.itemDescription
    }
}

展开segue以使用之前的数据填充单元格 的ViewController:

//Unwinde Segue
@IBAction func unWindlToList(sender: UIStoryboardSegue){
    if let sourceViewController = sender.source as? ProcessViewController, let item = sourceViewController.item{
        let newIndexPath = IndexPath(row: myList.count, section: 0)
        myList.append(item)
        dataTableView.insertRows(at: [newIndexPath], with: .automatic)
    }
    saveToSavedData()
}
//Archive Data
func saveToSavedData(){
    NSKeyedArchiver.archiveRootObject(myList, toFile: (dataList.fileFolder?.path)!)
}
//Unarchive Data
func loadSavedItems() -> [dataList]?{
    return NSKeyedUnarchiver.unarchiveObject(withFile: (dataList.fileFolder?.path)!) as? [dataList]
}

}

class PrototypeCell: UITableViewCell {

    @IBOutlet weak var itemDescription: UILabel!

    @IBOutlet weak var imageItem: UIImageView!

}

3 个答案:

答案 0 :(得分:1)

您在didSelectRowAt中犯了一个错误,在调用performSegue时,您必须通过sender控制器,在您的情况下,它是您当前的UIVIewController ,所以你必须写self作为发送者控制者。所以你纠正的方法看起来就像下面的代码片段一样:

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


    print("Row \(indexPath.row) selected")
    selectedImage! = myList[indexPath.row].photoList
    selectedLabel! = myList[indexPath.row]
    performSegue(withIdentifier: "selectedRowSegue", sender: self)
}

答案 1 :(得分:1)

只需使用以下代码替换prepare(for segue: UIStoryboardSegue, sender: Any?)函数

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if(segue.identifier == "selectedRowSegue"), let list = sender as? dataList {
            let chosenRowViewController = segue.destination as! chosenRowViewController
            chosenRowViewController.image3 = list.photoList
            chosenRowViewController.label3 = list.itemDescription 
        }
    }

答案 2 :(得分:0)

有几件事情很突出。

1- var myList = [dataList]() dataList是Class,类应该大写。它应该是var myList = [DataList]()

2-你有这个作为一个类属性,但它没有在你发布的代码中的任何地方使用,所以你为什么要添加它以及它的目的是什么? var textToBeSent: String = ""

3-您有这两个类属性变量

var selectedImage: UIImage?
var selectedLabel: String?

保留[myList]的数据,但您确实不需要它们,因为您只能使用[myList]内的dot notation访问prepareForSegue中的数据(阅读评论)在prepareForSegue中输出代码。

4-在prepareForSegue中,你有let chosenRowViewController = segue.destination as! chosenRowViewController。 ChosenRowViewController是一个类,它应该像这样大写:

let chosenRowViewController = segue.destination as! ChosenRowViewController // it's capitalized after the as!

这里的代码有点清理。

@IBOutlet weak var dataTableView: UITableView!

var myList = [DataList]()

func loaditems(){
    let item1 = dataList(photoList: UIImage.self(), itemDescription: "Descripcion Aqui")
    let item2 = dataList(photoList: UIImage.self(), itemDescription: "Aqui tmb")

    myList.append(item1)
    myList.append(item2)
}

override func viewDidLoad() {
    super.viewDidLoad()
    // everything you already have inside here...
}

// your tableView datasource methods...

5-由于您使用prepareForSegue,因此不需要didSelectRowAt indexPath

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if(segue.identifier == "selectedRowSegue"){

        // get the indexPath for the selectedRow
        let indexPath = tableView.indexPathForSelectedRow

        let chosenRowViewController = segue.destination as! ChosenRowViewController
        chosenRowViewController.image3 = myList[indexPath!.row].photoList // use dot notation to access the photoList property
        chosenRowViewController.label3 = myList[indexPath!.row].itemDescription  // use dot notation to access the itemDescription property
    }
}