Changed stack to use a percent modifier to compensate for spacing.

This commit is contained in:
Pfeil, Scott Robert 2020-01-23 09:31:33 -05:00
parent c6ba48397c
commit 15a943d2e7
2 changed files with 39 additions and 14 deletions

View File

@ -14,11 +14,21 @@ open class MoleculeStackView: Stack<MoleculeStackModel> {
}
/// 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

View File

@ -31,8 +31,10 @@ open class Stack<T>: 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<T>: 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<T>: 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<T>: 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)