在 SwiftUI 的 tabview 中嵌入 webview
Embedding webview within a tabview in SwiftUI
我一直在尝试使用 PageIndexViewStyle
创建一个 TabView,其中每个页面都是一个包含图像和 WebView 的 ScrollView。当我在 TabView 外部创建页面时,@Asperi 的示例代码 工作得很好,但是当我在 TabView 内部移动内容时,第二页上的 WebView 不显示。
import SwiftUI
import WebKit
struct Webview : UIViewRepresentable {
@Binding var dynamicHeight: CGFloat
var webview: WKWebView = WKWebView()
class Coordinator: NSObject, WKNavigationDelegate {
var parent: Webview
init(_ parent: Webview) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
DispatchQueue.main.async {
self.parent.dynamicHeight = height as! CGFloat
}
})
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
webview.scrollView.bounces = false
webview.navigationDelegate = context.coordinator
let htmlStart = "<HTML><HEAD><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\"></HEAD><BODY>"
let htmlEnd = "</BODY></HTML>"
let dummy_html = """
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut venenatis risus. Fusce eget orci quis odio lobortis hendrerit. Vivamus in sollicitudin arcu. Integer nisi eros, hendrerit eget mollis et, fringilla et libero. Duis tempor interdum velit. Curabitur</p>
<p>ullamcorper, nulla nec elementum sagittis, diam odio tempus erat, at egestas nibh dui nec purus. Suspendisse at risus nibh. Mauris lacinia rutrum sapien non faucibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec interdum enim et augue suscipit, vitae mollis enim maximus.</p>
<p>Fusce et convallis ligula. Ut rutrum ipsum laoreet turpis sodales, nec gravida nisi molestie. Ut convallis aliquet metus, sit amet vestibulum risus dictum mattis. Sed nec leo vel mauris pharetra ornare quis non lorem. Aliquam sed justo</p>
"""
let htmlString = "\(htmlStart)\(dummy_html)\(htmlEnd)"
webview.loadHTMLString(htmlString, baseURL: nil)
return webview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
}
struct ContentView: View {
@State private var webViewHeight: CGFloat = .zero
var body: some View {
TabView {
ScrollView {
VStack {
Image(systemName: "doc")
.resizable()
.scaledToFit()
.frame(height: 100)
Divider()
Webview(dynamicHeight: $webViewHeight)
.padding(.horizontal)
.frame(height: webViewHeight)
}
}
ScrollView {
VStack {
Image(systemName: "star")
.resizable()
.scaledToFit()
.frame(height: 100)
Divider()
Webview(dynamicHeight: $webViewHeight)
.padding(.horizontal)
.frame(height: webViewHeight)
}
}
}
.tabViewStyle(PageTabViewStyle())
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
}
}
我不能确切地告诉你是什么导致了这种奇怪的行为,但是设置 TabView
的 selection
参数解决了这个问题。
根据我的理解,SwiftUI
希望我们在 TabView
.
上提供一个选择 binding
所以,改变
TabView {
到
TabView(selection: $selectedtab) {
// Or
TabView(selection: .constant(1)) {
解决了。
我一直在尝试使用 PageIndexViewStyle
创建一个 TabView,其中每个页面都是一个包含图像和 WebView 的 ScrollView。当我在 TabView 外部创建页面时,@Asperi 的示例代码
import SwiftUI
import WebKit
struct Webview : UIViewRepresentable {
@Binding var dynamicHeight: CGFloat
var webview: WKWebView = WKWebView()
class Coordinator: NSObject, WKNavigationDelegate {
var parent: Webview
init(_ parent: Webview) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
DispatchQueue.main.async {
self.parent.dynamicHeight = height as! CGFloat
}
})
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
webview.scrollView.bounces = false
webview.navigationDelegate = context.coordinator
let htmlStart = "<HTML><HEAD><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\"></HEAD><BODY>"
let htmlEnd = "</BODY></HTML>"
let dummy_html = """
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut venenatis risus. Fusce eget orci quis odio lobortis hendrerit. Vivamus in sollicitudin arcu. Integer nisi eros, hendrerit eget mollis et, fringilla et libero. Duis tempor interdum velit. Curabitur</p>
<p>ullamcorper, nulla nec elementum sagittis, diam odio tempus erat, at egestas nibh dui nec purus. Suspendisse at risus nibh. Mauris lacinia rutrum sapien non faucibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec interdum enim et augue suscipit, vitae mollis enim maximus.</p>
<p>Fusce et convallis ligula. Ut rutrum ipsum laoreet turpis sodales, nec gravida nisi molestie. Ut convallis aliquet metus, sit amet vestibulum risus dictum mattis. Sed nec leo vel mauris pharetra ornare quis non lorem. Aliquam sed justo</p>
"""
let htmlString = "\(htmlStart)\(dummy_html)\(htmlEnd)"
webview.loadHTMLString(htmlString, baseURL: nil)
return webview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
}
struct ContentView: View {
@State private var webViewHeight: CGFloat = .zero
var body: some View {
TabView {
ScrollView {
VStack {
Image(systemName: "doc")
.resizable()
.scaledToFit()
.frame(height: 100)
Divider()
Webview(dynamicHeight: $webViewHeight)
.padding(.horizontal)
.frame(height: webViewHeight)
}
}
ScrollView {
VStack {
Image(systemName: "star")
.resizable()
.scaledToFit()
.frame(height: 100)
Divider()
Webview(dynamicHeight: $webViewHeight)
.padding(.horizontal)
.frame(height: webViewHeight)
}
}
}
.tabViewStyle(PageTabViewStyle())
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
}
}
我不能确切地告诉你是什么导致了这种奇怪的行为,但是设置 TabView
的 selection
参数解决了这个问题。
根据我的理解,SwiftUI
希望我们在 TabView
.
binding
所以,改变
TabView {
到
TabView(selection: $selectedtab) {
// Or
TabView(selection: .constant(1)) {
解决了。