数组更新晚了 - Swift - MVVM

问题描述

大家好,我是实现 MVVM 模式的新手,我想弄清楚为什么我的数组更新这么晚,我的意思是如果我不使用 dispatchQueue,它就不会加载,我的意思是我'我试图将 tableviewdatasource 与 viewcontroller 分开,这似乎弊大于利。 这是我的代码

视图模型:

import Foundation
import UIKit

class Notificationsviewmodel: NSObject {
    
    private(set) var notificationsData: [Notification]! {
        didSet {
            self.bindNotificationsviewmodelToController()
        }
    }
    
    var bindNotificationsviewmodelToController : (() -> ()) = {}
    
    var arrOfNotifications = [Notification]()
    
    var selectedCounter = 0
    var notificationIsRead = false
    
    override init() {
        super.init()
        callFuncToGetNotData()
        
    }
    
    
    func callFuncToGetNotData()  {
        dispatchQueue.main.async {
            var tempNotificationsArr : [Notification] = []
            
            var notification1 = Notification(image: UIImage(named: "messageImage")!,title: "Hello1",date: Date.getCurrentDate(Date())(),team: "In: Team1",isRead: false)
            var notification2 = Notification(image: UIImage(named: "messageImage")!,title: "Hello2",team: "In: QA Teams",isRead: true)
            
            
            tempNotificationsArr.append(notification1)
            tempNotificationsArr.append(notification2)
            
            self.notificationsData = tempNotificationsArr
        }
        
    }
    
    
    func setTitle(title:String,subtitle:String) -> UIView {
        
        let titleLabel = UILabel(frame: CGRect(x: 0,y: -2,width: 0,height: 0))
        
        titleLabel.backgroundColor = UIColor.clear
        titleLabel.textColor = UIColor.white
        titleLabel.font = UIFont.boldSystemFont(ofSize: 17)
        titleLabel.text = title
        titleLabel.sizetoFit()
        
        let subtitleLabel = UILabel(frame: CGRect(x:0,y:18,width:0,height:0))
        subtitleLabel.backgroundColor = .clear
        subtitleLabel.textColor = .white
        subtitleLabel.font = UIFont.systemFont(ofSize: 12)
        subtitleLabel.text = subtitle
        subtitleLabel.sizetoFit()
        
        
        let titleView = UIView(frame: CGRect(x: 0,y: 0,width: max(titleLabel.frame.size.width,subtitleLabel.frame.size.width),height: 30))
        titleView.addSubview(titleLabel)
        titleView.addSubview(subtitleLabel)
        
        let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width
        
        if widthDiff < 0 {
            let newX = widthDiff / 2
            subtitleLabel.frame.origin.x = abs(newX)
        } else {
            let newX = widthDiff / 2
            titleLabel.frame.origin.x = newX
        }
        
        return titleView
    }
    
    func selectAllRows(_ tableView: UITableView) {
        for section in 0..<tableView.numberOfSections {
            for row in 0..<tableView.numberOfRows(inSection: section) {
                tableView.selectRow(at: IndexPath(row: row,section: section),animated: false,scrollPosition: .none)
            }
        }
    }
    
    func deselectAllRows(_ tableView: UITableView) {
        for section in 0..<tableView.numberOfSections {
            for row in 0..<tableView.numberOfRows(inSection: section) {
                tableView.deselectRow(at: IndexPath(row: row,animated: false)
            }
        }
    }
    
    
    func getAlertSheet() -> UIAlertController {
        let alertController = UIAlertController(title: nil,message: "\(selectedCounter) Message",preferredStyle: .actionSheet)
        
        let cancelAction = UIAlertAction(title: "Cancel",style: .cancel) { (action) in
            // ...
        }
        alertController.addAction(cancelAction)
        
        
        let markAsUnReadAction = UIAlertAction(title: "Mark as Unread",style: .default) { (action) in
        }
        alertController.addAction(markAsUnReadAction)
        
        let flag = UIAlertAction(title: "Flag",style: .default) { (action) in
            //
        }
        alertController.addAction(flag)
        
        let markAsRead = UIAlertAction(title: "Mark as Read",style: .default) { (action) in
            //
        }
        alertController.addAction(markAsRead)

        return alertController
    }


    func enableButtons(_ markBtn: UIBarButtonItem,_ selectAllBtn: UIBarButtonItem,_ deleteBtn: UIBarButtonItem) {
        selectedCounter+=1
        notificationIsRead = true
        print(selectedCounter)
            markBtn.isEnabled = true
            selectAllBtn.isEnabled = true
            deleteBtn.isEnabled = true
        
    }

    func disableButtons(_ markBtn: UIBarButtonItem,_ deleteBtn: UIBarButtonItem) {
        selectedCounter -= 1
        notificationIsRead = false
        if selectedCounter == 0 {
            markBtn.isEnabled = false
            selectAllBtn.isEnabled = false
            deleteBtn.isEnabled = false
        }
        
    }
}

视图控制器:

import UIKit
class NotificationsViewController: UIViewController,ViewControllerDelegate {
    
