Created
November 9, 2022 14:55
-
-
Save Tunous/1935b016a0cd91472fc8bd3036ffe051 to your computer and use it in GitHub Desktop.
SwiftUI view wrapper for UIKit that calculates its size
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
final class SwiftUIView<Content: View>: UIView { | |
private var heightConstraint: NSLayoutConstraint? | |
init(content: Content, onSizeChanged: @escaping (CGSize) -> Void) { | |
super.init(frame: .zero) | |
let sizeReadingContent = content.readSize { [weak self] newSize in | |
self?.heightConstraint?.constant = newSize.height | |
self?.heightConstraint?.isActive = true | |
onSizeChanged(newSize) | |
} | |
let host = UIHostingController(rootView: sizeReadingContent) | |
let hostedView: UIView = host.view | |
hostedView.backgroundColor = .clear | |
addSubview(hostedView) | |
hostedView.translatesAutoresizingMaskIntoConstraints = false | |
NSLayoutConstraint.activate([ | |
hostedView.leadingAnchor.constraint(equalTo: leadingAnchor), | |
hostedView.trailingAnchor.constraint(equalTo: trailingAnchor), | |
hostedView.topAnchor.constraint(equalTo: topAnchor), | |
hostedView.bottomAnchor.constraint(equalTo: bottomAnchor) | |
]) | |
self.heightConstraint = hostedView.heightAnchor.constraint(equalToConstant: 0) | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
} | |
extension View { | |
func readSize(_ onSizeChanged: @MainActor @escaping (CGSize) -> Void) -> some View { | |
background { | |
GeometryReader { geometry in | |
Color.clear.assign(geometry.size, to: onSizeChanged) | |
} | |
} | |
} | |
func assign<Value: Equatable>(_ value: @autoclosure () -> Value, to action: @MainActor @escaping (Value) -> Void) -> some View { | |
let computedValue = value() | |
return task(id: computedValue) { | |
await action(computedValue) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment