как настроить UITableView с помощью MVC парадигмы SWIFT - PullRequest
0 голосов
/ 05 марта 2020

Пожалуйста, кто-нибудь может мне помочь. Я провел около 1 недели, пытаясь решить ее самостоятельно. У меня есть таблица и парадигма MVC. Я не могу настроить cellForRow и numbersOfSections. Потому что это как расширение в UIView, но я не могу сохранить какие-либо свойства в UIView из-за парадигмы MVC. Может кто-нибудь объяснить мне, как я могу решить эту проблему?

class ShopView: UIView {

private(set) lazy var productListTableView: UITableView = {
    let productList = UITableView()
    productList.dataSource = self
    productList.translatesAutoresizingMaskIntoConstraints = false
    return productList
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    self.setupLayout()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.setupLayout()
}
}

class ShopViewControllerModel: UIViewController {

weak var coordinator: MainCoordinator?

let requestFactory = RequestFactory()

private var shopTableView: ShopView  {
    return self.view as! ShopView
}

override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
}

override func loadView() {
    super.loadView()
    self.view = ShopView()
}
}


extension ShopViewControllerModel {
{
    func download(completion: @escaping (Product) -> ()) {
        let getGoods = requestFactory.getGoods()
        getGoods.getNewGoods(pageNumber: 1, id_category: 1) { response in
            switch response.result {
            case .success(let goods):
                for index in goods.products {
                    let array = Product(product_name: index.product_name, id: index.id, price: index.price)
                    completion(array)
                }
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }
}

class ShopViewController: UIViewController {

lazy var shopTableView = ShopViewControllerModel()
weak var coordinator: MainCoordinator?
var totalGoodsModel: [Product] = []



override func viewDidLoad() {
    super.viewDidLoad()
    self.title = "Shop"
    self.navigationController?.navigationBar.isHidden = true
    self.view.backgroundColor = .red
    addEditVC()

}

private func addEditVC() {
    self.shopTableView.download { (response) in
        self.totalGoodsModel = [response]

        print(self.totalGoodsModel)
    }
}

extension ShopView: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let sections = 2
        return sections
    }



    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        self.productListTableView.register(UITableViewCell.self, forCellReuseIdentifier: "contactCell")
        let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ShopTableViewCell
        cell.textLabel?.text = "ShopTableViewCell"
        return cell
    }
}

Ответы [ 2 ]

1 голос
/ 05 марта 2020

Как уже упоминалось в комментариях к исходному сообщению, источником данных для вашего TableView должен быть ваш класс ViewController.

Вы можете извлекать продукты и предоставлять данные в отдельный класс ShopModel, но он не должен наследовать UIViewController.

Попробуйте что-то вроде этого:

import UIKit

struct Product: Codable {
    var title: String
    var price: Double
    var isFeatured: Bool
}

class ShopViewController: UIViewController {

    private var products = [Product]()
    private var tableView: UITableView!

    override func viewDidLoad() {
        setupLayout()
        fetchProducts()
    }

    private func setupLayout() {
        tableView = UITableView()
        view.addSubview(tableView)

        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        tableView.dataSource = self

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "productCell")
    }

    private func fetchProducts() {
        URLSession.shared.dataTask(with: URL(string: "192.168.1.1/products")!, completionHandler: { data, response, error in
            guard error == nil else {
                print(error!.localizedDescription)
                return
            }

            do {
                self.products = try JSONDecoder().decode([Product].self, from: data!)
                // Refresh table after downloading products and make sure to do it from main thread
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            } catch {
                print("Error decoding list of products from received data.")
            }
        }).resume()
    }
}

extension ShopViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            // Featured products
            return products.filter { $0.isFeatured }.count
        } else {
            // All products
            return products.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "productCell", for: indexPath)
        cell.textLabel?.text = products[indexPath.row].title
        cell.detailTextLabel?.text = String(products[indexPath.row].price)
        return cell
    }
}

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

0 голосов
/ 05 марта 2020
import UIKit

struct Product: Codable { // Model
    var title: String
    var price: Double
    var isFeatured: Bool
}

class ShopView: UIView { // View

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

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

    private func setupView() {
        addSubview(shopTableView)
        shopTableView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        shopTableView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        shopTableView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        shopTableView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }

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

class ShopViewController: UIViewController { //  Controller

    private var products = [Product]()
    let shopView = ShopView()
    let cellId = "cellId"

    override func viewDidLoad() {
        super.viewDidLoad()
        setupDelegatesAndDataSources()
        fetchProducts()
    }

    private func setupDelegatesAndDataSources() {
        shopView.shopTableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
        shopView.shopTableView.dataSource = self
    }

    private func fetchProducts() {
        let data1 = Product(title: "Hello", price: 123.0, isFeatured: true)
        let data2 = Product(title: "Hey", price: 12345.00, isFeatured: true)
        let data3 = Product(title: "Hi", price: 1234567.00, isFeatured: true)
        let data4 = Product(title: "Bye", price: 123456789.000, isFeatured: true)
        products = [data1, data2, data3, data4]
    }

//    private func fetchProducts() {
//        URLSession.shared.dataTask(with: URL(string: "192.168.1.1/products")!, completionHandler: { data, response, error in
//            guard error == nil else {
//                print(error!.localizedDescription)
//                return
//            }
//
//            do {
//                self.products = try JSONDecoder().decode([Product].self, from: data!)
//                // Refresh table after downloading products and make sure to do it from main thread
//                DispatchQueue.main.async {
//                    self.shopView.shopTableView.reloadData()
//                }
//            } catch {
//                print("Error decoding list of products from received data.")
//            }
//        }).resume()
//    }

    override func loadView() {
        view = shopView
    }
}

extension ShopViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            // Featured products
            return products.filter { $0.isFeatured }.count
        } else {
            // All products
            return products.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = shopView.shopTableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
        cell.textLabel?.text = products[indexPath.row].title
        cell.detailTextLabel?.text = String(products[indexPath.row].price)
        return cell
    }
}

Просто обновленный ответ Lieksu .

Модель = Продукт

Вид = ShopView

Контроллер = ShopViewController

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...