SwiftUI 在 link 单击 WKWebView 内部打开一个新视图
SwiftUI open a new View on link click inside of WKWebView
我想在WKWebView里面点击一个link后在SwfitUI(webview)中打开一个新视图,我不知道该怎么做。我知道你必须通过协调员,但我不知道更多。我在 swift.
的水平不是很高
这是我的 Swiftui 视图(我删除了多余的元素)和 al calsse 以在我的视图中显示我的内容:
struct PostDetailView: View {
var p: Post
@ObservedObject var dataManager: DataManager
let preferences:Preferences = parsePreferences()
let contentWebView = ArticleCustomView()
@State var showComments = false
@Binding var favorite: Bool
@Environment(\.colorScheme) var colorScheme
var body: some View {
let content: String = contentWebView.contentArticle(title: p.title.rendered.stringByDecodingHTMLEntities, content: p.content.rendered, date: formatDateDetailPost(dateToChange: p.date), author: p.author_meta.nickname)
ZStack{
BackgroundView()
articleWebView(text: content, color: colorScheme)
}
.navigationBarTitle(...)
.navigationBarItems(...)
}
}
x
struct articleWebView: UIViewRepresentable {
@State var text: String
@State var color: ColorScheme
func makeUIView(context: Context) -> WKWebView {
return _wkwebview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
var html = ""
var normalizeCSS: String = ""
var articlesCSS: String = ""
//let articlesDarkCSS: String
let altCSS: String
altCSS = "-dark"
guard let fileURL = Bundle.main.url(forResource: "articles", withExtension: "html") else { return print("articles.html introuvable")}
guard let fileURLNormalizeCss = Bundle.main.url(forResource: "normalize", withExtension: "css") else { return print("normalize.css introuvable")}
guard let fileURLArticlesCss = Bundle.main.url(forResource: "articles\(altCSS)", withExtension: "css") else { return print("articles\(altCSS).css introuvable")}
do {
html = try String(contentsOf: fileURL)
} catch {
print("Unable to get the articles.html")
}
do {
normalizeCSS = try String(contentsOf: fileURLNormalizeCss)
} catch {
print("Unable to get the normalize.css")
}
do {
articlesCSS = try String(contentsOf: fileURLArticlesCss)
} catch {
print("Unable to get the articles.css")
}
html = html.replacingOccurrences(of: "[article:content]", with: text)
html = html.replacingOccurrences(of: "[normalize:CSS]", with: normalizeCSS)
html = html.replacingOccurrences(of: "[style:articles]", with: articlesCSS)
uiView.loadHTMLString(html, baseURL: nil)
//----------------------------------------------//
uiView.allowsBackForwardNavigationGestures = true
uiView.isOpaque = false
uiView.backgroundColor = .clear
uiView.scrollView.backgroundColor = UIColor.clear
uiView.scrollView.showsVerticalScrollIndicator = false
uiView.scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
提前致谢。
我终于找到了解决问题的方法。您必须使用协调器来了解何时单击 link 并检索 link.
使用绑定,我将 url 传输到视图,然后打开一个 sheetView,在里面我有我的 webview,它打开了 url
struct PostDetailView: View {
var p: Post
@ObservedObject var dataManager: DataManager
let preferences:Preferences = parsePreferences()
let contentWebView = ArticleCustomView()
@State var showComments = false
@Binding var favorite: Bool
@State var activeSheet: Bool = false
@State var urlToOpenInSheet: String = ""
@Environment(\.colorScheme) var colorScheme
var body: some View {
let content: String = contentWebView.contentArticle(title: p.title.rendered.stringByDecodingHTMLEntities, content: p.content.rendered, date: formatDateDetailPost(dateToChange: p.date), author: p.author_meta.nickname)
ZStack{
BackgroundView()
articleWebView(text: content, color: colorScheme, activeSheet: $activeSheet, urlToOpenInSheet: $urlToOpenInSheet)
}
.navigationBarTitle(...)
.navigationBarItems(...)
.sheet(isPresented: $activeSheet) {
if !urlToOpenInSheet.isEmpty {
ExternalWebView(urlToVisite: urlToOpenInSheet, activeButtons: true, fromSheet: true, closeSheet: $activeSheet)
.ignoresSafeArea()
.accentColor(.white)
}
}
.onChange(of: urlToOpenInSheet) { newValue in
print("url changed to \(urlToOpenInSheet)!")
}
}
}
struct articleWebView: UIViewRepresentable {
@State var text: String
@State var color: ColorScheme
@Binding var activeSheet: Bool
@Binding var urlToOpenInSheet: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let WKWebView = WKWebView()
WKWebView.navigationDelegate = context.coordinator
return WKWebView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
var html = ""
var normalizeCSS: String = ""
var articlesCSS: String = ""
//let articlesDarkCSS: String
let altCSS: String
guard let fileURL = Bundle.main.url(forResource: "articles", withExtension: "html") else { return print("articles.html introuvable")}
guard let fileURLNormalizeCss = Bundle.main.url(forResource: "normalize", withExtension: "css") else { return print("normalize.css introuvable")}
guard let fileURLArticlesCss = Bundle.main.url(forResource: "articles\(altCSS)", withExtension: "css") else { return print("articles\(altCSS).css introuvable")}
do {
html = try String(contentsOf: fileURL)
} catch {
print("Unable to get the articles.html")
}
do {
normalizeCSS = try String(contentsOf: fileURLNormalizeCss)
} catch {
print("Unable to get the normalize.css")
}
do {
articlesCSS = try String(contentsOf: fileURLArticlesCss)
} catch {
print("Unable to get the articles.css")
}
html = html.replacingOccurrences(of: "[article:content]", with: text)
html = html.replacingOccurrences(of: "[normalize:CSS]", with: normalizeCSS)
html = html.replacingOccurrences(of: "[style:articles]", with: articlesCSS)
//print(html)
uiView.loadHTMLString(html, baseURL: nil)
//---------------------- Activer /Desactiver certaines options sur la Webview -------------------------//
uiView.allowsBackForwardNavigationGestures = true
uiView.isOpaque = false
uiView.backgroundColor = .clear
uiView.scrollView.backgroundColor = UIColor.clear
uiView.scrollView.showsVerticalScrollIndicator = false // indicateur de scroll
uiView.scrollView.pinchGestureRecognizer?.isEnabled = false // zommer-dezommer avec le doigt
}
class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
var parent: articleWebView
init(_ parent: articleWebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url {
if UIApplication.shared.canOpenURL(url) {
//UIApplication.shared.open(url)
print(url)
parent.urlToOpenInSheet = url.absoluteString
print(self.parent.urlToOpenInSheet)
parent.activeSheet = true
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
} else {
//print("not a user click")
decisionHandler(.allow)
}
}
}
}
我想在WKWebView里面点击一个link后在SwfitUI(webview)中打开一个新视图,我不知道该怎么做。我知道你必须通过协调员,但我不知道更多。我在 swift.
的水平不是很高这是我的 Swiftui 视图(我删除了多余的元素)和 al calsse 以在我的视图中显示我的内容:
struct PostDetailView: View {
var p: Post
@ObservedObject var dataManager: DataManager
let preferences:Preferences = parsePreferences()
let contentWebView = ArticleCustomView()
@State var showComments = false
@Binding var favorite: Bool
@Environment(\.colorScheme) var colorScheme
var body: some View {
let content: String = contentWebView.contentArticle(title: p.title.rendered.stringByDecodingHTMLEntities, content: p.content.rendered, date: formatDateDetailPost(dateToChange: p.date), author: p.author_meta.nickname)
ZStack{
BackgroundView()
articleWebView(text: content, color: colorScheme)
}
.navigationBarTitle(...)
.navigationBarItems(...)
}
}
x
struct articleWebView: UIViewRepresentable {
@State var text: String
@State var color: ColorScheme
func makeUIView(context: Context) -> WKWebView {
return _wkwebview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
var html = ""
var normalizeCSS: String = ""
var articlesCSS: String = ""
//let articlesDarkCSS: String
let altCSS: String
altCSS = "-dark"
guard let fileURL = Bundle.main.url(forResource: "articles", withExtension: "html") else { return print("articles.html introuvable")}
guard let fileURLNormalizeCss = Bundle.main.url(forResource: "normalize", withExtension: "css") else { return print("normalize.css introuvable")}
guard let fileURLArticlesCss = Bundle.main.url(forResource: "articles\(altCSS)", withExtension: "css") else { return print("articles\(altCSS).css introuvable")}
do {
html = try String(contentsOf: fileURL)
} catch {
print("Unable to get the articles.html")
}
do {
normalizeCSS = try String(contentsOf: fileURLNormalizeCss)
} catch {
print("Unable to get the normalize.css")
}
do {
articlesCSS = try String(contentsOf: fileURLArticlesCss)
} catch {
print("Unable to get the articles.css")
}
html = html.replacingOccurrences(of: "[article:content]", with: text)
html = html.replacingOccurrences(of: "[normalize:CSS]", with: normalizeCSS)
html = html.replacingOccurrences(of: "[style:articles]", with: articlesCSS)
uiView.loadHTMLString(html, baseURL: nil)
//----------------------------------------------//
uiView.allowsBackForwardNavigationGestures = true
uiView.isOpaque = false
uiView.backgroundColor = .clear
uiView.scrollView.backgroundColor = UIColor.clear
uiView.scrollView.showsVerticalScrollIndicator = false
uiView.scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
提前致谢。
我终于找到了解决问题的方法。您必须使用协调器来了解何时单击 link 并检索 link.
使用绑定,我将 url 传输到视图,然后打开一个 sheetView,在里面我有我的 webview,它打开了 url
struct PostDetailView: View {
var p: Post
@ObservedObject var dataManager: DataManager
let preferences:Preferences = parsePreferences()
let contentWebView = ArticleCustomView()
@State var showComments = false
@Binding var favorite: Bool
@State var activeSheet: Bool = false
@State var urlToOpenInSheet: String = ""
@Environment(\.colorScheme) var colorScheme
var body: some View {
let content: String = contentWebView.contentArticle(title: p.title.rendered.stringByDecodingHTMLEntities, content: p.content.rendered, date: formatDateDetailPost(dateToChange: p.date), author: p.author_meta.nickname)
ZStack{
BackgroundView()
articleWebView(text: content, color: colorScheme, activeSheet: $activeSheet, urlToOpenInSheet: $urlToOpenInSheet)
}
.navigationBarTitle(...)
.navigationBarItems(...)
.sheet(isPresented: $activeSheet) {
if !urlToOpenInSheet.isEmpty {
ExternalWebView(urlToVisite: urlToOpenInSheet, activeButtons: true, fromSheet: true, closeSheet: $activeSheet)
.ignoresSafeArea()
.accentColor(.white)
}
}
.onChange(of: urlToOpenInSheet) { newValue in
print("url changed to \(urlToOpenInSheet)!")
}
}
}
struct articleWebView: UIViewRepresentable {
@State var text: String
@State var color: ColorScheme
@Binding var activeSheet: Bool
@Binding var urlToOpenInSheet: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let WKWebView = WKWebView()
WKWebView.navigationDelegate = context.coordinator
return WKWebView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
var html = ""
var normalizeCSS: String = ""
var articlesCSS: String = ""
//let articlesDarkCSS: String
let altCSS: String
guard let fileURL = Bundle.main.url(forResource: "articles", withExtension: "html") else { return print("articles.html introuvable")}
guard let fileURLNormalizeCss = Bundle.main.url(forResource: "normalize", withExtension: "css") else { return print("normalize.css introuvable")}
guard let fileURLArticlesCss = Bundle.main.url(forResource: "articles\(altCSS)", withExtension: "css") else { return print("articles\(altCSS).css introuvable")}
do {
html = try String(contentsOf: fileURL)
} catch {
print("Unable to get the articles.html")
}
do {
normalizeCSS = try String(contentsOf: fileURLNormalizeCss)
} catch {
print("Unable to get the normalize.css")
}
do {
articlesCSS = try String(contentsOf: fileURLArticlesCss)
} catch {
print("Unable to get the articles.css")
}
html = html.replacingOccurrences(of: "[article:content]", with: text)
html = html.replacingOccurrences(of: "[normalize:CSS]", with: normalizeCSS)
html = html.replacingOccurrences(of: "[style:articles]", with: articlesCSS)
//print(html)
uiView.loadHTMLString(html, baseURL: nil)
//---------------------- Activer /Desactiver certaines options sur la Webview -------------------------//
uiView.allowsBackForwardNavigationGestures = true
uiView.isOpaque = false
uiView.backgroundColor = .clear
uiView.scrollView.backgroundColor = UIColor.clear
uiView.scrollView.showsVerticalScrollIndicator = false // indicateur de scroll
uiView.scrollView.pinchGestureRecognizer?.isEnabled = false // zommer-dezommer avec le doigt
}
class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
var parent: articleWebView
init(_ parent: articleWebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url {
if UIApplication.shared.canOpenURL(url) {
//UIApplication.shared.open(url)
print(url)
parent.urlToOpenInSheet = url.absoluteString
print(self.parent.urlToOpenInSheet)
parent.activeSheet = true
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
} else {
//print("not a user click")
decisionHandler(.allow)
}
}
}
}