如何解决SwiftUI:WebKit 在输入 url 时不断加载页面
这是我的 macOS 应用程序中的 URL 地址栏,与此 TextField 配合良好:
@State private var text = ""
@State private var site = "www.google.com/" //stored as two separate values so that WebKit isn't trying to continuously load a URL with every single keystroke. The "site" property is only updated once the user presses the return key.
var body: some View {
let webView = WebView(site: $site,text: $text)
TextField("Enter a URL",text: $text,onCommit: {
guard !text.isEmpty else {return}
site = text
})
webView //To display the loaded web page
}
..但是在实现了 trim function 后,当用户将 URL 复制并粘贴到地址栏时删除“https://”后,WebKit 现在尝试在每次击键时连续加载 URL,我的应用停止工作。
@State private var text = ""
@State private var site = "www.google.com/"
var body: some View {
let webView = WebView(site: $site,text: $text)
TextField("Enter a URL",text: Binding(
get: { text },set: { newValue in
if trim(newValue).starts(with: "https://") {
text = String(trim(newValue).dropFirst(8))
} else {
text = newValue
}
}),onCommit: {
guard !text.isEmpty else {return}
site = text
})
webView //To display the loaded web page
}
func trim(_ str: String) -> String {
return str.trimmingCharacters(in: .whitespacesAndNewlines)
}
网页视图
struct WebView: NSViewRepresentable {
@Binding var site: String
private var webView: WKWebView
init(site: Binding<String>,text: Binding<String>) {
self.webView = WKWebView()
_site = site //
}
func makeNSView(context: Context) -> WKWebView {
return webView
}
func updateNSView(_ nsView: WKWebView,context: Context) {
nsView.load(URLRequest(url: (URL(string: "https://" + site) ?? Bundle.main.url(forResource: "URLError",withExtension: "pdf")!)))
}
解决方法
抱歉,删除了我之前的代码,因为它不适用于面向 macOS 10.15 的 Big Sur 11.3。
可能是因为“文本”在以下内容中不断更新而获得持续更新:
let webView = WebView(site: $site,text: $text)
删除您不使用的“文本”部分并相应地调整“WebView”初始化:
let webView = WebView(site: $site)
编辑 2:
为了完整起见,这是我在 macos 12 上运行的测试代码(因为这是我唯一的) 但应该在 macos 11.3 上工作。它使用 ObservableObject 进行绑定。
import Foundation
import SwiftUI
import WebKit
extension String {
func trim() -> String {
return self.trimmingCharacters(in: .whitespacesAndNewlines)
}
}
class WebStateModel: ObservableObject {
@Published var url: URL? = URL(string: "https://www.google.com")
func updateUrl(_ str: String) {
if let theUrl = URL(string: "https://" + WebStateModel.stripHttps(str)) {
url = theUrl
}
}
static func stripHttps(_ str: String) -> String {
var txt = str.trim()
if txt.starts(with: "https://") {
txt = String(txt.dropFirst(8))
}
return txt
}
}
struct ContentView: View {
@StateObject var webModel = WebStateModel()
@State var text = ""
var body: some View {
VStack (spacing: 80) {
TextField("Enter a URL",text: Binding(
get: { text },set: { text = WebStateModel.stripHttps($0) } ),onCommit: {
webModel.updateUrl(text)
})
WebView(webModel: webModel)
}
}
}
struct WebView: NSViewRepresentable {
@ObservedObject var webModel: WebStateModel
func makeNSView(context: Context) -> WKWebView {
let wkWebview = WKWebView()
if let theUrl = webModel.url {
let request = URLRequest(url: theUrl,cachePolicy: .returnCacheDataElseLoad)
wkWebview.load(request)
}
return wkWebview
}
func updateNSView(_ nsView: WKWebView,context: Context) {
if let theUrl = webModel.url {
let request = URLRequest(url: theUrl,cachePolicy: .returnCacheDataElseLoad)
nsView.load(request)
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。