Как обработать изменение значения элемента подкласса UIView в ячейке табличного представления - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть табличное представление и заполнение ячейки пользовательским классом UITableViewcell с помощью другого подкласса UIView. При изменении статуса элемента подкласса UIView я хочу обновить свой массив источников данных [CheckLists] и обновить соответствующие значения в firebase.

UIViewController, содержащий представление таблицы

TableView

import UIKit

class QuickVC: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var checkLists : [CheckListItem] = [] {didSet{tableView.reloadData()}}
    var checkListItemViews: [[ItemView]] = []
    var state: [[ItemView]]?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource = self
        tableView.delegate = self
        DataService.instance.getAllCheckList { (result) in
            if let result = result {self.checkLists = result}
        }
        NotificationCenter.default.addObserver(self, selector: #selector(itemStatusChanged), name: NSNotification.Name(rawValue: "ItemStatusChanged"), object: nil)
    }

    @objc func itemStatusChanged() {

    }
}

extension QuickVC: UITableViewDataSource, UITableViewDelegate{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return checkLists.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: QuickNoteTableViewCell.className) as! QuickNoteTableViewCell
        cell.configure(checkList: self.checkLists[indexPath.row]) { (itemViews) in
            self.checkListItemViews.append(itemViews)
            if self.state == nil { self.state = self.checkListItemViews}
        }
        return cell
    }

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


import UIKit

class QuickNoteTableViewCell: UITableViewCell {

    @IBOutlet weak var colorView: UIView!
    @IBOutlet weak var descriptionLabel: UILabel!
    @IBOutlet weak var itemsStackView: UIStackView!

    var items: [Item] = []

    override func awakeFromNib() {
        super.awakeFromNib()

    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    func configure(checkList: CheckListItem, onCompletion: @escaping (_ itemsHandler: [ItemView]) -> ()){
        self.descriptionLabel.text = checkList.note.description
        self.colorView.backgroundColor = checkList.note.color
        let items = addCheckListItemsIfAvailable(items: checkList.items)
        onCompletion(items)
    }

    fileprivate func addCheckListItemsIfAvailable(items: [Item]) -> [ItemView]{

        for subview in self.itemsStackView.subviews {
            if (subview.tag == 100) {
                subview.removeFromSuperview()
            }
        }
        var itemsHandler: [ItemView] = []
        if items.count > 0 {
            if !items.isEmpty {
                items.forEach { (item) in
                    let itemView = ItemView(frame: CGRect(x: 48, y: 0, width: 200, height: 28.5))
                    itemView.tag = 100
                    itemView.titleLabel.text = item.title
                    itemView.isChecked = item.status
                    self.itemsStackView.addArrangedSubview(itemView)
                    itemsHandler.append(itemView)
                }
            }

        }
        return itemsHandler
    }
}


import UIKit

class ItemView: UIView {

    let XIB_NAME = ItemView.className

    @IBOutlet var contentView: UIView!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var checkBoxView: CustomizableView!

    var isChecked: Bool = false {
        didSet {
            updateCheckBox()
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ItemStatusChanged"), object: nil)
        }
    }

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

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

    func commonInit() {
        Bundle.main.loadNibNamed(XIB_NAME, owner: self, options: nil)
        contentView.fixInView(self)
        let tap =  UITapGestureRecognizer(target: self, action: #selector(updateIsCheckedValue))
        checkBoxView.addGestureRecognizer(tap)
    }

    @objc func updateIsCheckedValue(){
        if isChecked {
            isChecked = false
        } else {
            isChecked = true
        }
    }

    func updateCheckBox (){
        if let text = titleLabel.text {
            if isChecked {
                checkBoxView.backgroundColor = #colorLiteral(red: 0.6323310137, green: 0.6328232288, blue: 0.632407248, alpha: 1)
                titleLabel.text = String(describing: myAttributedString(text: text, applyAtrribute: true))
            } else {
                checkBoxView.backgroundColor = #colorLiteral(red: 0.9658892751, green: 0.9697455764, blue: 0.9658194184, alpha: 1)
                titleLabel.text = String(describing: myAttributedString(text: text, applyAtrribute: false))
            }
        }
    }

    func myAttributedString(text: String,applyAtrribute: Bool)->NSAttributedString {
           let attributeString =  NSMutableAttributedString(string: text)
           attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue,range: NSMakeRange(0, attributeString.length)
           )
           let removedAttributString = NSMutableAttributedString(string: text)
               removedAttributString.removeAttribute(NSAttributedString.Key.strikethroughStyle, range: NSMakeRange(0, attributeString.length))

           return applyAtrribute ? attributeString : removedAttributString
       }
}

и ниже являются моделями

import UIKit

struct CheckListItem {
    var id:String
    var note: Note
    var items: [Item]

    init() {
        note = Note(description: "", color: .clear)
        items = []
        id = ""
    }
    init(id: String, description: String, items: [Item], color: UIColor) {
        self.note = Note(description: description, color: color)
        self.items = items
        self.id = id
    }
}

import Foundation

struct Item {
    var title: String
    var status: Bool
}
...