在macOS上使用swiftUI实施webkit(并创建网页预览)

切尔

我正在尝试创建一个显示该网站收件箱的菜单栏应用程序。我想做一个简单的功能,用该项目的网址打开一个小的弹出窗口(不打开野生动物园)。收件箱项目看起来像这样

struct InboxItem: View {
    @State var MesgSite: String = "https://duckduckgo.com"
    @State private var showSafari = false    
   
    var body: some View {
        VStack(alignment: .leading) {
            Text("some text")
        .background(SelectColor.opacity(0.5))
        .onLongPressGesture {
           //show preview of the MesgSite here
            self.SelectColor = .blue
            self.showSafari.toggle()
        }.popover(isPresented: self.$showSafari) {
            SafariPreview()
        }
    }
}

struct SafariPreview: View {

    var body: some View {
        VStack {
            Text("Display the webpage here")
            .padding()
        }.frame(maxWidth: 533, maxHeight: 300)
    }

}

我想,当长按该项目时,它应该像在macOS上的默认邮件应用程序中那样预览关联的网页,如下所示:

现在弹出窗口工作了

打开网站预览

我曾尝试添加一个wkwebview,以及一个SafariView在一个NSViewRepresentable,但是我有(间相似)使用代码从下面的错误消息这个SO交

Use of undeclared type 'UIViewRepresentable'

TIA!

编辑:

该项目的最基本版本可以在github上找到

编辑2:

更加关注这个问题

切尔

我也曾想出一个解决方案。由于我在该网上都找不到任何文档,因此我将通过反复试验给出我找到的解决方案。

首先,事实证明UI...,它在macOS上的对应版本名为NS...因此UIViewRepresentableNSViewRepresentable在macOS上。接下来,我发现了这样的问题,其中有一个WKWebview关于macOS的示例通过将该代码与另一个SO问题上的答案结合起来,我还可以检测到URL变化,并且知道何时完成视图加载。

macOS上的SwiftUI WebView

这导致了以下代码。为了清楚起见,我建议将其放在另一个文件中,例如WebView.swift

首先,导入所需的软件包:

import SwiftUI
import WebKit
import Combine

然后创建一个模型,其中包含您希望能够在SwiftUI视图中访问的数据:

class WebViewModel: ObservableObject {
    @Published var link: String
    @Published var didFinishLoading: Bool = false
    @Published var pageTitle: String
    
    init (link: String) {
        self.link = link
        self.pageTitle = ""
    }
}

最后,创建structwith NSViewRepresentable,将其作为类似HostingViewController的代码,WebView()如下所示:

struct SwiftUIWebView: NSViewRepresentable {
    
    public typealias NSViewType = WKWebView
    @ObservedObject var viewModel: WebViewModel

    private let webView: WKWebView = WKWebView()
    public func makeNSView(context: NSViewRepresentableContext<SwiftUIWebView>) -> WKWebView {
        webView.navigationDelegate = context.coordinator
        webView.uiDelegate = context.coordinator as? WKUIDelegate
        webView.load(URLRequest(url: URL(string: viewModel.link)!))
        return webView
    }

    public func updateNSView(_ nsView: WKWebView, context: NSViewRepresentableContext<SwiftUIWebView>) { }

    public func makeCoordinator() -> Coordinator {
        return Coordinator(viewModel)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        private var viewModel: WebViewModel

        init(_ viewModel: WebViewModel) {
           //Initialise the WebViewModel
           self.viewModel = viewModel
        }
        
        public func webView(_: WKWebView, didFail: WKNavigation!, withError: Error) { }

        public func webView(_: WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error) { }

        //After the webpage is loaded, assign the data in WebViewModel class
        public func webView(_ web: WKWebView, didFinish: WKNavigation!) {
            self.viewModel.pageTitle = web.title!
            self.viewModel.link = web.url?.absoluteString as! String
            self.viewModel.didFinishLoading = true
        }

        public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { }

        public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            decisionHandler(.allow)
        }

    }

}

此代码可以按如下方式使用:

