Код: Выделить всё
/// PreferenceKey to capture the bounds of the content
struct BoundsPreferenceKey: PreferenceKey {
typealias Value = Anchor?
static var defaultValue: Anchor? = nil
static func reduce(value: inout Anchor?, nextValue: () -> Anchor?) {
value = value ?? nextValue()
}
}
/// Wraps any SwiftUI `Content` in a `UIHostingController`
/// and calls you back with its `.view` so you can use it in UIKit.
struct ViewProvider: UIViewRepresentable {
let content: Content
@Binding var uiView: UIView
let bounds: CGRect
func makeUIView(context: Context) -> UIView {
let host = UIHostingController(rootView: content)
host.view.backgroundColor = .clear
host.view.bounds = bounds
DispatchQueue.main.async {
uiView = host.view
}
return host.view
}
func updateUIView(_ uiView: UIView, context: Context) {
uiView.bounds = bounds // doesn't have any effect
}
}
struct UIKitWrapperModifier: ViewModifier {
@Binding var uiView: UIView
@State var bounds = CGRect.zero
func body(content: Content) -> some View {
ViewProvider(
content: contentMeasured(content: content),
uiView: $uiView,
bounds: bounds
)
}
@ViewBuilder
func contentMeasured(content: Content) -> some View {
content
.anchorPreference(key: BoundsPreferenceKey.self, value: .bounds) { $0 }
.backgroundPreferenceValue(BoundsPreferenceKey.self) { anchor in
GeometryReader { geometry in
if let anchor {
print(geometry[anchor]) // prints correct bounds
bounds = geometry[anchor]
}
return Color.clear
}
}
}
}
extension View {
func uiKitWrapped(_ uiView: Binding) -> some View {
modifier(UIKitWrapperModifier(uiView: uiView))
}
}
< /code>
Но используя его < /p>
struct ContentView: View {
@State private var sourceUIView = UIView()
var body: some View {
Color.blue
.frame(width: 200, height: 150)
.uiKitWrapped($sourceUIView)
.background(Color.yellow)
}
}
, который изображает, что обертка Uikit не обнимает свою подветренность. Любая справка оценена.>
Подробнее здесь: https://stackoverflow.com/questions/796 ... nal-layout