Can we use SwiftUi to build iOS Today Extension?

2020-06-19 15:39发布

问题:

I want to use Swift UI to build iOS's Today Extensions, but I don't know how to get started.

回答1:

Check this UIHostingController tutorial out, easy, straightforward and works like a charm: https://medium.com/@code_cookies/swiftui-embed-swiftui-view-into-the-storyboard-a6fc96e7a0a1



回答2:

Using an instance of UIHostingController as your NSExtensionPrincipalClass to instantiate your SwiftUI view should work on iOS 13.



回答3:

Create SwiftUI view and integrate it with UIHostingController.

You can do this just like use SwiftUI from UIKit.

Create Today Extension (Widget) with SwiftUI

//
//  WidgetView.swift
//

import SwiftUI

struct WidgetView: View {
    var body: some View {
        HStack {
            Image(systemName: "globe")
            Text("Hello, SwiftUI!")
        }
        .font(.title)
    }
}
//
//  TodayViewController.swift
//

import UIKit
import NotificationCenter
import SwiftUI

class TodayViewController: UIViewController, NCWidgetProviding {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let vc  = UIHostingController(rootView: WidgetView())
        self.addChild(vc)
        self.view.addSubview(vc.view)
        vc.didMove(toParent: self)

        vc.view.translatesAutoresizingMaskIntoConstraints = false
        vc.view.heightAnchor.constraint(equalTo: self.view.heightAnchor).isActive = true
        vc.view.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
        vc.view.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
        vc.view.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        vc.view.backgroundColor = UIColor.clear
    }

    func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
        // Perform any setup necessary in order to update the view.

        // If an error is encountered, use NCUpdateResult.Failed
        // If there's no update required, use NCUpdateResult.NoData
        // If there's an update, use NCUpdateResult.NewData

        completionHandler(NCUpdateResult.newData)
    }

}