method to put provided views into a vertical stack view. • method to put provided buttons into a vertical stack view. All these would allow me to update reg flow screens to look the same without specifying layout metrics multiple times.
135 lines
4.7 KiB
Swift
135 lines
4.7 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import UIKit
|
|
|
|
public extension NSDirectionalEdgeInsets {
|
|
|
|
static var buttonContainerLayoutMargins: NSDirectionalEdgeInsets {
|
|
return .init(top: 0, leading: 12, bottom: 16, trailing: 12)
|
|
}
|
|
}
|
|
|
|
public extension UIStackView {
|
|
|
|
func addArrangedSubviews(_ subviews: [UIView]) {
|
|
for subview in subviews {
|
|
addArrangedSubview(subview)
|
|
}
|
|
}
|
|
|
|
func removeArrangedSubviewsAfter(_ subview: UIView) {
|
|
guard let subviewIndex = arrangedSubviews.firstIndex(of: subview) else { return }
|
|
|
|
let viewsToRemove = arrangedSubviews.suffix(from: subviewIndex.advanced(by: 1))
|
|
for view in viewsToRemove {
|
|
removeArrangedSubview(view)
|
|
}
|
|
}
|
|
|
|
func addHairline(with color: UIColor) {
|
|
insertHairline(with: color, at: arrangedSubviews.count)
|
|
}
|
|
|
|
func insertHairline(with color: UIColor, at index: Int) {
|
|
let hairlineView = UIView()
|
|
hairlineView.backgroundColor = color
|
|
hairlineView.autoSetDimension(.height, toSize: 1)
|
|
insertArrangedSubview(hairlineView, at: index)
|
|
}
|
|
|
|
func addBackgroundView(_ backgroundView: UIView) {
|
|
addSubview(backgroundView)
|
|
sendSubviewToBack(backgroundView)
|
|
backgroundView.autoPinEdgesToSuperviewEdges()
|
|
}
|
|
|
|
@discardableResult
|
|
func addBackgroundView(withBackgroundColor backgroundColor: UIColor, cornerRadius: CGFloat = 0) -> UIView {
|
|
let backgroundView = UIView(frame: bounds)
|
|
backgroundView.backgroundColor = backgroundColor
|
|
backgroundView.layer.cornerRadius = cornerRadius
|
|
self.addBackgroundView(backgroundView)
|
|
return backgroundView
|
|
}
|
|
|
|
/// Adds a `UIVisualEffectView` with a `UIBlurEffect` as a background to the view.
|
|
/// - Parameters:
|
|
/// - blur: The blur effect style to use.
|
|
/// - accessibilityFallbackColor: An optional fallback color when the
|
|
/// system "Reduce Transparency" accessibility feature is enabled. If this
|
|
/// is not set, the system automatically calculates a color to use.
|
|
/// - cornerRadius: The corner radius the background view should have.
|
|
/// - Returns: The background subview which has been added and pinned to the superview.
|
|
@discardableResult
|
|
func addBackgroundBlurView(
|
|
blur: UIBlurEffect.Style,
|
|
accessibilityFallbackColor: UIColor? = nil,
|
|
cornerRadius: CGFloat = 0
|
|
) -> UIView {
|
|
if
|
|
UIAccessibility.isReduceTransparencyEnabled,
|
|
let accessibilityFallbackColor
|
|
{
|
|
return self.addBackgroundView(
|
|
withBackgroundColor: accessibilityFallbackColor,
|
|
cornerRadius: cornerRadius
|
|
)
|
|
} else {
|
|
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: blur))
|
|
self.addBackgroundView(blurEffectView)
|
|
return blurEffectView
|
|
}
|
|
}
|
|
|
|
@discardableResult
|
|
func addBorderView(withColor color: UIColor, strokeWidth: CGFloat, cornerRadius: CGFloat = 0) -> UIView {
|
|
let borderView = UIView(frame: bounds)
|
|
borderView.isUserInteractionEnabled = false
|
|
borderView.backgroundColor = .clear
|
|
borderView.isOpaque = false
|
|
borderView.layer.borderColor = color.cgColor
|
|
borderView.layer.borderWidth = strokeWidth
|
|
borderView.layer.cornerRadius = cornerRadius
|
|
addSubview(borderView)
|
|
borderView.autoPinEdgesToSuperviewEdges()
|
|
return borderView
|
|
}
|
|
|
|
@discardableResult
|
|
func addPillBackgroundView(backgroundColor: UIColor) -> UIView {
|
|
let backgroundView = OWSLayerView.pillView()
|
|
backgroundView.backgroundColor = backgroundColor
|
|
self.addBackgroundView(backgroundView)
|
|
return backgroundView
|
|
}
|
|
|
|
class func verticalButtonStack(buttons: [UIButton], isFullWidthButtons: Bool = true) -> UIStackView {
|
|
let stackView = UIStackView(arrangedSubviews: buttons)
|
|
stackView.axis = .vertical
|
|
stackView.spacing = 12
|
|
stackView.alignment = isFullWidthButtons ? .fill : .center
|
|
stackView.isLayoutMarginsRelativeArrangement = true
|
|
stackView.directionalLayoutMargins = .buttonContainerLayoutMargins
|
|
return stackView
|
|
}
|
|
}
|
|
|
|
public extension UIView {
|
|
|
|
/// A Boolean value that determines whether the view is hidden while working
|
|
/// around a UIStackView bug where hidden subviews sometimes re-appear.
|
|
var isHiddenInStackView: Bool {
|
|
get { isHidden }
|
|
set {
|
|
// Setting isHidden to true when already hidden can cause layout issues
|
|
if isHidden != newValue {
|
|
isHidden = newValue
|
|
}
|
|
alpha = newValue ? 0 : 1
|
|
}
|
|
}
|
|
}
|