Skip to content

Commit 246c69d

Browse files
committed
Address initial PR comments
1 parent e67b054 commit 246c69d

File tree

3 files changed

+69
-37
lines changed

3 files changed

+69
-37
lines changed

Sources/UIKitBackend/UIKitBackend+Container.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ final class ScrollWidget: ContainerWidget {
1818
scrollView.translatesAutoresizingMaskIntoConstraints = false
1919
}
2020

21-
override func viewWillLayoutSubviews() {
21+
override func updateViewConstraints() {
2222
NSLayoutConstraint.activate(contentLayoutGuideConstraints)
23-
super.viewWillLayoutSubviews()
23+
super.updateViewConstraints()
2424
}
2525

2626
func setScrollBars(

Sources/UIKitBackend/UIViewControllerRepresentable.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ where Content == Never {
1616
-> UIViewControllerType
1717

1818
/// Update the view with new values.
19+
/// - Note: This may be called even when `context` has not changed.
1920
/// - Parameters:
2021
/// - uiViewController: The controller to update.
2122
/// - context: The context, including the coordinator and potentially new environment
2223
/// values.
23-
/// - Note: This may be called even when `context` has not changed.
2424
func updateUIViewController(
2525
_ uiViewController: UIViewControllerType,
2626
context: UIViewControllerRepresentableContext<Coordinator>)
@@ -32,31 +32,31 @@ where Content == Never {
3232
func makeCoordinator() -> Coordinator
3333

3434
/// Compute the view's size.
35+
///
36+
/// The default implementation uses `uiViewController.view.intrinsicContentSize` and
37+
/// `uiViewController.view.systemLayoutSizeFitting(_:)` to determine the return value.
3538
/// - Parameters:
3639
/// - proposal: The proposed frame for the view to render in.
3740
/// - uiViewController: The controller being queried for its view's preferred size.
3841
/// - context: The context, including the coordinator and environment values.
3942
/// - Returns: Information about the view's size. The ``SwiftCrossUI/ViewSize/size``
40-
/// property is what frame the view will actually be rendered with if the current layout
41-
/// pass is not a dry run, while the other properties are used to inform the layout engine
42-
/// how big or small the view can be. The ``SwiftCrossUI/ViewSize/idealSize`` property
43-
/// should not vary with the `proposal`, and should only depend on the view's contents.
44-
/// Pass `nil` for the maximum width/height if the view has no maximum size (and therefore
45-
/// may occupy the entire screen).
46-
///
47-
/// The default implementation uses `uiViewController.view.intrinsicContentSize` and
48-
/// `uiViewController.view.systemLayoutSizeFitting(_:)` to determine the return value.
43+
/// property is what frame the view will actually be rendered with if the current layout
44+
/// pass is not a dry run, while the other properties are used to inform the layout
45+
/// engine how big or small the view can be. The ``SwiftCrossUI/ViewSize/idealSize``
46+
/// property should not vary with the `proposal`, and should only depend on the view's
47+
/// contents. Pass `nil` for the maximum width/height if the view has no maximum size
48+
/// (and therefore may occupy the entire screen).
4949
func determineViewSize(
5050
for proposal: SIMD2<Int>, uiViewController: UIViewControllerType,
5151
context: UIViewControllerRepresentableContext<Coordinator>
5252
) -> ViewSize
5353

5454
/// Called to clean up the view when it's removed.
55+
///
56+
/// The default implementation does nothing.
5557
/// - Parameters:
5658
/// - uiViewController: The controller being dismantled.
5759
/// - coordinator: The coordinator.
58-
///
59-
/// The default implementation does nothing.
6060
static func dismantleUIViewController(
6161
_ uiViewController: UIViewControllerType, coordinator: Coordinator)
6262
}

Sources/UIKitBackend/Widget.swift

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,38 +29,70 @@ private protocol WidgetProtocolHelpers: WidgetProtocol {
2929

3030
extension WidgetProtocolHelpers {
3131
func updateLeftConstraint() {
32-
leftConstraint?.isActive = false
33-
guard let superview = view.superview else { return }
34-
leftConstraint = view.leftAnchor.constraint(
35-
equalTo: superview.safeAreaLayoutGuide.leftAnchor, constant: CGFloat(x))
36-
// Set the constraint priority for leftConstraint (and topConstraint) to just under
37-
// "required" so that we don't get warnings about unsatisfiable constraints from
38-
// scroll views, which position relative to their contentLayoutGuide instead.
39-
// This *should* be high enough that it won't cause any problems unless there was
40-
// a constraint conflict anyways.
41-
leftConstraint!.priority = .init(UILayoutPriority.required.rawValue - 1.0)
42-
leftConstraint!.isActive = true
32+
guard let superview = view.superview else {
33+
leftConstraint?.isActive = false
34+
return
35+
}
36+
37+
if let leftConstraint,
38+
leftConstraint.secondAnchor === superview.safeAreaLayoutGuide.leftAnchor
39+
{
40+
leftConstraint.constant = CGFloat(x)
41+
leftConstraint.isActive = true
42+
} else {
43+
self.leftConstraint?.isActive = false
44+
let leftConstraint = view.leftAnchor.constraint(
45+
equalTo: superview.safeAreaLayoutGuide.leftAnchor, constant: CGFloat(x))
46+
self.leftConstraint = leftConstraint
47+
// Set the constraint priority for leftConstraint (and topConstraint) to just
48+
// under "required" so that we don't get warnings about unsatisfiable constraints
49+
// from scroll views, which position relative to their contentLayoutGuide instead.
50+
// This *should* be high enough that it won't cause any problems unless there was
51+
// a constraint conflict anyways.
52+
leftConstraint.priority = .init(UILayoutPriority.required.rawValue - 1.0)
53+
leftConstraint.isActive = true
54+
}
4355
}
4456

4557
func updateTopConstraint() {
46-
topConstraint?.isActive = false
47-
guard let superview = view.superview else { return }
48-
topConstraint = view.topAnchor.constraint(
49-
equalTo: superview.safeAreaLayoutGuide.topAnchor, constant: CGFloat(y))
50-
topConstraint!.priority = .init(UILayoutPriority.required.rawValue - 1.0)
51-
topConstraint!.isActive = true
58+
guard let superview = view.superview else {
59+
topConstraint?.isActive = false
60+
return
61+
}
62+
63+
if let topConstraint,
64+
topConstraint.secondAnchor === superview.safeAreaLayoutGuide.topAnchor
65+
{
66+
topConstraint.constant = CGFloat(y)
67+
topConstraint.isActive = true
68+
} else {
69+
self.topConstraint?.isActive = false
70+
let topConstraint = view.topAnchor.constraint(
71+
equalTo: superview.safeAreaLayoutGuide.topAnchor, constant: CGFloat(y))
72+
self.topConstraint = topConstraint
73+
topConstraint.priority = .init(UILayoutPriority.required.rawValue - 1.0)
74+
topConstraint.isActive = true
75+
}
5276
}
5377

5478
func updateWidthConstraint() {
55-
widthConstraint?.isActive = false
56-
widthConstraint = view.widthAnchor.constraint(equalToConstant: CGFloat(width))
57-
widthConstraint!.isActive = true
79+
if let widthConstraint {
80+
widthConstraint.constant = CGFloat(width)
81+
} else {
82+
let widthConstraint = view.widthAnchor.constraint(equalToConstant: CGFloat(width))
83+
self.widthConstraint = widthConstraint
84+
widthConstraint.isActive = true
85+
}
5886
}
5987

6088
func updateHeightConstraint() {
61-
heightConstraint?.isActive = false
62-
heightConstraint = view.heightAnchor.constraint(equalToConstant: CGFloat(height))
63-
heightConstraint!.isActive = true
89+
if let heightConstraint {
90+
heightConstraint.constant = CGFloat(height)
91+
} else {
92+
let heightConstraint = view.heightAnchor.constraint(equalToConstant: CGFloat(height))
93+
self.heightConstraint = heightConstraint
94+
heightConstraint.isActive = true
95+
}
6496
}
6597
}
6698

0 commit comments

Comments
 (0)