121 lines
4.1 KiB
Swift
121 lines
4.1 KiB
Swift
//
|
|
// SelectorGroupHandlerable.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 8/23/22.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
///MARK: Groups that allow anything selected
|
|
public protocol SelectorGroupModelHandlerable: ModelHandlerable, Disabling, Surfaceable where ModelType: SelectorGroupModelable {
|
|
associatedtype ModelHandlerType: ModelHandlerable where ModelType.SelectorModelType == ModelHandlerType.ModelType, ModelHandlerType: UIControl
|
|
var selectorViews: [ModelHandlerType] { get set }
|
|
func createModelHandler(selector: ModelHandlerType.ModelType) -> ModelHandlerType
|
|
}
|
|
|
|
extension SelectorGroupModelHandlerable {
|
|
|
|
public func findSelectorView(id: UUID) -> ModelHandlerType? {
|
|
return selectorViews.first(where: { existingSelectorView in
|
|
return existingSelectorView.model.id == id
|
|
})
|
|
}
|
|
|
|
public func createModelHandler(selector: ModelHandlerType.ModelType) -> ModelHandlerType {
|
|
//create view
|
|
let newSelectorView = ModelHandlerType(with: selector)
|
|
|
|
//add model update to the subscribers
|
|
newSelectorView.handlerPublisher()
|
|
.sink { [weak self] model in
|
|
if let cached = self?.getCachedSelector(viewModel: model), newSelectorView.shouldUpdateView(viewModel: cached) {
|
|
self?.replace(viewModel: model)
|
|
}
|
|
}
|
|
.store(in: &subscribers)
|
|
|
|
return newSelectorView
|
|
}
|
|
|
|
public func updateSelectors(){
|
|
let selectors = model.selectors.compactMap { existing in
|
|
return existing.copyWith {
|
|
$0.disabled = disabled
|
|
$0.surface = surface
|
|
}
|
|
}
|
|
model.selectors = selectors
|
|
}
|
|
|
|
public func getCachedSelector(viewModel: ModelHandlerType.ModelType) -> ModelHandlerType.ModelType? {
|
|
if let index = model.selectors.firstIndex(where: { element in
|
|
return element.id == viewModel.id
|
|
}) {
|
|
return model.selectors[index]
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public func replace(viewModel: ModelHandlerType.ModelType){
|
|
if let index = model.selectors.firstIndex(where: { element in
|
|
return element.id == viewModel.id
|
|
}) {
|
|
model.selectors[index] = viewModel
|
|
}
|
|
}
|
|
}
|
|
|
|
///MARK: Groups that allow single selections
|
|
public protocol SelectorGroupSelectedModelHandlerable: SelectorGroupModelHandlerable {
|
|
var selectedModel: ModelHandlerType.ModelType? { get set }
|
|
func didSelect(selector: ModelHandlerType.ModelType)
|
|
}
|
|
|
|
extension SelectorGroupSelectedModelHandlerable {
|
|
|
|
public func createModelHandler(selector: ModelHandlerType.ModelType) -> ModelHandlerType {
|
|
//create view
|
|
let newSelectorView = ModelHandlerType(with: selector)
|
|
|
|
//add the selectedPublisher for the change
|
|
newSelectorView.publisher(for: .valueChanged)
|
|
.sink(receiveValue: { [weak self] control in
|
|
guard self?.model.selectors.count ?? 0 > 0 else { return }
|
|
self?.didSelect(selector: control.model)
|
|
})
|
|
.store(in: &subscribers)
|
|
|
|
//add model update to the subscribers
|
|
newSelectorView.handlerPublisher()
|
|
.sink { [weak self] model in
|
|
if let cached = self?.getCachedSelector(viewModel: model), newSelectorView.shouldUpdateView(viewModel: cached) {
|
|
self?.replace(viewModel: model)
|
|
}
|
|
}
|
|
.store(in: &subscribers)
|
|
|
|
return newSelectorView
|
|
}
|
|
|
|
public func didSelect(selector: ModelHandlerType.ModelType) {
|
|
if var oldSelectedModel = selectedModel {
|
|
oldSelectedModel.selected = false
|
|
replace(viewModel: oldSelectedModel)
|
|
}
|
|
|
|
//only select is selected
|
|
if selector.selected {
|
|
var newSelectedModel = selector
|
|
newSelectedModel.selected = true
|
|
replace(viewModel: newSelectedModel)
|
|
selectedModel = newSelectedModel
|
|
} else {
|
|
//ensure current value is removed
|
|
selectedModel = nil
|
|
}
|
|
}
|
|
}
|