- タスクを優先順位付きで作成し、タスクを実行し、タスクをキャンセルします。
- ユーザーが「集中モード」をオンにしたかどうかを把握する
- 位置情報ボタン
- (SwiftUI) SwiftUIを利用してリモート画像を読み込む
- (SwiftUI)
List
リストの検索機能 - (SwiftUI) リストセパレータを隠す
- (SwiftUI) リストにPull to Refresh(引っ張って更新)機能を追加
- (SwiftUI) テキストフィールドのフォーカスを外す
- (SwiftUI) リストセルにスワイプアクションを追加する
- (SwiftUI) テキストビューでマークダウンを使用する
- (SwiftUI) 画面が表示されたらタスクを実行します
- (SwiftUI) タブビューにバッジ(未読メッセージカウンター)を追加
この記事は developer.apple.com
上で公開されている文書に基づいて書かれました。スクリーンショットは後ほどこちらに追加します。
iOS 14の新機能に関して私が書いた別の記事もお読みいただけます。
たった数行のコードで作成できる iOS 14 の新たなフレームワークの機能
タスクを優先順位付きで作成し、タスクを実行し、タスクをキャンセルします。
このコードはタスクを非同期 (asynchronously) で実行します。
let task = Task(priority: .userInitiated) {
Server.fetchCatNames { catNames in
print(catNames)
}
}
ユーザーが「集中モード」をオンにしたかどうかを把握する
フォーカスモードはiOS15の新機能です。
アプリは、ユーザーが邪魔されたくないかどうかを確認することができます。
まず、Communication Notifications
権利を登録する必要があります。
次に、ユーザーの「集中モード」にアクセスが必要な理由を説明するNSFocusStatusUsageDescription
キーの値を登録します。
以下のコードを使ってアクセス権をリクエストします。
// import Intents
let permissionNotDetermined = (INFocusStatusCenter.default.authorizationStatus == .notDetermined)
if permissionNotDetermined {
INFocusStatusCenter.default.requestAuthorization { status in
print(status)
}
}
ユーザーの集中モードの状態を確認するには、次のコードを使います。
let isAccessAuthorized = (INFocusStatusCenter.default.authorizationStatus == .authorized)
if let isFocused = INFocusStatusCenter.default.focusStatus.isFocused,
isAccessAuthorized {
print(isFocused)
}
SwiftUIの位置情報ボタン
ユーザーの位置情報をリクエストしたい場合、その旨を示すボタンを表示することができます。
このボタンには、開発者にかわって実際に位置情報の許可をリクエストする機能はありません。
プリセットスタイルが適用された、単なる普通のボタンです。
ユーザーの位置情報をリクエストして取得するためのロジックの実装は、開発者に委ねられています。
// import CoreLocation
// import CoreLocationUI
LocationButton(.currentLocation) {
print("Location requested.")
}
.cornerRadius(15)
.symbolVariant(.fill)
.foregroundColor(.white)
ボタンに表示するラベルは、さまざまなものから選ぶことができます:
LocationButton(.currentLocation)
LocationButton(.sendCurrentLocation)
LocationButton(.sendMyCurrentLocation)
LocationButton(.shareCurrentLocation)
LocationButton(.shareMyCurrentLocation)
UIKitフレームワークの位置情報要求ボタンCLLocationButton
についてはこちらの記事をご覧ください。
Apple Developer Documentation
SwiftUIを利用してリモート画像を読み込む
リモート画像を非同期で素早く読み込むことができます。
AsyncImage(url: URL(string: "https://via.placeholder.com/350x150")!)
画像UIオブジェクトやエラーメッセージを取得し、画像をダウンロードしている最中にロード画面を表示することもできます。
AsyncImage(url: URL(string: "https://via.placeholder.com/350x150")!, scale: 1.0) { phase in
if let image = phase.image {
image
} else if let error = phase.error {
Text(error.localizedDescription)
} else {
ProgressView()
}
}
SwiftUIのリストに関する新機能
List
に対して.searchable
を使用すれば検索ボックスを表示できます。
struct ContentView: View {
@State var searchTextEntered: String = ""
var allCatNames = ["ムギ", "ソラ", "リン"]
var body: some View {
NavigationView {
Form {
List {
ForEach(allCatNames, id: \.self) { catName in
Text(catName)
}
}
.searchable(text: $searchTextEntered)
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
var searchResults: [String] {
if searchTextEntered.isEmpty {
return allCatNames
} else {
return allCatNames.filter { catName in
return catName.contains(searchTextEntered)
}
}
}
}
また、次のコードを使用して検索候補を表示することもできます。
.searchable(text: <#T##Binding<String>#>, prompt: <#T##LocalizedStringKey#>, suggestions: <#T##() -> View#>)
.listRowSeparator(.hidden)
を使って、リストビューの改行コードを非表示にすることができます。
List {
ForEach(allCatNames, id: \.self) { catName in
Text(catName)
.listRowSeparator(.hidden)
}
}
リストの更新メカニズムを提供することもできます
SwiftUIリストにPull to Refresh(引っ張って更新)機能を追加できます。
ローディングインジケーターは、ユーザーがプルダウンして更新すると表示され、コードが完了すると非表示になります。
List {
ForEach(allCatNames, id: \.self) { catName in
Text(catName)
}
}
.refreshable {
Server.fetchCatNames { catNames in
self.allCatNames = catNames
}
}
リストセルにスワイプアクションを追加する
ユーザーが行を左または右にスワイプすることで、特定のアクションを行えるようにすることができます。
Form {
List {
ForEach(allCats, id: \.self) { cat in
Text(cat)
.swipeActions(edge: .leading) {
Button {
print("pinned")
} label: {
Image(systemName: "bookmark")
}
.tint(.blue)
}
}
}
}
SwiftUIのテキストビューでマークダウンを使用する
これでSwiftUIでマークダウンを使用できます
Text("You can **now** type *in* markdown. You can put [links](https://example.com) here, or some `code`.")
テキストフィールドのフォーカスを外す
アクティブなテキストフィールドにあるキーボードは、(TextField
の)変数FocusState
とプロパティ.focused
を使って閉じることができます
(下の例を参照してください)
テキストフィールドにキーボードツールバーを加えましょう
テキストフィールドの動作中、キーボード上方にツールバーを表示させることができます。
struct ContentView: View {
@State var catNameEntered: String = ""
@FocusState var isCatNameFieldFocused: Bool
var body: some View {
Form {
TextField("Cat name", text: $catNameEntered)
.focused($isCatNameFieldFocused)
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
HStack {
Button("Clear textfield") {
self.catNameEntered = ""
}
Spacer()
Button("Done") {
self.isCatNameFieldFocused = false
}
}
}
}
}
}
}
SwiftUI画面が表示されたらタスクを実行します
画面が表示されたらタスクを実行することができます。
これを利用すれば遠隔サーバからデータを取り込めます。
var body: some View {
Form {
List(allCatNames, id: \.self) { catName in
Text(catName)
}
}
.task {
Server.fetchCatNames { catNames in
self.allCatNames = catNames
}
}
}
ユーザーがキーボードの送信ボタンをクリックしたことを知る
ユーザーがキーボードの送信ボタンをクリックしたことを知るために、.onSubmit
をForm
に使用することができます。
struct ContentView: View {
@State var newCatNameField: String = ""
@State var newCatColorField: String = ""
var body: some View {
Form {
TextField("Cat name", text: $newCatNameField)
TextField("Cat color", text: $newCatColorField)
}
.onSubmit {
print("onSubmit \(newCatNameField) \(newCatColorField)")
}
}
}
SwiftUIのタブビューにバッジ(未読メッセージカウンター)を追加
タブビューのタブにバッジを追加することができます(例えば、チャットタブでは、未読メッセージ数のバッジを表示することができます)。
TabView {
Form {
Text("Tab 1")
}
.tabItem({
Label("Tab 1", systemImage: "book")
})
.badge(10)
Form {
Text("Tab 2")
}
.tabItem {
Label("Tab 2", systemImage: "calendar")
}
.badge(1)
}
Time-Sensitive(一刻を争う)notifications 通知
通知を緊急のものとしてマークすることができます。その場合、ユーザーがフォーカスモードをオンにしていても、画面上に通知が表示されます。
アプリ資格付与ファイルにCommunication Notification
、Push Notifications
、Time Sensitive Notifications
を追加する必要があります。
これら2つのページをチェックすることができます: