diff --git a/MVMCoreUI/Organisms/MoleculeStackView.swift b/MVMCoreUI/Organisms/MoleculeStackView.swift index afc1f954..d6f934a7 100644 --- a/MVMCoreUI/Organisms/MoleculeStackView.swift +++ b/MVMCoreUI/Organisms/MoleculeStackView.swift @@ -14,11 +14,21 @@ open class MoleculeStackView: Stack { } /// Convenience function, adds a molecule to a MoleculeStackItem to the MoleculeStack - func addMolecule(_ view: View, lastItem: Bool) { - guard let model = view.model else { return } - let stackItemModel = MoleculeStackItemModel(with: model) - let stackItem = MoleculeStackItem(andContain: view) - addView(stackItem, stackItemModel, lastItem: lastItem) + func setup(with views: [View], lastItem: Bool) { + var models: [MoleculeStackItemModel] = [] + for view in views { + guard let model = view.model else { return } + let stackItemModel = MoleculeStackItemModel(with: model) + let stackItem = MoleculeStackItem(andContain: view) + stackItems.append(stackItem) + models.append(stackItemModel) + } + if let stackModel = stackModel { + stackModel.molecules = models + } else { + model = MoleculeStackModel(molecules: models) + } + restack() } // MARK: - Adding to stack diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index a92d5a2f..2ab77421 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -31,8 +31,10 @@ open class Stack: Container where T: StackModelProtocol { let lastItemIndex = stackModel.molecules.lastIndex(where: { (item) -> Bool in return !item.gone }) + + // Adds the views for (index, view) in stackItems.enumerated() { - addView(view, stackModel.molecules[index], lastItem: lastItemIndex == index) + addView(view, stackModel.molecules[index], percentModifier: getPercentModifier(), lastItem: lastItemIndex == index) } } @@ -170,15 +172,28 @@ open class Stack: Container where T: StackModelProtocol { } // MARK: - Adding to stack - /// Convenience function, adds a view to a StackItem to the Stack - func addViewToItemToStack(_ view: UIView, lastItem: Bool) { - let stackItemModel = StackItemModel() - let stackItem = StackItem(andContain: view) - addView(stackItem, stackItemModel, lastItem: lastItem) + /// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved. + private func getPercentModifier() -> CGFloat { + guard let stackModel = stackModel else { return 0.0 } + var totalSpace: CGFloat = 0.0 + var totalViews = 0 + var firstMoleculeFound = false + for stackItemModel in stackModel.molecules { + guard !stackItemModel.gone else { continue } + totalViews += 1 + let spacing = stackItemModel.spacing ?? stackModel.spacing + if firstMoleculeFound { + totalSpace += spacing + } else { + firstMoleculeFound = true + totalSpace += (stackModel.useStackSpacingBeforeFirstItem ? spacing : stackItemModel.spacing ?? 0) + } + } + return (totalViews > 0 ? -(totalSpace / CGFloat(totalViews)) : 0) } /// Adds the stack item view - func addView(_ view: UIView,_ model: StackItemModelProtocol, lastItem: Bool) { + private func addView(_ view: UIView,_ model: StackItemModelProtocol, percentModifier: CGFloat, lastItem: Bool) { guard let stackModel = self.stackModel else { return } guard !model.gone else { // Gone views do not show @@ -208,7 +223,7 @@ open class Stack: Container where T: StackModelProtocol { pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: CGFloat(percent)/100.0).isActive = true + view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true } if lastItem { pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) @@ -225,7 +240,7 @@ open class Stack: Container where T: StackModelProtocol { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: CGFloat(percent)/100.0).isActive = true + view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true } if lastItem { pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)