Swift - перезагрузка TableViewCell внутри CollectionViewCell - PullRequest
0 голосов
/ 19 февраля 2020

Я пытался viewWillAppear, tableView.reloadData() и collectionView.reloadData(), но массив данных, кажется, никогда не появляется

import UIKit

class yearOne: UICollectionViewController, coursesDelegate {

    let customCellIdentifier = "cellID"
    let customCellIdentifier2 = "cellID2"
    let customCellIdentifier3 = "cellID3"
    let customCellIdentifier4 = "cellID4"

    let quarters = [
        customLabel (title: "Fall Quarter"),
        customLabel (title: "Winter Quarter"),
        customLabel (title: "Spring Quarter"),
        customLabel (title: "Summer Quarter")
    ]


    func sendDataBackFall(data: String) {
        fallQuarterCell.data.append(data)
        //UserDefaults.standard.set(fallQuarterCell.data, forKey: "SavedArray")
    }
    func sendDataBackWinter(data2: String) {
        winterQuarterCell.data.append(data2)
        //UserDefaults.standard.set(winterQuarterCell.data, forKey: "SavedArray")
    }
    func sendDataBackSpring(data3: String) {
        springQuarterCell.data.append(data3)
        //UserDefaults.standard.set(springQuarterCell.data, forKey: "SavedArray")
    }
    func sendDataBackSummer(data4: String) {
        summerQuarterCell.data.append(data4)
        //UserDefaults.standard.set(summerQuarterCell.data, forKey: "SavedArray")
    }

    let vc = fallQuarterCell()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("1")
        print(fallQuarterCell.data)
        vc.tableView.reloadData()
        collectionView.reloadData()
        print("2")
        print(fallQuarterCell.data)
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.dataSource = self
        collectionView.delegate = self

        self.collectionView!.register(fallQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier)
        self.collectionView!.register(winterQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier2)
        self.collectionView!.register(springQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier3)
        self.collectionView!.register(summerQuarterCell.self, forCellWithReuseIdentifier: customCellIdentifier4)

        navigationItem.title = "Year One"
        navigationController?.navigationBar.prefersLargeTitles = true
        collectionView?.backgroundColor = .lightGray
        //navigationItem.prompt = "Click the + button to add courses, Swipe left on a course to delete."

    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return quarters.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if (indexPath.row == 0){
            let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier, for: indexPath) as! fallQuarterCell
            cell1.layer.borderColor = UIColor.orange.cgColor
            cell1.layer.borderWidth = 2
            cell1.layer.cornerRadius = 5
            cell1.quarters = self.quarters[0]
            return cell1
        }
        else if (indexPath.row == 1){
            let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier2, for: indexPath) as! winterQuarterCell
            cell2.layer.borderColor = UIColor.blue.cgColor
            cell2.layer.borderWidth = 2
            cell2.layer.cornerRadius = 5
            cell2.quarters = self.quarters[1]
            return cell2
        }
        else if (indexPath.row == 2){
            let cell3 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier3, for: indexPath) as! springQuarterCell
            cell3.layer.borderColor = UIColor.green.cgColor
            cell3.layer.borderWidth = 2
            cell3.layer.cornerRadius = 5
            cell3.quarters = self.quarters[2]
            return cell3
        }
        else if (indexPath.row == 3){
            let cell4 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier4, for: indexPath) as! summerQuarterCell
            cell4.layer.borderColor = UIColor.red.cgColor
            cell4.layer.borderWidth = 2
            cell4.layer.cornerRadius = 5
            cell4.quarters = self.quarters[3]
            return cell4
        }
        else{
            return UICollectionViewCell()
        }
    }

    @objc func buttonAction(sender: UIButton!) {
        switch sender.tag {
        case 0:
            let destination = SearchPage()
            destination.delegate = self
            destination.tag = sender.tag
            navigationController?.pushViewController(destination, animated: true)
        case 1:
            let destination = SearchPage()
            destination.delegate = self
            destination.tag = sender.tag
            navigationController?.pushViewController(destination, animated: true)
        case 2:
            let destination = SearchPage()
            destination.delegate = self
            destination.tag = sender.tag
            navigationController?.pushViewController(destination, animated: true)
        case 3:
            let destination = SearchPage()
            destination.delegate = self
            destination.tag = sender.tag
            navigationController?.pushViewController(destination, animated: true)
        default:
            let destination = SearchPage()
            destination.delegate = self
            destination.tag = sender.tag
            navigationController?.pushViewController(destination, animated: true)
        }

    }
}

extension yearOne : UICollectionViewDelegateFlowLayout{

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = (view.frame.width - 30)
        return CGSize(width: width, height: 200)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 8
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        UIEdgeInsets(top: 30, left: 10, bottom: 30, right: 10)
    }

}


class fallQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {

//    var data = UserDefaults.standard.object(forKey: "SavedArray") as? [String] ?? [String](){
//        didSet{
//            self.tableView.reloadData()
//        }
//    }

    static var data: [String] = []

//    func load(){
//        if let loadeddata: [String] = UserDefaults.standard.object(forKey: "SavedArray") as? [String] {
//            data = loadeddata
//            tableView.reloadData()
//        }
//    }

    let cellId = "coursesName"

    let tableView:UITableView = {
        let tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.backgroundColor = UIColor.white
        return tableView
    }()

    override init(frame: CGRect){
        super.init(frame: frame)
        addSubview(tableView)
        setupView()
    }

    func setupView(){

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
        tableView.delegate = self
        tableView.dataSource = self

        self.backgroundColor = UIColor.white
        contentView.addSubview(quarterLabel)
        contentView.addSubview(addButton)

        quarterLabel.translatesAutoresizingMaskIntoConstraints = false
        quarterLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
        quarterLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true

        addButton.translatesAutoresizingMaskIntoConstraints = false
        addButton.topAnchor.constraint(equalTo: quarterLabel.topAnchor, constant: -5).isActive = true
        addButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
        addButton.heightAnchor.constraint(equalToConstant: 25).isActive = true
        addButton.widthAnchor.constraint(equalToConstant: 25).isActive = true

        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 35).isActive = true
        tableView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5).isActive = true
        tableView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
        tableView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true

    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
        let stringLabel = fallQuarterCell.data[indexPath.row]
        cell.textLabel?.text = stringLabel
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 40
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == .delete) {
            if (indexPath.row == 0){
                fallQuarterCell.data.remove(at: 0)
                self.tableView.reloadData()
                //UserDefaults.standard.set(fallQuarterCell.data, forKey: "SavedArray")
            }
            else if (indexPath.row == 1){
                fallQuarterCell.data.remove(at: 1)
                self.tableView.reloadData()
                //UserDefaults.standard.set(fallQuarterCell.data, forKey: "SavedArray")
            }
            else if (indexPath.row == 2){
                fallQuarterCell.data.remove(at: 2)
                self.tableView.reloadData()
                //UserDefaults.standard.set(fallQuarterCell.data, forKey: "SavedArray")
            }
            else if (indexPath.row == 3){
                fallQuarterCell.data.remove(at: 3)
                self.tableView.reloadData()
                //UserDefaults.standard.set(fallQuarterCell.data, forKey: "SavedArray")
            }
            else if (indexPath.row == 4){
                fallQuarterCell.data.remove(at: 4)
                self.tableView.reloadData()
                //UserDefaults.standard.set(fallQuarterCell.data, forKey: "SavedArray")
            }
        }
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        //add class information???
    }

    var quarters: customLabel? {
        didSet {
            guard let quarters = quarters else {return}
            quarterLabel.text = quarters.title
        }
    }

    let quarterLabel : UILabel = {
        let label = UILabel()//frame: CGRect(x: 15, y: -75, width: 300, height: 50))
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor.black
        label.font = UIFont.boldSystemFont(ofSize: 16)
        //label.textAlignment = .center
        return label
    }()

    let addButton : UIButton = {
        let button = UIButton()//frame: CGRect(x: 345, y: 10, width: 30, height: 30))
        button.setImage(UIImage(named: "addicon"), for: .normal)
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        button.tag = 0
        button.addTarget(self, action: #selector(yearOne.buttonAction), for: .touchUpInside)
        return button
    }()


    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

У меня также есть

class winterQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource

class springQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource

class summerQuarterCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource

аналогично fallQuarterCell(). Я использовал print(fallQuarterCell.data), чтобы увидеть, работает ли делегирование и добавляется ли строка данных, и, кажется, она добавляется в массив, просто она не будет отображаться в tableQ fallQuarterCell при выходе из SearchPage()

Вот 'SearchPage () where the user clicks on an element from the tableView to append to the fallQuarterCell.data through delegation and automatically pop backs to yearOne () `:

import UIKit

protocol coursesDelegate {
    func sendDataBackFall(data: String)
    func sendDataBackWinter(data2: String)
    func sendDataBackSpring(data3: String)
    func sendDataBackSummer(data4: String)
}

class SearchPage: UITableViewController {

    var delegate: coursesDelegate?

    let cellId = "course"

    var allCourses : NSArray = NSArray()
    var filteredCourses = [String]()
    var resultSearchController = UISearchController()

    var tag: Int?

    @objc func addTapped(sender: UIBarButtonItem!) {
        let addAlert = UIAlertController(title: "Create New Course", message: "Enter a course name", preferredStyle: .alert)

        addAlert.addTextField {(textfield:UITextField) in textfield.placeholder = "Course"}

        addAlert.addAction(UIAlertAction(title: "Create", style: .default, handler: { (action:UIAlertAction) in
            var _customCourse = String()

            if let courseTextField = addAlert.textFields?.first, let customCourse = courseTextField.text{
                _customCourse = customCourse
            }

        }))

        addAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

        self.present(addAlert, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let courses : CourseList = CourseList()
        allCourses = courses.coursesList

        navigationItem.title = "Select Courses"
        navigationController?.navigationBar.prefersLargeTitles = true

        let button1 = UIBarButtonItem(title: "Add Course", style: .plain, target: self, action: #selector(addTapped))
        self.navigationItem.rightBarButtonItem = button1


        self.view.backgroundColor = .systemBackground

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
        tableView.delegate = self
        tableView.dataSource = self

        self.tableView.tableFooterView = UIView()

        resultSearchController = ({
            let controller = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.obscuresBackgroundDuringPresentation = false
            controller.searchBar.placeholder = "Search Courses"
            controller.searchBar.sizeToFit()

            tableView.tableHeaderView = controller.searchBar

            return controller
        })()

    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if  (resultSearchController.isActive) {
            return filteredCourses.count
        }
        else{
            return allCourses.count
        }
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)

        if (resultSearchController.isActive) {
            cell.textLabel?.text = filteredCourses[indexPath.row]
            return cell
         }
         else {
            let courses = self.allCourses[indexPath.row]
            cell.textLabel?.text = courses as? String
            return cell
         }
    }

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

        tableView.deselectRow(at: indexPath, animated: true)

        if (tag == 0){
            if (resultSearchController.isActive){
//                fallQuarterCelll.data.append(filteredCourses[indexPath.row])
//                UserDefaults.standard.set(fallQuarterCelll.data, forKey: "SavedArray")
//                self.navigationController?.popViewController(animated: true)
                let data = filteredCourses[indexPath.row]
                delegate?.sendDataBackFall(data: data)
                self.navigationController?.popViewController(animated: true)

            }
            else{
//                fallQuarterCelll.data.append(allCourses[indexPath.row] as! String)
//                UserDefaults.standard.set(fallQuarterCelll.data, forKey: "SavedArray")
//                self.navigationController?.popViewController(animated: true)
                let data = allCourses[indexPath.row] as! String
                delegate?.sendDataBackFall(data: data)
                self.navigationController?.popViewController(animated: true)

            }
        }
    }

    var isSearchBarEmpty: Bool {
      return resultSearchController.searchBar.text?.isEmpty ?? true
    }
}

extension SearchPage: UISearchResultsUpdating {

  func updateSearchResults(for searchController: UISearchController) {
      filteredCourses.removeAll(keepingCapacity: false)

      let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
      let array = (allCourses as NSArray).filtered(using: searchPredicate)
      filteredCourses = array as! [String]

      self.tableView.reloadData()
  }

}

Игнорировать UsersDefault ... Я пытаюсь заставить данные появляться на fallQuarterCell Сначала tableView.

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Вы не перезагружаете табличное представление в fallQuarterCell.

let vc = fallQuarterCell() создает новую ячейку. Ваше представление коллекции не содержит его, поэтому vc.tableView.reloadData() ничего не делает.

Когда вы используете collectionView.dequeueReusableCell, вы можете получить старую ячейку, поэтому вам следует перезагрузить табличное представление в этой ячейке. Вам следует прочитать документацию :

Вызвать этот метод из объекта источника данных, когда его попросят предоставить новую ячейку для представления сбора. Этот метод удаляет существующую ячейку, если она доступна, или создает новую

Например, вы можете добавить func updateViews() в fallQuarterCell:

func updateViews() {
    tableView.reloadData()
}

и вызвать ее здесь:

if (indexPath.row == 0){
    let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier, for: indexPath) as! fallQuarterCell
    cell1.layer.borderColor = UIColor.orange.cgColor
    cell1.layer.borderWidth = 2
    cell1.layer.cornerRadius = 5
    cell1.quarters = self.quarters[0]
    cell1.updateViews()
    return cell1
}
0 голосов
/ 19 февраля 2020

Все, что вам нужно сделать, это создать отдельный класс ячейки для ячейки представления коллекции и создать выход вашего табличного представления в этот класс ячейки.


В вашем cellForItemAt метод представления коллекции выполните код ниже:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TabelCell", for: indexPath) as! MyTabelCell

cell.MyTableView.reloadData()

}

Теперь вам нужно перезагрузить представление коллекции, и оно автоматически перезагрузит табличное представление. Это лучший и самый простой способ приблизиться к TableView в CollectionView

...