Обновление tableView на VIewController'e из subView

swift

#1

Добрый день.
Не писал бы если бы нашел решение здесь))
В приложение есть таблица в которую данные подгружаются из Realm. В БД они добавляются/редактируются на subView, которое всплывает по нажатию “Add”(ViewController в это время блюрится). Настроен делегат при сохранении нового/ редактировании старого объекта по нажатию “save” на subView делегат сробатывает и блюр уходит c ViewController. В той же функции для делегата прописываю перезагрузку TableView, но видимо из за медленной записи в БП нет новых данных для отображения. Весь проект здесь: https://github.com/VAmpersand/Smenka

Файл subView:

protocol ShiftTypeCreationViewDelegate {
func pushButton()
}

class ShiftTypeCreationView: UIView {

class func initShiftTypeCreationView(delegate:  ShiftTypeCreationViewDelegate) ->  ShiftTypeCreationView {
    let shiftTypeCreation = Bundle.main.loadNibNamed("ShiftTypeCreationView", owner: self, options: nil)![0] as! ShiftTypeCreationView
    shiftTypeCreation.delegate = delegate
    return shiftTypeCreation
}

@IBOutlet weak var typeNameTextField: UITextField!
@IBOutlet weak var startTimePicker: UIDatePicker!
@IBOutlet weak var endTimePicker: UIDatePicker!
@IBOutlet weak var shiftColorCollectionView: UICollectionView!
@IBOutlet weak var cancelBatton: UIButton!
@IBOutlet weak var saveBatton: UIButton!

var delegate: ShiftTypeCreationViewDelegate?
var shiftTypes: Results<ShiftType>!

var shiftType = ShiftType()
var startTime = Date().getTime()
var endTime = Date().getTime()

//    var indicesSelectedColor: [Int] = []

var indexEditableType: Int!

let reuseIdentifier = "shiftTypeColorCell"
let localeID = Locale.preferredLanguages.first

//MARK: ShiftTypeCreationView display function
func showShiftTypeCreationViewInController(viewController: UIViewController) {
    
    shiftTypes = realm.objects(ShiftType.self)
    
    startTimePicker.datePickerMode = .time
    endTimePicker.datePickerMode = .time
    
    startTimePicker.locale = Locale(identifier: localeID!)
    endTimePicker.locale = Locale(identifier: localeID!)
    
    startTimePicker.addTarget(self, action: #selector(getStartTime), for: .valueChanged)
    endTimePicker.addTarget(self, action: #selector(getEndTime), for: .valueChanged)
    
    self.frame.origin.x = (viewController.view.frame.width - 360) / 2
    self.frame.origin.y = viewController.view.frame.height
    self.layer.cornerRadius = 15
    
    UIView.animate(withDuration: 0.6, animations: {
        self.frame.origin.y = 85
    })
    
    viewController.view.addSubview(self)
}


@IBAction func cancelButtonPressed(_ sender: Any) {
    delegate?.pushButton()
    hidingShiftTypeCreationView()
}


@IBAction func saveButtonPressed(_ sender: Any) {
    delegate?.pushButton()
    hidingShiftTypeCreationView()
    getShiftType()
    
    //MARK: Сhoose to save new or overwrite editable
    if indexEditableType != nil {
        DispatchQueue.main.async {
            StorageManager.editShiftType(self.shiftTypes[self.indexEditableType], self.shiftType)
        }
    } else {
        DispatchQueue.main.async {
            StorageManager.saveShiftType(self.shiftType)
        }
    }
}

}

extension ShiftTypeCreationView {

// Hiding animation for ShiftTypeCreationView
func hidingShiftTypeCreationView() {
    self.frame.origin.y = 85
    self.layer.cornerRadius = 15
    
    UIView.animate(withDuration: 0.6, animations: {
        self.frame.origin.y = (self.delegate as! UIViewController).view.frame.height
    }) { (bool) in
        self.removeFromSuperview()
    }
}

func getShiftType() {
    shiftType.shiftTypeName = typeNameTextField.text ?? "Default value"
    shiftType.startTime = startTime
    shiftType.endTime = endTime
}

@objc func getStartTime() {
    startTime = startTimePicker.date.getTime()
}

@objc func getEndTime() {
    endTime = endTimePicker.date.getTime()
}

}

Файл ViewController:

import UIKit
import RealmSwift

class SettingsViewController: UIViewController {

@IBOutlet weak var screenModeLabel: UILabel!
@IBOutlet weak var screenModeSwitch: UISwitch!
@IBOutlet weak var addTypeButton: UIButton!
@IBOutlet weak var shiftTypeTable: UITableView!
@IBOutlet weak var blurEffect: UIVisualEffectView!

var shiftTypes: Results<ShiftType>!


override func viewDidLoad() {
    super.viewDidLoad()
    
    shiftTypeTable.delegate = self
    shiftTypeTable.dataSource = self
    
    shiftTypes = realm.objects(ShiftType.self)
}

//MARK: Reload shift type table after return from MainVC
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
        shiftTypeTable.reloadData()
}


@IBAction func screenModeToggle(_ sender: Any) {
    
}

@IBAction func addShiftType(_ sender: Any) {
    
    let shiftTypeCreation = ShiftTypeCreationView.initShiftTypeCreationView(delegate: self)
    shiftTypeCreation.showShiftTypeCreationViewInController(viewController: self)
    
    UIView.animate(withDuration: 1) {
        self.blurEffect.alpha = 0.9
    }
}

}

extension SettingsViewController: ShiftTypeCreationViewDelegate {

func pushButton() {
    UIView.animate(withDuration: 1) {
        self.blurEffect.alpha = 0
    }
}

}

Повторю, что делегат работает. (viewDidApear добавил для обновления таблицы при возвращении на вью на первое время.) При добавлении в func pushButton() строку shiftTypeTabl.reloadDate(), таблица обновляется только если редактировал данные, а не добавлял новые записи.
Вопрос в том, как отследить загрузку данных в Realm а затем обновить или мб. есть иные способы решение проблемы?


#2

Так у вас порядок действий не правильный.
Вы вызываете метод делегата перед сохранением записей в базу.

Другие варианты отследить изменение - это realmChangeListener.
Так же все можно сделать и без этого, через от же делегат, но после сохранения записи в замыкании вызывать pushButton.


#3

Тут бы отлично подошел смайл фейспалма))) Я слишком понадеялся на поддержку контекста, и забил на старый добрый порядок команд. Спасибо что открыли глаза, все работает!!


#4

держите :slight_smile: