From 9c32ea4870ed483c41e36f8f89f95d384455f595 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 26 Jun 2024 09:50:06 -0500 Subject: [PATCH 01/15] redo constraints Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 146 +++++++++++------- 1 file changed, 89 insertions(+), 57 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 546d8d05..b6014e8f 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -179,11 +179,16 @@ open class TileContainerBase: Control where Padding //-------------------------------------------------- internal var widthConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint? - internal var heightGreaterThanConstraint: NSLayoutConstraint? - internal var containerTopConstraint: NSLayoutConstraint? - internal var containerBottomConstraint: NSLayoutConstraint? - internal var containerLeadingConstraint: NSLayoutConstraint? - internal var containerTrailingConstraint: NSLayoutConstraint? + + internal var containerViewBottomConstraint: NSLayoutConstraint? + internal var containerViewTrailingConstraint: NSLayoutConstraint? + internal var containerViewBottomLessThanOrEqualConstraint: NSLayoutConstraint? + internal var containerViewTrailingLessThanOrEqualConstraint: NSLayoutConstraint? + + internal var contentViewTopConstraint: NSLayoutConstraint? + internal var contentViewBottomConstraint: NSLayoutConstraint? + internal var contentViewLeadingConstraint: NSLayoutConstraint? + internal var contentViewTrailingConstraint: NSLayoutConstraint? //-------------------------------------------------- // MARK: - Configuration @@ -221,29 +226,25 @@ open class TileContainerBase: Control where Padding open override func setup() { super.setup() isAccessibilityElement = false - - let layoutGuide = UILayoutGuide() - addLayoutGuide(layoutGuide) - layoutGuide + addSubview(containerView) + containerView.addSubview(backgroundImageView) + containerView.addSubview(contentView) + containerView.addSubview(highlightView) + + containerView .pinTop() .pinLeading() - .pinTrailing(0, .defaultHigh) - .pinBottom(0, .defaultHigh) - addSubview(backgroundImageView) - addSubview(containerView) - containerView.addSubview(contentView) - addSubview(highlightView) - - containerView.pinToSuperView() - widthConstraint = layoutGuide.widthAnchor.constraint(equalToConstant: 0) - - heightGreaterThanConstraint = layoutGuide.heightAnchor.constraint(greaterThanOrEqualToConstant: 44.0) - heightGreaterThanConstraint?.isActive = false - - heightConstraint = layoutGuide.heightAnchor.constraint(equalToConstant: 0) - + containerViewTrailingConstraint = containerView.pinTrailing(anchor: trailingAnchor)?.deactivate() + containerViewBottomConstraint = containerView.pinBottom(anchor: bottomAnchor)?.deactivate() + + containerViewTrailingLessThanOrEqualConstraint = containerView.pinTrailingLessThanOrEqualTo(anchor: trailingAnchor)?.deactivate() + containerViewBottomLessThanOrEqualConstraint = containerView.pinBottomLessThanOrEqualTo(anchor: bottomAnchor)?.deactivate() + backgroundImageView.pinToSuperView() + + widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 0).deactivate() + heightConstraint = containerView.heightAnchor.constraint(equalToConstant: 0).deactivate() backgroundImageView.setContentHuggingPriority(.defaultLow, for: .horizontal) backgroundImageView.setContentHuggingPriority(.defaultLow, for: .vertical) @@ -252,20 +253,20 @@ open class TileContainerBase: Control where Padding backgroundImageView.isUserInteractionEnabled = false backgroundImageView.isHidden = true - containerTopConstraint = contentView.pinTop(anchor: layoutGuide.topAnchor, constant: padding.value) - containerBottomConstraint = layoutGuide.pinBottom(anchor: contentView.bottomAnchor, constant: padding.value) - containerLeadingConstraint = contentView.pinLeading(anchor: layoutGuide.leadingAnchor, constant: padding.value) - containerTrailingConstraint = layoutGuide.pinTrailing(anchor: contentView.trailingAnchor, constant: padding.value) + contentViewTopConstraint = contentView.pinTop(anchor: containerView.topAnchor, constant: padding.value) + contentViewBottomConstraint = containerView.pinBottom(anchor: contentView.bottomAnchor, constant: padding.value) + contentViewLeadingConstraint = contentView.pinLeading(anchor: containerView.leadingAnchor, constant: padding.value) + contentViewTrailingConstraint = containerView.pinTrailing(anchor: contentView.trailingAnchor, constant: padding.value) - highlightView.pin(layoutGuide) + highlightView.pin(containerView) highlightView.isHidden = true highlightView.backgroundColor = .clear //corner radius - layer.cornerRadius = cornerRadius + containerView.layer.cornerRadius = cornerRadius backgroundImageView.layer.cornerRadius = cornerRadius highlightView.layer.cornerRadius = cornerRadius - clipsToBounds = true + containerView.clipsToBounds = true containerView.bridge_isAccessibilityElementBlock = { [weak self] in self?.onClickSubscriber != nil } containerView.accessibilityHint = "Double tap to open." @@ -303,43 +304,74 @@ open class TileContainerBase: Control where Padding highlightView.backgroundColor = hightLightViewColorConfiguration.getColor(self) highlightView.isHidden = !isHighlighted - layer.borderColor = borderColorConfiguration.getColor(self).cgColor - layer.borderWidth = showBorder ? VDSFormControls.borderWidth : 0 + containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor + containerView.layer.borderWidth = showBorder ? VDSFormControls.borderWidth : 0 - containerTopConstraint?.constant = padding.value - containerLeadingConstraint?.constant = padding.value - containerBottomConstraint?.constant = padding.value - containerTrailingConstraint?.constant = padding.value + contentViewTopConstraint?.constant = padding.value + contentViewLeadingConstraint?.constant = padding.value + contentViewBottomConstraint?.constant = padding.value + contentViewTrailingConstraint?.constant = padding.value + //deactivate everything + widthConstraint?.deactivate() + heightConstraint?.deactivate() + containerViewTrailingLessThanOrEqualConstraint?.deactivate() + containerViewTrailingLessThanOrEqualConstraint?.deactivate() + containerViewBottomConstraint?.deactivate() + containerViewTrailingConstraint?.deactivate() + + //run logic to determine which to activate if let width, aspectRatio == .none && height == nil{ widthConstraint?.constant = width - widthConstraint?.isActive = true - heightConstraint?.isActive = false - heightGreaterThanConstraint?.isActive = true + widthConstraint?.activate() + containerViewTrailingConstraint?.activate() + containerViewBottomConstraint?.activate() + + } else if let height, aspectRatio == .none && width == nil{ + heightConstraint?.constant = height + heightConstraint?.activate() + containerViewTrailingConstraint?.activate() + containerViewBottomConstraint?.activate() + } else if let height, let width { widthConstraint?.constant = width heightConstraint?.constant = height - heightConstraint?.isActive = true - widthConstraint?.isActive = true - heightGreaterThanConstraint?.isActive = false + heightConstraint?.activate() + widthConstraint?.activate() + containerViewTrailingLessThanOrEqualConstraint?.activate() + containerViewBottomLessThanOrEqualConstraint?.activate() + } else if let width { let size = ratioSize(for: width) widthConstraint?.constant = size.width heightConstraint?.constant = size.height - widthConstraint?.isActive = true - heightConstraint?.isActive = true - heightGreaterThanConstraint?.isActive = false + widthConstraint?.activate() + heightConstraint?.activate() + containerViewTrailingLessThanOrEqualConstraint?.activate() + containerViewBottomLessThanOrEqualConstraint?.activate() + + } else if let height { + let size = ratioSize(for: height) + //enforce exact height/width + widthConstraint?.constant = size.width + heightConstraint?.constant = size.height + widthConstraint?.activate() + heightConstraint?.activate() + containerViewTrailingLessThanOrEqualConstraint?.activate() + containerViewBottomLessThanOrEqualConstraint?.activate() + } else { - widthConstraint?.isActive = false - heightConstraint?.isActive = false + //set to the parent view + containerViewBottomConstraint?.activate() + containerViewTrailingConstraint?.activate() } applyBackgroundEffects() if showDropShadow, surface == .light { - addDropShadow(dropShadowConfiguration) + containerView.addDropShadow(dropShadowConfiguration) } else { - removeDropShadows() + containerView.removeDropShadows() } } @@ -372,8 +404,8 @@ open class TileContainerBase: Control where Padding /// Used to update frames for the added CAlayers to our view open override func layoutSubviews() { super.layoutSubviews() - dropShadowLayers?.forEach { $0.frame = bounds } - gradientLayers?.forEach { $0.frame = bounds } + containerView.dropShadowLayers?.forEach { $0.frame = bounds } + containerView.gradientLayers?.forEach { $0.frame = bounds } } //-------------------------------------------------- @@ -400,25 +432,25 @@ open class TileContainerBase: Control where Padding switch backgroundEffect { case .transparency: alphaConfiguration = 0.8 - removeGradientLayer() + containerView.removeGradientLayer() case .gradient(let firstColor, let secondColor): alphaConfiguration = 1.0 - addGradientLayer(with: firstColor, secondColor: secondColor) + containerView.addGradientLayer(with: firstColor, secondColor: secondColor) backgroundImageView.isHidden = true backgroundImageView.alpha = 1.0 case .none: alphaConfiguration = 1.0 - removeGradientLayer() + containerView.removeGradientLayer() } if let backgroundImage { backgroundImageView.image = backgroundImage backgroundImageView.isHidden = false backgroundImageView.alpha = alphaConfiguration - backgroundColor = imageFallbackColor.withAlphaComponent(alphaConfiguration) + containerView.backgroundColor = imageFallbackColor.withAlphaComponent(alphaConfiguration) } else { backgroundImageView.isHidden = true backgroundImageView.alpha = 1.0 - backgroundColor = color.withAlphaComponent(alphaConfiguration) + containerView.backgroundColor = color.withAlphaComponent(alphaConfiguration) } } From a432534e1a095953c1336003460abcb9d51dc87a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 26 Jun 2024 13:28:39 -0500 Subject: [PATCH 02/15] updated constraints Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index b6014e8f..3e3b2ddf 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -179,10 +179,12 @@ open class TileContainerBase: Control where Padding //-------------------------------------------------- internal var widthConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint? - - internal var containerViewBottomConstraint: NSLayoutConstraint? + + internal var containerViewCenterXConstraint: NSLayoutConstraint? + internal var containerViewLeadingConstraint: NSLayoutConstraint? + internal var containerViewLeadingGreaterThanOrEqualConstraint: NSLayoutConstraint? + internal var containerViewTrailingConstraint: NSLayoutConstraint? - internal var containerViewBottomLessThanOrEqualConstraint: NSLayoutConstraint? internal var containerViewTrailingLessThanOrEqualConstraint: NSLayoutConstraint? internal var contentViewTopConstraint: NSLayoutConstraint? @@ -233,14 +235,15 @@ open class TileContainerBase: Control where Padding containerView .pinTop() - .pinLeading() + .pinBottom() + containerViewCenterXConstraint = containerView.pinCenterX(anchor: centerXAnchor)?.deactivate() + containerViewLeadingConstraint = containerView.pinLeading(anchor: leadingAnchor)?.deactivate() + containerViewLeadingGreaterThanOrEqualConstraint = containerView.pinLeadingGreaterThanOrEqualTo(anchor: leadingAnchor)?.deactivate() + containerViewTrailingConstraint = containerView.pinTrailing(anchor: trailingAnchor)?.deactivate() - containerViewBottomConstraint = containerView.pinBottom(anchor: bottomAnchor)?.deactivate() - containerViewTrailingLessThanOrEqualConstraint = containerView.pinTrailingLessThanOrEqualTo(anchor: trailingAnchor)?.deactivate() - containerViewBottomLessThanOrEqualConstraint = containerView.pinBottomLessThanOrEqualTo(anchor: bottomAnchor)?.deactivate() - + backgroundImageView.pinToSuperView() widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 0).deactivate() @@ -315,31 +318,40 @@ open class TileContainerBase: Control where Padding //deactivate everything widthConstraint?.deactivate() heightConstraint?.deactivate() + + containerViewCenterXConstraint?.deactivate() + + containerViewLeadingGreaterThanOrEqualConstraint?.deactivate() + containerViewLeadingConstraint?.deactivate() + containerViewTrailingLessThanOrEqualConstraint?.deactivate() - containerViewTrailingLessThanOrEqualConstraint?.deactivate() - containerViewBottomConstraint?.deactivate() containerViewTrailingConstraint?.deactivate() + print("Width: \(width?.description ?? "none")") + print("Height: \(height?.description ?? "none")") + //run logic to determine which to activate if let width, aspectRatio == .none && height == nil{ widthConstraint?.constant = width widthConstraint?.activate() - containerViewTrailingConstraint?.activate() - containerViewBottomConstraint?.activate() + containerViewCenterXConstraint?.activate() + containerViewLeadingGreaterThanOrEqualConstraint?.activate() + containerViewTrailingLessThanOrEqualConstraint?.activate() } else if let height, aspectRatio == .none && width == nil{ heightConstraint?.constant = height heightConstraint?.activate() + containerViewLeadingConstraint?.activate() containerViewTrailingConstraint?.activate() - containerViewBottomConstraint?.activate() } else if let height, let width { widthConstraint?.constant = width heightConstraint?.constant = height heightConstraint?.activate() widthConstraint?.activate() + containerViewCenterXConstraint?.activate() + containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() - containerViewBottomLessThanOrEqualConstraint?.activate() } else if let width { let size = ratioSize(for: width) @@ -347,22 +359,23 @@ open class TileContainerBase: Control where Padding heightConstraint?.constant = size.height widthConstraint?.activate() heightConstraint?.activate() + containerViewCenterXConstraint?.activate() + containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() - containerViewBottomLessThanOrEqualConstraint?.activate() } else if let height { let size = ratioSize(for: height) - //enforce exact height/width widthConstraint?.constant = size.width heightConstraint?.constant = size.height widthConstraint?.activate() heightConstraint?.activate() + containerViewCenterXConstraint?.activate() + containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() - containerViewBottomLessThanOrEqualConstraint?.activate() } else { //set to the parent view - containerViewBottomConstraint?.activate() + containerViewLeadingConstraint?.activate() containerViewTrailingConstraint?.activate() } From db3ba4f1a1726d869d5fc1dabffbe10e6895066e Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 26 Jun 2024 13:29:45 -0500 Subject: [PATCH 03/15] reset to start with none Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 4 ++-- VDS/Components/Tilelet/Tilelet.swift | 9 ++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 3e3b2ddf..d2425464 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -126,7 +126,7 @@ open class TileContainerBase: Control where Padding } /// This controls the aspect ratio for the component. - open var aspectRatio: AspectRatio = .ratio1x1 { didSet { setNeedsUpdate() } } + open var aspectRatio: AspectRatio = .none { didSet { setNeedsUpdate() } } /// Sets the background color for the component. open var color: BackgroundColor? { didSet { setNeedsUpdate() } } @@ -290,7 +290,7 @@ open class TileContainerBase: Control where Padding super.reset() shouldUpdateView = false color = .white - aspectRatio = .ratio1x1 + aspectRatio = .none imageFallbackColor = .light width = nil height = nil diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 95acf895..0a7178e2 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -302,7 +302,6 @@ open class Tilelet: TileContainerBase { /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() - aspectRatio = .none color = .black addContentView(stackView) @@ -386,7 +385,6 @@ open class Tilelet: TileContainerBase { /// Resets to default settings. open override func reset() { shouldUpdateView = false - aspectRatio = .none color = .black //models badgeModel = nil @@ -405,11 +403,7 @@ open class Tilelet: TileContainerBase { updateBadge() updateTitleLockup() updateIcons() - ///Content-driven height Tilelets - Minimum height is configurable. - ///if width != nil && (aspectRatio != .none || height != nil) then tilelet is not self growing, so we can apply text position alignments. - if width != nil && (aspectRatio != .none || height != nil) { - updateTextPositionAlignment() - } + updateTextPositionAlignment() setNeedsLayout() } @@ -584,6 +578,7 @@ open class Tilelet: TileContainerBase { } private func updateTextPositionAlignment() { + guard width != nil && (aspectRatio != .none || height != nil) else { return } switch textPostion { case .top: titleLockupTopConstraint?.activate() From bd908aeb471559b44a03cc3a22a0d93774a9177b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 26 Jun 2024 13:31:29 -0500 Subject: [PATCH 04/15] removed logic Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index d2425464..ad356065 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -326,10 +326,7 @@ open class TileContainerBase: Control where Padding containerViewTrailingLessThanOrEqualConstraint?.deactivate() containerViewTrailingConstraint?.deactivate() - - print("Width: \(width?.description ?? "none")") - print("Height: \(height?.description ?? "none")") - + //run logic to determine which to activate if let width, aspectRatio == .none && height == nil{ widthConstraint?.constant = width From 0f368b5132fb0108b387092c6fd1e8d0d31c01c4 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 26 Jun 2024 15:46:37 -0500 Subject: [PATCH 05/15] updated constraints Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index ad356065..c2d03aea 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -180,7 +180,6 @@ open class TileContainerBase: Control where Padding internal var widthConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint? - internal var containerViewCenterXConstraint: NSLayoutConstraint? internal var containerViewLeadingConstraint: NSLayoutConstraint? internal var containerViewLeadingGreaterThanOrEqualConstraint: NSLayoutConstraint? @@ -235,9 +234,9 @@ open class TileContainerBase: Control where Padding containerView .pinTop() + .pinCenterX() .pinBottom() - containerViewCenterXConstraint = containerView.pinCenterX(anchor: centerXAnchor)?.deactivate() containerViewLeadingConstraint = containerView.pinLeading(anchor: leadingAnchor)?.deactivate() containerViewLeadingGreaterThanOrEqualConstraint = containerView.pinLeadingGreaterThanOrEqualTo(anchor: leadingAnchor)?.deactivate() @@ -318,9 +317,7 @@ open class TileContainerBase: Control where Padding //deactivate everything widthConstraint?.deactivate() heightConstraint?.deactivate() - - containerViewCenterXConstraint?.deactivate() - + containerViewLeadingGreaterThanOrEqualConstraint?.deactivate() containerViewLeadingConstraint?.deactivate() @@ -331,7 +328,6 @@ open class TileContainerBase: Control where Padding if let width, aspectRatio == .none && height == nil{ widthConstraint?.constant = width widthConstraint?.activate() - containerViewCenterXConstraint?.activate() containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() @@ -346,7 +342,6 @@ open class TileContainerBase: Control where Padding heightConstraint?.constant = height heightConstraint?.activate() widthConstraint?.activate() - containerViewCenterXConstraint?.activate() containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() @@ -356,7 +351,6 @@ open class TileContainerBase: Control where Padding heightConstraint?.constant = size.height widthConstraint?.activate() heightConstraint?.activate() - containerViewCenterXConstraint?.activate() containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() @@ -366,7 +360,6 @@ open class TileContainerBase: Control where Padding heightConstraint?.constant = size.height widthConstraint?.activate() heightConstraint?.activate() - containerViewCenterXConstraint?.activate() containerViewLeadingGreaterThanOrEqualConstraint?.activate() containerViewTrailingLessThanOrEqualConstraint?.activate() From 742bae9169e9f95ff3a6fd3f427f7062bda82dab Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 26 Jun 2024 17:19:17 -0500 Subject: [PATCH 06/15] Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index c2d03aea..03e320e7 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -364,7 +364,6 @@ open class TileContainerBase: Control where Padding containerViewTrailingLessThanOrEqualConstraint?.activate() } else { - //set to the parent view containerViewLeadingConstraint?.activate() containerViewTrailingConstraint?.activate() } From 5fcc59d8af7bff1bbacd6e62a82176001509595e Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 09:48:52 -0500 Subject: [PATCH 07/15] added helpers methods to layoutconstrainable Signed-off-by: Matt Bruce --- VDS/Protocols/LayoutConstraintable.swift | 124 +++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/VDS/Protocols/LayoutConstraintable.swift b/VDS/Protocols/LayoutConstraintable.swift index 3e40885b..3661bae0 100644 --- a/VDS/Protocols/LayoutConstraintable.swift +++ b/VDS/Protocols/LayoutConstraintable.swift @@ -631,6 +631,130 @@ extension LayoutConstraintable { return centerYAnchor.constraint(greaterThanOrEqualTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } } } + +// alignment +public enum LayoutAlignment: String, CaseIterable { + case fill + case leading + case top + case center + case trailing + case bottom +} + +public enum LayoutDistribution: String, CaseIterable { + case fill + case fillProportionally +} + +extension LayoutConstraintable { + public func removeConstraints() { + guard let view = self as? UIView, let superview = view.superview else { return } + + // Remove all existing constraints on the containerView + let superviewConstraints = superview.constraints + for constraint in superviewConstraints { + if constraint.firstItem as? UIView == view + || constraint.secondItem as? UIView == view { + superview.removeConstraint(constraint) + } + } + } + + public func applyAlignment(_ alignment: LayoutAlignment, edges: UIEdgeInsets = UIEdgeInsets.zero) { + guard let superview = superview else { return } + + removeConstraints() + + switch alignment { + case .fill: + pinToSuperView(edges) + + case .leading: + pinTop(edges.top) + pinLeading(edges.left) + pinTrailingLessThanOrEqualTo(anchor: superview.trailingAnchor, constant: edges.right) + pinBottom(edges.bottom) + + case .trailing: + pinTop(edges.top) + pinLeadingGreaterThanOrEqualTo(anchor: superview.leadingAnchor, constant: edges.left) + pinTrailing(edges.right) + pinBottom(edges.bottom) + + case .top: + pinTop(edges.top) + pinLeadingGreaterThanOrEqualTo(anchor: superview.leadingAnchor, constant: edges.left) + pinTrailingLessThanOrEqualTo(anchor: superview.trailingAnchor, constant: edges.right) + pinBottomLessThanOrEqualTo(anchor: superview.bottomAnchor, constant: edges.bottom) + + case .bottom: + pinTopGreaterThanOrEqualTo(anchor: superview.topAnchor, constant: edges.top) + pinLeadingGreaterThanOrEqualTo(anchor: superview.leadingAnchor, constant: edges.left) + pinTrailingLessThanOrEqualTo(anchor: superview.trailingAnchor, constant: edges.right) + pinBottom(edges.bottom) + + case .center: + pinCenterX() + pinTop(edges.top) + pinLeadingGreaterThanOrEqualTo(anchor: superview.leadingAnchor, constant: edges.left) + pinTrailingLessThanOrEqualTo(anchor: superview.trailingAnchor, constant: edges.right) + pinBottom(edges.bottom) + + } + } + + // Method to check if the view is pinned to its superview + public func isPinnedToSuperview() -> Bool { + isPinnedVerticallyToSuperview() && isPinnedHorizontallyToSuperview() + } + + public func isPinnedHorizontallyToSuperview() -> Bool { + guard let view = self as? UIView, let superview = view.superview else { return false } + let constraints = superview.constraints + var leadingPinned = false + var trailingPinned = false + + for constraint in constraints { + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .leading && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .leading && constraint.relation == .equal && constraint.firstItem as? UIView == superview) || + (constraint.firstItem as? UIView == view && constraint.firstAttribute == .left && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .left && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + leadingPinned = true + } + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .trailing && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .trailing && constraint.relation == .equal && constraint.firstItem as? UIView == superview) || + (constraint.firstItem as? UIView == view && constraint.firstAttribute == .right && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .right && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + trailingPinned = true + } + } + + return leadingPinned && trailingPinned + } + + public func isPinnedVerticallyToSuperview() -> Bool { + guard let view = self as? UIView, let superview = view.superview else { return false } + let constraints = superview.constraints + var topPinned = false + var bottomPinned = false + + for constraint in constraints { + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .top && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .top && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + topPinned = true + } + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .bottom && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .bottom && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + bottomPinned = true + } + } + + return topPinned && bottomPinned + } +} + + //-------------------------------------------------- // MARK: - Implementations //-------------------------------------------------- From 289353a4432dbb774122f8ff75a5237e6eaf4a83 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 09:55:37 -0500 Subject: [PATCH 08/15] refactored to final fix, hopefully :D Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 162 ++++++++---------- 1 file changed, 75 insertions(+), 87 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 03e320e7..9b121aa1 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -44,6 +44,7 @@ open class TileContainer: TileContainerBase { } open class TileContainerBase: Control where PaddingType.ValueType == CGFloat { + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -109,7 +110,16 @@ open class TileContainerBase: Control where Padding $0.clipsToBounds = true } - internal var containerView = View() + open var containerView = View().with { + $0.setContentHuggingPriority(.defaultLow, for: .horizontal) + $0.setContentHuggingPriority(.defaultLow, for: .vertical) + $0.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + $0.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) + } + + open var distribution: LayoutDistribution = .fill { didSet { setNeedsUpdate() } } + + open var alignment: LayoutAlignment = .center { didSet { setNeedsUpdate() } } //-------------------------------------------------- // MARK: - Public Properties @@ -180,12 +190,6 @@ open class TileContainerBase: Control where Padding internal var widthConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint? - internal var containerViewLeadingConstraint: NSLayoutConstraint? - internal var containerViewLeadingGreaterThanOrEqualConstraint: NSLayoutConstraint? - - internal var containerViewTrailingConstraint: NSLayoutConstraint? - internal var containerViewTrailingLessThanOrEqualConstraint: NSLayoutConstraint? - internal var contentViewTopConstraint: NSLayoutConstraint? internal var contentViewBottomConstraint: NSLayoutConstraint? internal var contentViewLeadingConstraint: NSLayoutConstraint? @@ -232,17 +236,6 @@ open class TileContainerBase: Control where Padding containerView.addSubview(contentView) containerView.addSubview(highlightView) - containerView - .pinTop() - .pinCenterX() - .pinBottom() - - containerViewLeadingConstraint = containerView.pinLeading(anchor: leadingAnchor)?.deactivate() - containerViewLeadingGreaterThanOrEqualConstraint = containerView.pinLeadingGreaterThanOrEqualTo(anchor: leadingAnchor)?.deactivate() - - containerViewTrailingConstraint = containerView.pinTrailing(anchor: trailingAnchor)?.deactivate() - containerViewTrailingLessThanOrEqualConstraint = containerView.pinTrailingLessThanOrEqualTo(anchor: trailingAnchor)?.deactivate() - backgroundImageView.pinToSuperView() widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 0).deactivate() @@ -313,70 +306,10 @@ open class TileContainerBase: Control where Padding contentViewLeadingConstraint?.constant = padding.value contentViewBottomConstraint?.constant = padding.value contentViewTrailingConstraint?.constant = padding.value - - //deactivate everything - widthConstraint?.deactivate() - heightConstraint?.deactivate() - containerViewLeadingGreaterThanOrEqualConstraint?.deactivate() - containerViewLeadingConstraint?.deactivate() - - containerViewTrailingLessThanOrEqualConstraint?.deactivate() - containerViewTrailingConstraint?.deactivate() - - //run logic to determine which to activate - if let width, aspectRatio == .none && height == nil{ - widthConstraint?.constant = width - widthConstraint?.activate() - containerViewLeadingGreaterThanOrEqualConstraint?.activate() - containerViewTrailingLessThanOrEqualConstraint?.activate() - - } else if let height, aspectRatio == .none && width == nil{ - heightConstraint?.constant = height - heightConstraint?.activate() - containerViewLeadingConstraint?.activate() - containerViewTrailingConstraint?.activate() - - } else if let height, let width { - widthConstraint?.constant = width - heightConstraint?.constant = height - heightConstraint?.activate() - widthConstraint?.activate() - containerViewLeadingGreaterThanOrEqualConstraint?.activate() - containerViewTrailingLessThanOrEqualConstraint?.activate() - - } else if let width { - let size = ratioSize(for: width) - widthConstraint?.constant = size.width - heightConstraint?.constant = size.height - widthConstraint?.activate() - heightConstraint?.activate() - containerViewLeadingGreaterThanOrEqualConstraint?.activate() - containerViewTrailingLessThanOrEqualConstraint?.activate() - - } else if let height { - let size = ratioSize(for: height) - widthConstraint?.constant = size.width - heightConstraint?.constant = size.height - widthConstraint?.activate() - heightConstraint?.activate() - containerViewLeadingGreaterThanOrEqualConstraint?.activate() - containerViewTrailingLessThanOrEqualConstraint?.activate() - - } else { - containerViewLeadingConstraint?.activate() - containerViewTrailingConstraint?.activate() - } - - applyBackgroundEffects() - - if showDropShadow, surface == .light { - containerView.addDropShadow(dropShadowConfiguration) - } else { - containerView.removeDropShadows() - } + updateContainerView() } - + open override var accessibilityElements: [Any]? { get { var items = [Any]() @@ -403,13 +336,6 @@ open class TileContainerBase: Control where Padding set {} } - /// Used to update frames for the added CAlayers to our view - open override func layoutSubviews() { - super.layoutSubviews() - containerView.dropShadowLayers?.forEach { $0.frame = bounds } - containerView.gradientLayers?.forEach { $0.frame = bounds } - } - //-------------------------------------------------- // MARK: - Public Methods //-------------------------------------------------- @@ -485,7 +411,69 @@ open class TileContainerBase: Control where Padding return CGSize(width: width, height: height) } + + private func sizeContainerView(width: CGFloat? = nil, height: CGFloat? = nil) { + if let width, width > 0 { + widthConstraint?.constant = width + widthConstraint?.activate() + } + + if let height, height > 0 { + heightConstraint?.constant = height + heightConstraint?.activate() + } + } + + private func updateContainerView() { + applyBackgroundEffects() + + widthConstraint?.deactivate() + heightConstraint?.deactivate() + if showDropShadow, surface == .light { + containerView.addDropShadow(dropShadowConfiguration) + } else { + containerView.removeDropShadows() + } + + containerView.dropShadowLayers?.forEach { $0.frame = bounds } + containerView.gradientLayers?.forEach { $0.frame = bounds } + + if width != nil || height != nil { + var containerViewWidth: CGFloat? + var containerViewHeight: CGFloat? + //run logic to determine which to activate + if let width, aspectRatio == .none && height == nil{ + containerViewWidth = width + + } else if let height, aspectRatio == .none && width == nil{ + containerViewHeight = height + + } else if let height, let width { + containerViewWidth = width + containerViewHeight = height + + } else if let width { + let size = ratioSize(for: width) + containerViewWidth = size.width + containerViewHeight = size.height + + } else if let height { + let size = ratioSize(for: height) + containerViewWidth = size.width + containerViewHeight = size.height + } + + sizeContainerView(width: containerViewWidth, height: containerViewHeight) + containerView.applyAlignment(alignment) + + } else { + containerView.applyAlignment(distribution == .fill ? .fill : alignment) + if let superview, distribution == .fill, !isPinnedHorizontallyToSuperview() { + sizeContainerView(width: superview.frame.size.width) + } + } + } } extension TileContainerBase { From 1044282c33f8c90ee757736ad8fa3071eb5afb65 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 10:24:18 -0500 Subject: [PATCH 09/15] fixed bug Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 6 +++--- VDS/Protocols/LayoutConstraintable.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 9b121aa1..72ef86d0 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -436,9 +436,9 @@ open class TileContainerBase: Control where Padding containerView.removeDropShadows() } - containerView.dropShadowLayers?.forEach { $0.frame = bounds } - containerView.gradientLayers?.forEach { $0.frame = bounds } - + containerView.dropShadowLayers?.forEach { $0.frame = containerView.bounds } + containerView.gradientLayers?.forEach { $0.frame = containerView.bounds } + if width != nil || height != nil { var containerViewWidth: CGFloat? var containerViewHeight: CGFloat? diff --git a/VDS/Protocols/LayoutConstraintable.swift b/VDS/Protocols/LayoutConstraintable.swift index 3661bae0..18c89c14 100644 --- a/VDS/Protocols/LayoutConstraintable.swift +++ b/VDS/Protocols/LayoutConstraintable.swift @@ -714,7 +714,7 @@ extension LayoutConstraintable { let constraints = superview.constraints var leadingPinned = false var trailingPinned = false - + for constraint in constraints { if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .leading && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || (constraint.secondItem as? UIView == view && constraint.secondAttribute == .leading && constraint.relation == .equal && constraint.firstItem as? UIView == superview) || From 25ebcff2d904cbf7fb1c83958751ea87af14bc11 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 12:52:38 -0500 Subject: [PATCH 10/15] rotation checking update size Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 72ef86d0..62e96890 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -266,6 +266,15 @@ open class TileContainerBase: Control where Padding containerView.bridge_isAccessibilityElementBlock = { [weak self] in self?.onClickSubscriber != nil } containerView.accessibilityHint = "Double tap to open." containerView.accessibilityLabel = nil + + NotificationCenter.default + .publisher(for: UIDevice.orientationDidChangeNotification) + .sink() { [weak self] _ in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.001) { [weak self] in + guard let self else { return } + setNeedsUpdate() + } + }.store(in: &subscribers) } @@ -423,7 +432,7 @@ open class TileContainerBase: Control where Padding heightConstraint?.activate() } } - + private func updateContainerView() { applyBackgroundEffects() @@ -469,8 +478,8 @@ open class TileContainerBase: Control where Padding } else { containerView.applyAlignment(distribution == .fill ? .fill : alignment) - if let superview, distribution == .fill, !isPinnedHorizontallyToSuperview() { - sizeContainerView(width: superview.frame.size.width) + if distribution == .fill, !isPinnedHorizontallyToSuperview(), let size = horizontalPinnedSize() { + sizeContainerView(width: size.width) } } } From 8dfcb416914921bb055a5623fbd4ee326be6a423 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 12:52:52 -0500 Subject: [PATCH 11/15] refactor for layoutguide Signed-off-by: Matt Bruce --- VDS/Protocols/LayoutConstraintable.swift | 89 ++++++++++++++++++++---- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/VDS/Protocols/LayoutConstraintable.swift b/VDS/Protocols/LayoutConstraintable.swift index 18c89c14..ba08e3c2 100644 --- a/VDS/Protocols/LayoutConstraintable.swift +++ b/VDS/Protocols/LayoutConstraintable.swift @@ -709,6 +709,69 @@ extension LayoutConstraintable { isPinnedVerticallyToSuperview() && isPinnedHorizontallyToSuperview() } + public func horizontalPinnedSize() -> CGSize? { + guard let view = self as? UIView, let superview = view.superview else { return nil } + let constraints = superview.constraints + + var leadingPinnedObject: AnyObject? + var trailingPinnedObject: AnyObject? + + for constraint in constraints { + if (constraint.firstItem === view && (constraint.firstAttribute == .leading || constraint.firstAttribute == .left)) { + leadingPinnedObject = constraint.secondItem as AnyObject? + } else if (constraint.secondItem === view && (constraint.secondAttribute == .leading || constraint.secondAttribute == .left)) { + leadingPinnedObject = constraint.firstItem as AnyObject? + } else if (constraint.firstItem === view && (constraint.firstAttribute == .trailing || constraint.firstAttribute == .right)) { + trailingPinnedObject = constraint.secondItem as AnyObject? + } else if (constraint.secondItem === view && (constraint.secondAttribute == .trailing || constraint.secondAttribute == .right)) { + trailingPinnedObject = constraint.firstItem as AnyObject? + } + } + + // Ensure both leading and trailing pinned objects are identified + if let leadingObject = leadingPinnedObject, let trailingObject = trailingPinnedObject { + + // Calculate the size based on the pinned objects + if let leadingView = leadingObject as? UIView, let trailingView = trailingObject as? UIView { + let leadingPosition = leadingView.convert(leadingView.bounds.origin, to: superview).x + let trailingPosition = trailingView.convert(trailingView.bounds.origin, to: superview).x + trailingView.bounds.width + return CGSize(width: trailingPosition - leadingPosition, height: view.bounds.size.height) + + } else if let leadingGuide = leadingObject as? UILayoutGuide, let trailingGuide = trailingObject as? UILayoutGuide { + let leadingPosition = leadingGuide.layoutFrame.minX + let trailingPosition = trailingGuide.layoutFrame.maxX + return CGSize(width: trailingPosition - leadingPosition, height: view.bounds.size.height) + + } else if let leadingView = leadingObject as? UIView, let trailingGuide = trailingObject as? UILayoutGuide { + let leadingPosition = leadingView.convert(leadingView.bounds.origin, to: superview).x + let trailingPosition = trailingGuide.layoutFrame.maxX + return CGSize(width: trailingPosition - leadingPosition, height: view.bounds.size.height) + + } else if let leadingGuide = leadingObject as? UILayoutGuide, let trailingView = trailingObject as? UIView { + let leadingPosition = leadingGuide.layoutFrame.minX + let trailingPosition = trailingView.convert(trailingView.bounds.origin, to: superview).x + trailingView.bounds.width + return CGSize(width: trailingPosition - leadingPosition, height: view.bounds.size.height) + } + + } else if let pinnedObject = leadingPinnedObject { + if let view = pinnedObject as? UIView { + return view.bounds.size + } else if let layoutGuide = pinnedObject as? UILayoutGuide { + return layoutGuide.layoutFrame.size + } + + } else if let pinnedObject = trailingPinnedObject { + if let view = pinnedObject as? UIView { + return view.bounds.size + } else if let layoutGuide = pinnedObject as? UILayoutGuide { + return layoutGuide.layoutFrame.size + } + + } + + return nil + } + public func isPinnedHorizontallyToSuperview() -> Bool { guard let view = self as? UIView, let superview = view.superview else { return false } let constraints = superview.constraints @@ -716,16 +779,16 @@ extension LayoutConstraintable { var trailingPinned = false for constraint in constraints { - if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .leading && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || - (constraint.secondItem as? UIView == view && constraint.secondAttribute == .leading && constraint.relation == .equal && constraint.firstItem as? UIView == superview) || - (constraint.firstItem as? UIView == view && constraint.firstAttribute == .left && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || - (constraint.secondItem as? UIView == view && constraint.secondAttribute == .left && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .leading && constraint.relation == .equal) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .leading && constraint.relation == .equal) || + (constraint.firstItem as? UIView == view && constraint.firstAttribute == .left && constraint.relation == .equal) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .left && constraint.relation == .equal) { leadingPinned = true } - if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .trailing && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || - (constraint.secondItem as? UIView == view && constraint.secondAttribute == .trailing && constraint.relation == .equal && constraint.firstItem as? UIView == superview) || - (constraint.firstItem as? UIView == view && constraint.firstAttribute == .right && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || - (constraint.secondItem as? UIView == view && constraint.secondAttribute == .right && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .trailing && constraint.relation == .equal) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .trailing && constraint.relation == .equal) || + (constraint.firstItem as? UIView == view && constraint.firstAttribute == .right && constraint.relation == .equal) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .right && constraint.relation == .equal) { trailingPinned = true } } @@ -740,18 +803,20 @@ extension LayoutConstraintable { var bottomPinned = false for constraint in constraints { - if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .top && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || - (constraint.secondItem as? UIView == view && constraint.secondAttribute == .top && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .top && constraint.relation == .equal) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .top && constraint.relation == .equal) { topPinned = true } - if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .bottom && constraint.relation == .equal && constraint.secondItem as? UIView == superview) || - (constraint.secondItem as? UIView == view && constraint.secondAttribute == .bottom && constraint.relation == .equal && constraint.firstItem as? UIView == superview) { + if (constraint.firstItem as? UIView == view && constraint.firstAttribute == .bottom && constraint.relation == .equal) || + (constraint.secondItem as? UIView == view && constraint.secondAttribute == .bottom && constraint.relation == .equal) { bottomPinned = true } } return topPinned && bottomPinned } + + } From 9db5257132e4d5d1c0c9760c96730a6f9d81c28a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 13:16:52 -0500 Subject: [PATCH 12/15] align left Signed-off-by: Matt Bruce --- VDS/Components/DatePicker/DatePicker.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS/Components/DatePicker/DatePicker.swift b/VDS/Components/DatePicker/DatePicker.swift index cb2b5b88..17ededf4 100644 --- a/VDS/Components/DatePicker/DatePicker.swift +++ b/VDS/Components/DatePicker/DatePicker.swift @@ -370,7 +370,7 @@ extension DatePicker { var popoverY: CGFloat = 0 // Calculate horizontal position - if sourceFrameInParent.width < popoverWidth { + if sourceFrameInParent.width <= popoverWidth { if sourceFrameInParent.midX - popoverWidth / 2 < 0 { // Align to left popoverX = sourceFrameInParent.minX @@ -382,7 +382,7 @@ extension DatePicker { popoverX = sourceFrameInParent.midX - popoverWidth / 2 } } else { - popoverX = sourceFrameInParent.midX - popoverWidth / 2 + popoverX = sourceFrameInParent.minX //sourceFrameInParent.midX - popoverWidth / 2 } // Ensure the popover is within the parent's bounds horizontally From 7d399a42ef216f5474fd85a561266c9f980f09fa Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jun 2024 15:10:30 -0500 Subject: [PATCH 13/15] fixed animation Signed-off-by: Matt Bruce --- VDS/Components/Toggle/ToggleView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Toggle/ToggleView.swift b/VDS/Components/Toggle/ToggleView.swift index 935ed519..dc5e9570 100644 --- a/VDS/Components/Toggle/ToggleView.swift +++ b/VDS/Components/Toggle/ToggleView.swift @@ -219,7 +219,7 @@ open class ToggleView: Control, Changeable, FormFieldable { } knobTrailingConstraint?.isActive = true knobLeadingConstraint?.isActive = true - setNeedsLayout() + layoutIfNeeded() } private func updateToggle() { From 842bb6f0ad55c36cf7fadaf5c3ff40205db3e04e Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 28 Jun 2024 18:08:50 -0500 Subject: [PATCH 14/15] updated to work at 100% width of parent if not set as well as calculating height if there is an aspect ration. --- .../TileContainer/TileContainer.swift | 63 +++++++++---------- VDS/Components/Tilelet/Tilelet.swift | 4 ++ 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 62e96890..d7c3f74f 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -117,10 +117,6 @@ open class TileContainerBase: Control where Padding $0.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) } - open var distribution: LayoutDistribution = .fill { didSet { setNeedsUpdate() } } - - open var alignment: LayoutAlignment = .center { didSet { setNeedsUpdate() } } - //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -136,7 +132,7 @@ open class TileContainerBase: Control where Padding } /// This controls the aspect ratio for the component. - open var aspectRatio: AspectRatio = .none { didSet { setNeedsUpdate() } } + open var aspectRatio: AspectRatio = .ratio1x1 { didSet { setNeedsUpdate() } } /// Sets the background color for the component. open var color: BackgroundColor? { didSet { setNeedsUpdate() } } @@ -190,11 +186,6 @@ open class TileContainerBase: Control where Padding internal var widthConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint? - internal var contentViewTopConstraint: NSLayoutConstraint? - internal var contentViewBottomConstraint: NSLayoutConstraint? - internal var contentViewLeadingConstraint: NSLayoutConstraint? - internal var contentViewTrailingConstraint: NSLayoutConstraint? - //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- @@ -231,15 +222,21 @@ open class TileContainerBase: Control where Padding open override func setup() { super.setup() isAccessibilityElement = false + addSubview(containerView) + containerView.pinToSuperView() + containerView.addSubview(backgroundImageView) - containerView.addSubview(contentView) - containerView.addSubview(highlightView) - backgroundImageView.pinToSuperView() - widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 0).deactivate() - heightConstraint = containerView.heightAnchor.constraint(equalToConstant: 0).deactivate() + containerView.addSubview(contentView) + contentView.pinToSuperView() + + containerView.addSubview(highlightView) + highlightView.pinToSuperView() + + widthConstraint = widthAnchor.constraint(equalToConstant: 0).deactivate() + heightConstraint = heightAnchor.constraint(equalToConstant: 0).deactivate() backgroundImageView.setContentHuggingPriority(.defaultLow, for: .horizontal) backgroundImageView.setContentHuggingPriority(.defaultLow, for: .vertical) @@ -248,19 +245,11 @@ open class TileContainerBase: Control where Padding backgroundImageView.isUserInteractionEnabled = false backgroundImageView.isHidden = true - contentViewTopConstraint = contentView.pinTop(anchor: containerView.topAnchor, constant: padding.value) - contentViewBottomConstraint = containerView.pinBottom(anchor: contentView.bottomAnchor, constant: padding.value) - contentViewLeadingConstraint = contentView.pinLeading(anchor: containerView.leadingAnchor, constant: padding.value) - contentViewTrailingConstraint = containerView.pinTrailing(anchor: contentView.trailingAnchor, constant: padding.value) - - highlightView.pin(containerView) highlightView.isHidden = true highlightView.backgroundColor = .clear //corner radius containerView.layer.cornerRadius = cornerRadius - backgroundImageView.layer.cornerRadius = cornerRadius - highlightView.layer.cornerRadius = cornerRadius containerView.clipsToBounds = true containerView.bridge_isAccessibilityElementBlock = { [weak self] in self?.onClickSubscriber != nil } @@ -311,11 +300,9 @@ open class TileContainerBase: Control where Padding containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor containerView.layer.borderWidth = showBorder ? VDSFormControls.borderWidth : 0 - contentViewTopConstraint?.constant = padding.value - contentViewLeadingConstraint?.constant = padding.value - contentViewBottomConstraint?.constant = padding.value - contentViewTrailingConstraint?.constant = padding.value - + contentView.removeConstraints() + contentView.pinToSuperView(.uniform(padding.value)) + updateContainerView() } @@ -472,14 +459,22 @@ open class TileContainerBase: Control where Padding containerViewWidth = size.width containerViewHeight = size.height } - sizeContainerView(width: containerViewWidth, height: containerViewHeight) - containerView.applyAlignment(alignment) - } else { - containerView.applyAlignment(distribution == .fill ? .fill : alignment) - if distribution == .fill, !isPinnedHorizontallyToSuperview(), let size = horizontalPinnedSize() { - sizeContainerView(width: size.width) + if let parentSize = horizontalPinnedSize() { + + var containerViewWidth: CGFloat? + var containerViewHeight: CGFloat? + + let size = ratioSize(for: parentSize.width) + if aspectRatio == .none { + containerViewWidth = size.width + } else { + containerViewWidth = size.width + containerViewHeight = size.height + } + + sizeContainerView(width: containerViewWidth, height: containerViewHeight) } } } diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 0a7178e2..0da20709 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -303,6 +303,8 @@ open class Tilelet: TileContainerBase { open override func setup() { super.setup() color = .black + aspectRatio = .none + addContentView(stackView) //badge @@ -385,6 +387,8 @@ open class Tilelet: TileContainerBase { /// Resets to default settings. open override func reset() { shouldUpdateView = false + super.reset() + aspectRatio = .none color = .black //models badgeModel = nil From 540dc35e2f88e292a2f08711d255fff0a60f6beb Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 29 Jun 2024 09:45:14 -0500 Subject: [PATCH 15/15] added cornerRadius back Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index d7c3f74f..6eeaf316 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -250,6 +250,8 @@ open class TileContainerBase: Control where Padding //corner radius containerView.layer.cornerRadius = cornerRadius + backgroundImageView.layer.cornerRadius = cornerRadius + highlightView.layer.cornerRadius = cornerRadius containerView.clipsToBounds = true containerView.bridge_isAccessibilityElementBlock = { [weak self] in self?.onClickSubscriber != nil }