diff --git a/Examples/DemosApp/DemosApp.xcodeproj/project.pbxproj b/Examples/DemosApp/DemosApp.xcodeproj/project.pbxproj index 00497518..81af7444 100644 --- a/Examples/DemosApp/DemosApp.xcodeproj/project.pbxproj +++ b/Examples/DemosApp/DemosApp.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 70; objects = { /* Begin PBXBuildFile section */ @@ -80,7 +80,6 @@ 740D221F2CD3BECA006731A5 /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1610; LastUpgradeCheck = 1610; TargetAttributes = { diff --git a/Sources/ComponentsKit/Components/Button/SUButton.swift b/Sources/ComponentsKit/Components/Button/SUButton.swift index 9dcf96d1..80cf0e89 100644 --- a/Sources/ComponentsKit/Components/Button/SUButton.swift +++ b/Sources/ComponentsKit/Components/Button/SUButton.swift @@ -108,6 +108,7 @@ private struct CustomButtonStyle: SwiftUI.ButtonStyle { configuration.label .font(self.model.preferredFont.font) .lineLimit(1) + .contentShape(.rect) .padding(.horizontal, self.model.horizontalPadding) .frame(maxWidth: self.model.width) .frame(height: self.model.height) diff --git a/Sources/ComponentsKit/Components/Button/UKButton.swift b/Sources/ComponentsKit/Components/Button/UKButton.swift index 113d2a63..e7b63552 100644 --- a/Sources/ComponentsKit/Components/Button/UKButton.swift +++ b/Sources/ComponentsKit/Components/Button/UKButton.swift @@ -2,7 +2,7 @@ import AutoLayout import UIKit /// A UIKit component that performs an action when it is tapped by a user. -open class UKButton: UIView, UKComponent { +open class UKButton: FullWidthComponent, UKComponent { // MARK: Properties /// A closure that is triggered when the button is tapped. diff --git a/Sources/ComponentsKit/Components/InputField/UKInputField.swift b/Sources/ComponentsKit/Components/InputField/UKInputField.swift index 1a553155..1c1e4bf1 100644 --- a/Sources/ComponentsKit/Components/InputField/UKInputField.swift +++ b/Sources/ComponentsKit/Components/InputField/UKInputField.swift @@ -2,7 +2,7 @@ import AutoLayout import UIKit /// A UIKit component that displays a field to input a text. -open class UKInputField: UIView, UKComponent { +open class UKInputField: FullWidthComponent, UKComponent { // MARK: Public Properties /// A closure that is triggered when the text changes. @@ -140,6 +140,8 @@ open class UKInputField: UIView, UKComponent { self.horizontalStackView.vertically() self.horizontalStackViewConstraints = self.horizontalStackView.horizontally(self.model.horizontalPadding) + self.captionLabel.horizontally() + self.textField.setContentHuggingPriority(.defaultLow, for: .horizontal) self.titleLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) } diff --git a/Sources/ComponentsKit/Components/ProgressBar/UKProgressBar.swift b/Sources/ComponentsKit/Components/ProgressBar/UKProgressBar.swift index 28943e6b..1583645b 100644 --- a/Sources/ComponentsKit/Components/ProgressBar/UKProgressBar.swift +++ b/Sources/ComponentsKit/Components/ProgressBar/UKProgressBar.swift @@ -2,7 +2,7 @@ import AutoLayout import UIKit /// A UIKit component that visually represents the progress of a task or process using a horizontal bar. -open class UKProgressBar: UIView, UKComponent { +open class UKProgressBar: FullWidthComponent, UKComponent { // MARK: - Public Properties /// A model that defines the appearance properties. diff --git a/Sources/ComponentsKit/Components/SegmentedControl/UKSegmentedControl.swift b/Sources/ComponentsKit/Components/SegmentedControl/UKSegmentedControl.swift index f759f3da..e642c6cb 100644 --- a/Sources/ComponentsKit/Components/SegmentedControl/UKSegmentedControl.swift +++ b/Sources/ComponentsKit/Components/SegmentedControl/UKSegmentedControl.swift @@ -2,7 +2,7 @@ import AutoLayout import UIKit /// A UIKit component that allows users to choose between multiple segments or options. -open class UKSegmentedControl: UIView, UKComponent { +open class UKSegmentedControl: FullWidthComponent, UKComponent { // MARK: Properties /// A closure that is triggered when a selected segment changes. diff --git a/Sources/ComponentsKit/Components/Slider/UKSlider.swift b/Sources/ComponentsKit/Components/Slider/UKSlider.swift index 1a715eb6..22615b63 100644 --- a/Sources/ComponentsKit/Components/Slider/UKSlider.swift +++ b/Sources/ComponentsKit/Components/Slider/UKSlider.swift @@ -2,7 +2,7 @@ import AutoLayout import UIKit /// A UIKit component that lets users select a value from a range by dragging a thumb along a track. -open class UKSlider: UIView, UKComponent { +open class UKSlider: FullWidthComponent, UKComponent { // MARK: - Properties /// A closure that is triggered when the `currentValue` changes. diff --git a/Sources/ComponentsKit/Helpers/UIKit/FullWidthComponent.swift b/Sources/ComponentsKit/Helpers/UIKit/FullWidthComponent.swift new file mode 100644 index 00000000..85dc5c4f --- /dev/null +++ b/Sources/ComponentsKit/Helpers/UIKit/FullWidthComponent.swift @@ -0,0 +1,28 @@ +import UIKit + +/// A base-class for views whose intrinsic content size depends on the +/// width of their super-view (e.g. full width button, input field, etc.). +/// +/// By inheriting from `FullWidthComponent` the component gets automatic +/// `invalidateIntrinsicContentSize()` calls whenever the device rotates, the +/// window is resized (iPad multitasking, Stage Manager) or the view moves +/// into a different container with a new width. +open class FullWidthComponent: UIView { + private var lastKnownParentWidth: CGFloat = .nan + + open override func layoutSubviews() { + super.layoutSubviews() + + guard let parentWidth = self.superview?.bounds.width else { return } + + if parentWidth != self.lastKnownParentWidth { + self.lastKnownParentWidth = parentWidth + + // Defer to the next run-loop tick so the current layout pass + // finishes with the new parent size first. + DispatchQueue.main.async { + self.invalidateIntrinsicContentSize() + } + } + } +}