SwiftUIでToday Extension (Widget)を作る
Published by @SoNiceInfo at 7/5/2020
SwiftUIを使ってToday Extension (Widget)を作成する方法を紹介します。
iOS 14から使える新しいWidgetを作成する方法は「Widget Extensionを作る」をご覧ください。
Today Extensionを追加する
File → New → Target...と進みダイアログが表示されたらToday Extension
を選択します。
適切なProduct Nameを入力してFinishします。
Activate "PRODUCT_NAME" schemeと聞かれるのでActivateを選択します。
新しいフォルダが作成されTodayViewController.swift
, MainInterface.storyboard
, info.plist
が追加されました。
これでToday Extensionを作成する準備は完了です。
初期状態のToday ExtensionではHello Worldと表示されています。
MainInterface.storyboardでHello Worldを削除する
MainInterface.storyboardの中身はこの様になっています。
今回はStoryboardではなくてSwiftUIで開発するのでHello Worldのラベルは削除します。
ここでBackgroundをなしにします。Viewを選択して後に右のInspector PaneでBackgroundをnone Defaultにします。他の色にしたい場合は自由に選択してください。
SwiftUIのViewを用意する
File → New → File...(⌘N)でSwiftUI Viewを選択します。
ここではファイル名はWidgetViewとしました。
//
// WidgetView.swift
//
import SwiftUI
struct WidgetView: View {
var body: some View {
HStack {
Image(systemName: "globe")
Text("Hello, SwiftUI!")
}
.font(.title)
}
}
struct WidgetView_Previews: PreviewProvider {
static var previews: some View {
WidgetView()
}
}
TodayViewControllerでWidgetViewを呼び出す
viewDidLoad
内でUIHostingController
を使ってWidgetView
を呼び出します。import SwiftUI
をするのを忘れないでください。
WidgetViewを呼び出したら、表示領域を自動的に決定するようにして背景をクリアにします。
//
// 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)
}
}
完成
GitHubにコードをおいています。d1v1b/WidgetSample: Today Extension Sample with SwiftUI
iOS 14対応
WWDC20ではホーム画面に配置することができる新しいWidgetが発表されました。
今回紹介した方法でiOS 14でもToday Extensionは引き続き利用できます。
WWDC20で発表されたiOS 14からの新しいWidgetを作成する方法は「Widget Extensionを作る」をご覧ください。