135 lines
5.7 KiB
Swift
135 lines
5.7 KiB
Swift
//
|
|
// ButtonGroupConstants.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 12/1/22.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
struct ButtonGroupConstants {
|
|
static let defaultSpace = 12.0
|
|
|
|
/// This will determine the spacing that will go between 2 ButtonBases either horizontally or vertically
|
|
/// - Parameters:
|
|
/// - axis: horizontal/vertical
|
|
/// - primary: first ButtonBase
|
|
/// - neighboring: next ButtonBase based off of axis
|
|
/// - Returns: float value
|
|
static func getSpacing(for axis: NSLayoutConstraint.Axis, with primary: ButtonBase, neighboring: ButtonBase) -> CGFloat {
|
|
|
|
//large button
|
|
if let button = primary as? Button, button.size == .large {
|
|
if let neighboringButton = neighboring as? Button, neighboringButton.size == .large {
|
|
return axis == .horizontal ? 12.0 : 12.0
|
|
} else if neighboring is TextLinkCaret {
|
|
return axis == .horizontal ? 24.0 : 24.0
|
|
} else if let neighboringTextLink = neighboring as? TextLink, neighboringTextLink.size == .large {
|
|
return axis == .horizontal ? 16.0 : 16.0
|
|
} else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
//large text link
|
|
else if let textLink = primary as? TextLink, textLink.size == .large {
|
|
if let neighboringButton = neighboring as? Button, neighboringButton.size == .large {
|
|
return axis == .horizontal ? 16.0 : 16.0
|
|
} else if neighboring is TextLinkCaret {
|
|
return axis == .horizontal ? 24.0 : 24.0
|
|
} else if let neighboringTextLink = neighboring as? TextLink, neighboringTextLink.size == .large {
|
|
return axis == .horizontal ? 16.0 : 24.0
|
|
} else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
//text link caret
|
|
else if let _ = primary as? TextLinkCaret {
|
|
if let neighboringButton = neighboring as? Button, neighboringButton.size == .large {
|
|
return axis == .horizontal ? 24.0 : 24.0
|
|
} else if let _ = neighboring as? TextLinkCaret {
|
|
return axis == .horizontal ? 24.0 : 24.0
|
|
} else if let neighboringTextLink = neighboring as? TextLink, neighboringTextLink.size == .large {
|
|
return axis == .horizontal ? 24.0 : 24.0
|
|
} else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
//small button
|
|
else if let button = primary as? Button, button.size == .small {
|
|
if let neighboringButton = neighboring as? Button, neighboringButton.size == .small {
|
|
return axis == .horizontal ? 12.0 : 12.0
|
|
} else if let neighboringTextLink = neighboring as? TextLink, neighboringTextLink.size == .small {
|
|
return axis == .horizontal ? 16.0 : 24.0
|
|
} else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
//small text link
|
|
else if let textLink = primary as? TextLink, textLink.size == .small {
|
|
if let neighboringTextLink = neighboring as? TextLink, neighboringTextLink.size == .small {
|
|
return axis == .horizontal ? 16.0 : 24.0
|
|
} else if let _ = neighboring as? Button {
|
|
return axis == .horizontal ? 16.0 : 32.0
|
|
} else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
//return defaultSpace
|
|
else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
|
|
/// Gets the tallest ButtonBases within the row
|
|
/// - Parameter row: Row that includes the attributes
|
|
/// - Returns: Array of [ButtonLayoutAttributes] of the tallest items
|
|
private static func getTallestAttributes(for row: ButtonCollectionViewRow) -> [ButtonLayoutAttributes] {
|
|
var height = 0.0
|
|
var foundIndexes:[Int] = []
|
|
for (index, attribute) in row.attributes.enumerated() {
|
|
if attribute.frame.height >= height {
|
|
height = attribute.frame.height
|
|
foundIndexes.append(index)
|
|
}
|
|
}
|
|
return foundIndexes.compactMap { row.attributes[$0] }
|
|
}
|
|
|
|
|
|
/// Gets the vertical spacing that will go between rows.
|
|
/// - Parameters:
|
|
/// - row: Primary row that the space will go between
|
|
/// - neighboringRow: Secondary row that will be below the Primary
|
|
/// - Returns: Amount of space that should live between these rows based off of the items. The largest space will win when the comparison occurs.
|
|
static func getVerticalSpacing(for row: ButtonCollectionViewRow, neighboringRow: ButtonCollectionViewRow?) -> CGFloat {
|
|
// if the neighboringRow is nil, this is the last row in the collection
|
|
// so return no space
|
|
guard let neighboringRow else { return 0.0 }
|
|
|
|
let primaryTallestAttributes = getTallestAttributes(for: row)
|
|
let neighboringTallestAttributes = getTallestAttributes(for: neighboringRow)
|
|
|
|
if primaryTallestAttributes.count > 0 && neighboringTallestAttributes.count > 0 {
|
|
// If there is a tie for “tallest child,” the tiebreaker criteria is to refer to the child with the larger space requirement (for vertical spacing).
|
|
var largestVerticalSpace = defaultSpace
|
|
|
|
primaryTallestAttributes.forEach { primaryAttribute in
|
|
neighboringTallestAttributes.forEach { neighboringTallestAttribute in
|
|
let space = getSpacing(for: .vertical, with: primaryAttribute.button!, neighboring: neighboringTallestAttribute.button!)
|
|
if space > largestVerticalSpace {
|
|
largestVerticalSpace = space
|
|
}
|
|
}
|
|
}
|
|
return largestVerticalSpace
|
|
}
|
|
else {
|
|
return defaultSpace
|
|
}
|
|
}
|
|
}
|