Как извлечь из данных UITableView (UIImage и String) в другой ViewController - PullRequest
0 голосов
/ 25 апреля 2018

Я хочу передать данные хранилища, содержащиеся в TableView, и передать их другому ViewController.Мой customCell имеет UIImage и строку.Когда пользователь нажимает на ячейку, я хочу показать «контроллер подробного представления» с 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()
}

Вот функция, в которую я хочу передать данные определенной ячейки.Данные взяты из файла Swift, хранящегося в «Списке данных» с использованием декодера 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
    }
}

Разверните последовательность, чтобы заполнить ячейки данными из предыдущего 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 голосов
/ 25 апреля 2018

просто замените 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 
        }
    }
0 голосов
/ 26 апреля 2018

Есть несколько вещей, которые выделяются.

1- var myList = [dataList]() dataList - это Class, классы должны начинаться с заглавной буквы.Это должно быть var myList = [DataList]()

2 - это свойство класса, но оно не используется нигде в опубликованном вами коде, так почему вы добавили его и какова его цель?var textToBeSent: String = ""

3- У вас есть эти 2 переменные свойства класса

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
    }
}
0 голосов
/ 25 апреля 2018

Вы допустили ошибку в вашем 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)
}
...