Swift, используя делегированный просмотр таблицы, чтобы обновить sh контент из другого класса - PullRequest
0 голосов
/ 12 февраля 2020

Мне нужно обновить содержимое TableView из другого класса, который выполняет асинхронный c вызов внешнего API.

Я реализовал протокол для обновления sh таблицы после вызова API, но кажется, что этот код никогда не выполняется. Я не могу понять, что не так с моим кодом .. возможно, я что-то забыл, это мое первое приложение, и я только начинаю изучать реализацию протоколов

Ниже я написал пример своего кода, где я удаляю весь ненужный код (для этого вопроса).

Определение протокола:

protocol ProductUpdateDelegate: class {
        func refreshTableView()
    }

Реализация Tabelview:

    class TestTableViewController: UITableViewController,
UITextFieldDelegate, ProductUpdateDelegate {

    var productList = [productInfo]()

    // Delegate function implementation
        func refreshTableView() {
              self.tableView.reloadData()
              self.tableView.beginUpdates()
              self.tableView.endUpdates()
        }

        override func viewDidLoad() {
          super.viewDidLoad()
          self.tableView.rowHeight = 50;
          self.tableView.dataSource = self
          self.tableView.delegate = self
          more code ...
        }

   @IBAction private func buttonTappedAction(_ sender: Any) {

    code that get input from user and did some check...

    if(isValidCode){
     self.storeProduct(productCode: code)        
    }

 }


func storeProduct(productCode: String){
        if(isNewCode){
          self.productList.append(productInfo(code: productCode,
          quantity: 1))

                }

         more code ...

        }

Класс, которому необходимо обновить некоторую информацию в tableView

import Foundation

class Product {

   weak var delegate: ProductUpdateDelegate?

   some code here...

   func getProductInfoFromAPI(){

     API CAll...

     if(result != "no_data")
      self.delegate?.refreshTableView()
     }

     more code ...

}

класс, используемый для хранения информации о продуктах и ​​используемый для обновления описания продуктов с использованием удаленного API

import Foundation

class productInfo: NSObject, NSCoding, Codable {

    var code = ""
    var quantity = 1
    public var product_name = "Wait for information..."

    init(code: String, quantity : Int, 
product_name : String = "Wait for information...") {
        self.code = code
        self.quantity = quantity
        self.product_name = product_name
        super.init()
        self.getProductInfoFromAPI()
    }

    required convenience init(coder aDecoder: NSCoder) {
        let code = aDecoder.decodeObject(forKey: "code") as! String
        let quantity = aDecoder.decodeInteger(forKey: "quantity")
        self.init(code:code, quantity:quantity)
        self.getProductInfoFromAPI()
    }

    func getProductInfoFromAPI(){
        let productInfo = Product()
        productInfo.getInfoByCode(productCode: code, refObject: self)
    }


    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.code, forKey: "code")
        aCoder.encode(self.quantity, forKey: "quantity")
    }
}

UPDATE1: Класс продукта вызывается из некоторых других классов (4 в всего), который я не включил сюда для простоты

Рабочий процесс приложения:

  • Запуск приложения
  • показ TestTableViewController

Затем у пользователя есть несколько вариантов обновления содержимого TableView. Каждый параметр контролируется отдельным классом, поэтому класс продукта называется fro. m некоторые другие классы и являются единственными, которые напрямую взаимодействуют с TestTableViewController

UPDATE2: Добавьте дополнительный код для отображения всего процесса. После инициализации просмотра пользователь может нажать на кнопку и вставить код продукта.

Вставленный код сохраняется в массиве productInfo с помощью команды append. Это действие активирует метод init класса productInfo и запускает удаленный сервис для вызова информации о самом продукте.

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

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020
var refreshControl = UIRefreshControl()

@IBOutlet weak var tblView: UITableView!


override func viewDidLoad() {
    super.viewDidLoad()
    refreshControl.attributedTitle = NSAttributedString(string: "")
    refreshControl.addTarget(self, action: #selector(refresh(sender:)), for: UIControl.Event.valueChanged)
    tblView.addSubview(refreshControl)
}


@objc func refresh(sender:AnyObject) {
    refreshControl.endRefreshing()
    apiFunction()
}


func apiFunction(){
    // call your api
}
1 голос
/ 13 февраля 2020

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

class Product {
   static let shared = Product()
   weak var delegate: ProductUpdateDelegate?

   private init() { }

   func getProductInfoFromAPI(){
     if(result != "no_data")
     self.delegate?.refreshTableView()
   }
}

И в вашем контроллере табличного представления вместо let productInfo = Product() вы можете использовать let productInfo = Product.shared, а затем установить свой делегат.

productInfo.delegate = self

Вот и все!

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