滚动按钮单击 ScrollView/WKWebView、Swift
Scroll on button click a ScrollView/WKWebView, Swift
我正在研究 SwiftUI,但由于没有 WKWebView,我通过 UIViewRepresentable 创建了它。
这是一些代码:
func makeUIView(context: Context) -> WKWebView {
let jsScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jsScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let wkController = WKUserContentController()
wkController.addUserScript(userScript)
let wkWebConfiguration = WKWebViewConfiguration()
wkWebConfiguration.userContentController = wkController
let webView = WKWebView(frame: .null, configuration: wkWebConfiguration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.loadHTMLString(htmlBody, baseURL: nil)
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
if let htmlBody = self.htmlBody {
uiView.loadHTMLString(htmlBody, baseURL: nil)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
我需要做的是在单击按钮时滚动到它的底部。
所以在我的 SwiftUI 视图中,我有一个 @State var 并将它传递给我的 UIViewRepresentable。
这是我尝试过的(在我的 updateUIView 中):
if scrollWebView {
let scrollPoint = CGPoint(x: 0, y: yourWebView.scrollView.contentSize.height - webView.frame.size.height)
webView.scrollView.setContentOffset(scrollPoint, animated: true)
}
但是此代码(单击按钮时)滚动到我的 WkWebView 的顶部。即使我改变了 y 的符号。它总是滚动到顶部而不是底部。
我不认为我可以在我的 SwiftUI 视图中实现这一点,而且我找不到滚动到我的 WKWebView 底部的方法。
我也认为该行为(因为我可以做到 webView.scrollView)与 ScrollView 非常相似。
有什么帮助吗?
这是可能方法的简化演示。测试 Xcode 12 / iOS 14.
struct DemoWebView : UIViewRepresentable {
let text: String
@Binding var scrollToBottom: Bool
func makeUIView(context: Context) -> WKWebView {
let webview = WKWebView()
webview.loadHTMLString(text, baseURL: nil)
return webview
}
func updateUIView(_ webview: WKWebView, context: Context) {
if scrollToBottom {
let point = CGPoint(x: 0, y: webview.scrollView.contentSize.height - webview.frame.size.height)
webview.scrollView.setContentOffset(point, animated: true)
DispatchQueue.main.async {
self.scrollToBottom = false // turn it back for reuse
}
}
}
}
和用法类似
@State private var scroll = false
var body: some View {
VStack {
Button("Bottom") { self.scroll = true }
DemoWebView(text: self.htmlText, scrollToBottom: $scroll)
}
}
我正在研究 SwiftUI,但由于没有 WKWebView,我通过 UIViewRepresentable 创建了它。
这是一些代码:
func makeUIView(context: Context) -> WKWebView {
let jsScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jsScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let wkController = WKUserContentController()
wkController.addUserScript(userScript)
let wkWebConfiguration = WKWebViewConfiguration()
wkWebConfiguration.userContentController = wkController
let webView = WKWebView(frame: .null, configuration: wkWebConfiguration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.loadHTMLString(htmlBody, baseURL: nil)
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
if let htmlBody = self.htmlBody {
uiView.loadHTMLString(htmlBody, baseURL: nil)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
我需要做的是在单击按钮时滚动到它的底部。
所以在我的 SwiftUI 视图中,我有一个 @State var 并将它传递给我的 UIViewRepresentable。
这是我尝试过的(在我的 updateUIView 中):
if scrollWebView {
let scrollPoint = CGPoint(x: 0, y: yourWebView.scrollView.contentSize.height - webView.frame.size.height)
webView.scrollView.setContentOffset(scrollPoint, animated: true)
}
但是此代码(单击按钮时)滚动到我的 WkWebView 的顶部。即使我改变了 y 的符号。它总是滚动到顶部而不是底部。
我不认为我可以在我的 SwiftUI 视图中实现这一点,而且我找不到滚动到我的 WKWebView 底部的方法。
我也认为该行为(因为我可以做到 webView.scrollView)与 ScrollView 非常相似。
有什么帮助吗?
这是可能方法的简化演示。测试 Xcode 12 / iOS 14.
struct DemoWebView : UIViewRepresentable {
let text: String
@Binding var scrollToBottom: Bool
func makeUIView(context: Context) -> WKWebView {
let webview = WKWebView()
webview.loadHTMLString(text, baseURL: nil)
return webview
}
func updateUIView(_ webview: WKWebView, context: Context) {
if scrollToBottom {
let point = CGPoint(x: 0, y: webview.scrollView.contentSize.height - webview.frame.size.height)
webview.scrollView.setContentOffset(point, animated: true)
DispatchQueue.main.async {
self.scrollToBottom = false // turn it back for reuse
}
}
}
}
和用法类似
@State private var scroll = false
var body: some View {
VStack {
Button("Bottom") { self.scroll = true }
DemoWebView(text: self.htmlText, scrollToBottom: $scroll)
}
}