struct ContentView: View {
    var body: some View {
        //Pass the url to the SafariWebView struct.
        SafariWebView(mesgURL: "https://stackoverflow.com/")
    }
}
struct SafariWebView: View {
    @ObservedObject var model: WebViewModel

    init(mesgURL: String) {
        //Assign the url to the model and initialise the model
        self.model = WebViewModel(link: mesgURL)
    }
    
    var body: some View {
        //Create the WebView with the model
        SwiftUIWebView(viewModel: model)
    }
}

创建Safari预览

因此,现在我们有了这些知识,重新创建方便的野生动物园预览相对容易。

为此,请确保将添加@State private var showSafari = false(当您要显示预览时会切换)到将调用预览的视图中。

同时添加.popover(isPresented: self.$showSafari) { ...以显示预览

struct ContentView: View {
    @State private var showSafari = false

    var body: some View {
        VStack(alignment: .leading) {
            Text("Press me to get a preview")
            .padding()
        }
        .onLongPressGesture {
            //Toggle to showSafari preview
            self.showSafari.toggle()
        }//if showSafari is true, create a popover
        .popover(isPresented: self.$showSafari) {
            //The view inside the popover is made of the SafariPreview
            SafariPreview(mesgURL: "https://duckduckgo.com/")
        }
    }
}

现在SafariPreview struct将如下所示:

struct SafariPreview: View {
    @ObservedObject var model: WebViewModel
    init(mesgURL: String) {
        self.model = WebViewModel(link: mesgURL)
    }
    
    var body: some View {
        //Create a VStack that contains the buttons in a preview as well a the webpage itself
        VStack {
            HStack(alignment: .center) {
                Spacer()
                Spacer()
                //The title of the webpage
                Text(self.model.didFinishLoading ? self.model.pageTitle : "")
                Spacer()
                //The "Open with Safari" button on the top right side of the preview
                Button(action: {
                    if let url = URL(string: self.model.link) {
                        NSWorkspace.shared.open(url)
                    }
                }) {
                    Text("Open with Safari")
                }
            }
            //The webpage itself
            SwiftUIWebView(viewModel: model)
        }.frame(width: 800, height: 450, alignment: .bottom)
            .padding(5.0)
    }
}

结果看起来像这样:

使用swiftUI的macOS Safari网页预览

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用CSS创建网页背景淡入淡出

来自分类Dev

在球拍中创建网页?

来自分类Dev

使用 Python 构建网页

来自分类Dev

如何创建网页配置文件

来自分类Dev

如何使用Java在png图像上创建网格图?

来自分类Dev

有可能使用来自intraweb的html5标签创建网页?

来自分类Dev

使用 CSS 和 html 构建网页

来自分类Dev

如何在Android中创建网址预览?

来自分类Dev

使用UIImageview创建网格

来自分类Dev

使用Highcharts在网页上创建图形

来自分类Dev

如何通过iOS应用程序动态创建网页?

来自分类Dev

如何在Mule ESB中创建网页

来自分类Dev

在网页(HTML)上实施监视功能

来自分类Dev

使用Firefox附加SDK来构建网页

来自分类Dev

macOS上的SwiftUI ListStyle

来自分类Dev

使用jQuery快速创建网格

来自分类Dev

使用jQuery快速创建网格

来自分类Dev

使用参数创建网址的javascript函数

来自分类Dev

如何在SwiftUI中创建网格视图?

来自分类Dev

如何使用网页上的关闭按钮创建顶部栏?

来自分类Dev

使用python 3创建脚本以捕获网页上的链接

来自分类Dev

如何在macOS上使用SwiftUI显示QLPreviewPanel?

来自分类Dev

如何使用SwiftUI在macOS 10.15上添加工具提示

来自分类Dev

在2D网格上从点云创建网格

来自分类Dev

在2D网格上从点云创建网格

来自分类Dev

如何在 Xamarin Forms 中的按钮上创建网格

来自分类Dev

如何在asp.net网页上添加预览横幅?

来自分类Dev

从浏览器缓存中重新创建网页

来自分类Dev

创建网页并想将外部链接调用为html和CSS?