Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose forceLayout in EpoxySwiftUIHostingView #172

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/airbnb/epoxy-ios/compare/0.10.0...HEAD)

### Added
- Expose `forceLayout` in `EpoxySwiftUIHostingView` for updating the hosting view size from outside.

### Changed
- `AnyItemModel` now implements the `ErasedContentProviding` protocol.
- Updated `ErasedContentProviding` protocol to use its type name instead of `Self` in the keys of its `EpoxyModelProperty` properties `contentProperty` and `isContentEqualProperty `.
Expand Down
21 changes: 12 additions & 9 deletions Sources/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,9 @@ public final class EpoxySwiftUIHostingView<RootView: View>: UIView, EpoxyableVie
// The view controller must be added to the view controller hierarchy to measure its content.
addViewControllerIfNeededAndReady()

// We need to layout the view to ensure it gets resized properly when cells are re-used
viewController.view.setNeedsLayout()
viewController.view.layoutIfNeeded()

// This is required to ensure that views with new content are properly resized.
viewController.view.invalidateIntrinsicContentSize()
// In this method `setNeedsLayout` and `layoutIfNeeded` are called. We need to layout the view to ensure it gets resized properly when cells are re-used
// In this method `invalidateIntrinsicContentSize` is called. This is required to ensure that views with new content are properly resized.
forceLayout()
}

public override func layoutMarginsDidChange() {
Expand Down Expand Up @@ -234,9 +231,7 @@ public final class EpoxySwiftUIHostingView<RootView: View>: UIView, EpoxyableVie
// to be more common with top and bottom bars, since they can be laid out early during view
// controller transitions. If this works well, we may make this the default behavior for all
// SwiftUI views.
viewController.view.setNeedsLayout()
viewController.view.layoutIfNeeded()
viewController.view.invalidateIntrinsicContentSize()
forceLayout()
} else {
// Allow the layout margins update to fully propagate through to the SwiftUI View before
// invalidating the layout.
Expand All @@ -246,6 +241,14 @@ public final class EpoxySwiftUIHostingView<RootView: View>: UIView, EpoxyableVie
}
}

/// Force relayout the UIHostingView and invalidate its intrinsic content size.
/// This is used for updating the view size manually.
public func forceLayout() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we add doc comments to this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. Added the usage description.

viewController.view.setNeedsLayout()
viewController.view.layoutIfNeeded()
viewController.view.invalidateIntrinsicContentSize()
}

public func handleWillDisplay(animated: Bool) {
guard state != .appeared, window != nil else { return }
transition(to: .appearing(animated: animated))
Expand Down
Loading