    @IBOutlet weak var notificationsTableView: UITableView!
    @IBOutlet weak var toolBar: UIToolbar!
    @IBOutlet weak var markButton: UIBarButtonItem!
    @IBOutlet weak var selectAllButton: UIBarButtonItem!
    @IBOutlet weak var deleteButton: UIBarButtonItem!
    
    private var notificationsviewmodel : Notificationsviewmodel!
    
    private var dataSource : NotificationTableViewDataSource<NotificationCell,Notification>!
    
    var tableViewDelegate: TableViewDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        callToviewmodelForUIUpdate()
        configureTableView()
        configureEditButton()
        self.navigationItem.titleView = notificationsviewmodel.setTitle(title: "Notifications",subtitle: "1 New")
        
    }
    
    func callToviewmodelForUIUpdate(){
        self.notificationsviewmodel =  Notificationsviewmodel()
        self.notificationsviewmodel.bindNotificationsviewmodelToController = {
            self.updateDataSource()
        }
    }
    
    
    func updateDataSource(){
        self.dataSource = NotificationTableViewDataSource(cellIdentifier: "notificationCell",notifications: self.notificationsviewmodel.notificationsData,configureCell: { (cell,nvm) in
            cell.titleLabel.text = nvm.title
            cell.imageView?.image = nvm.image
            cell.dateLabel.text = nvm.date
            cell.teamLabel.text = nvm.team
            cell.notificationBadge.isHidden = nvm.isRead
        })

        self.notificationsTableView.dataSource = self.dataSource
        self.notificationsTableView.reloadData()
        
    }
    
    func configureTableView() {
        notificationsTableView.rowHeight = 80
        notificationsTableView.allowsMultipleSelectionDuringEditing = true
        self.tableViewDelegate = TableViewDelegate(withDelegate: self)
        self.notificationsTableView.delegate = self.tableViewDelegate
        self.toolBar.isHidden = true
        self.markButton.isEnabled = false
        self.deleteButton.isEnabled = false
    }
    
    
    func configureEditButton() {
        self.navigationItem.rightBarButtonItem = editButtonItem
        self.navigationItem.rightBarButtonItem?.tintColor = .white
    }
    
    
    @IBAction func markBtnpressed(_ sender: UIBarButtonItem) {
        //  UIAlert Pops up
        self.present(notificationsviewmodel.getAlertSheet(),animated: true,completion: nil)
        
    }
    
    @IBAction func selectAllBtnpressed(_ sender: UIBarButtonItem) {
        //  Selects/diselect All The Rows In Our TableView.
        if sender.title == "Select All"{
            notificationsviewmodel.selectAllRows(self.notificationsTableView)
            markButton.isEnabled = true
            deleteButton.isEnabled = true
            sender.title = "deselect All"
        } else {
            notificationsviewmodel.deselectAllRows(self.notificationsTableView)
            sender.title = "Select All"
            markButton.isEnabled = false
            deleteButton.isEnabled = false
        }
    }
    
    
    @IBAction func deleteBtnpressed(_ sender: UIBarButtonItem) {
        //  Deletes a row
        print("Delete Button Is pressed")
        
    }
    
    override func setEditing(_ editing: Bool,animated: Bool) {
        super.setEditing(editing,animated: animated)
        self.notificationsTableView.setEditing(editing,animated: animated)
        if editing {
            //Section of when we are in Editing Mode:
            toolBar.isHidden = false
            self.navigationItem.rightBarButtonItem?.title = "Cancel"
            toolBar.toolBaranimation(self.toolBar)
        } else {
            //Section of when we are NOT in Editing Mode:
            toolBar.toolBardissapearanimation(self.toolBar)
            self.navigationItem.rightBarButtonItem?.title = "Edit"
            toolBar.toolBardissapearanimation(self.toolBar)
        }
    }
    
    
    func selectedCell(row: Int) {
        if isEditing {
            notificationsviewmodel.enableButtons(self.markButton,self.selectAllButton,self.deleteButton)
        }
    }
    
    
    func diselectedCell(row: Int) {
        if isEditing {
            notificationsviewmodel.disableButtons(self.markButton,self.deleteButton)
        }
    }
}

TableViewDataSource 文件

import Foundation
import UIKit

class NotificationTableViewDataSource<CELL : UITableViewCell,T> : NSObject,UITableViewDataSource {
    
    private var cellIdentifier : String!
    private var notifications : [T]!
    var configureCell : (CELL,T) -> () = {_,_ in }
    
    
    init(cellIdentifier : String,notifications : [T],configureCell : @escaping (CELL,T) -> ()) {
        self.cellIdentifier = cellIdentifier
        self.notifications =  notifications
        self.configureCell = configureCell
    }
    
    func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        notifications.count
    }
    
    func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
         let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier,for: indexPath) as! CELL
        
        let item = self.notifications[indexPath.row]
        self.configureCell(cell,item)
        return cell
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)