2020.09.04
今日は、AppleのCombineフレームワークを使用した通知の監視について学習します。コードは非常にシンプルで、説明はほとんど必要ありません。それでも、システムイベントのあらゆる種類の監視を行うことができます。
タイマーを使用して繰り返しイベントをトリガーする
SwiftUIアプリがバックグラウンドに移動したときに通知を受ける方法
SwiftUIによる特定のアクセシビリティニーズのサポート
タイマーを使用して繰り返しイベントをトリガーする
Triggering events repeatedly using a timer
import SwiftUI
struct ContentView: View {
//let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
let timer = Timer.publish(every: 1, tolerance: 0.5, on: .main, in: .common).autoconnect()
@State private var counter = 0
var body: some View {
Text("Hello, World!")
.onReceive(timer) { time in
if self.counter == 5 {
self.timer.upstream.connect().cancel()
} else {
print("The time is now \(time)")
}
self.counter += 1
}
}
}
SwiftUIアプリがバックグラウンドに移動したときに通知を受ける方法
How to be notified when your SwiftUI app moves to the background
Combine(組み合わせ)
UIApplication.willResignActiveNotification
アプリがバックグラウンドに移行し始めたときに通知センターからメッセージが送信される。
willEnterForegroundNotification
アプリを再度アクティブ化
userDidTakeScreenshotNotification
ユーザーがスクリーンショットを撮ったことを検出する
UIApplication.significantTimeChangeNotification ユーザーが時計を変更したとき、または夏時間が変更されたときに呼び出されます。
UIResponder.keyboardDidShowNotification キーボードが表示されているときに呼び出されます。
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Text("Hello, World!")
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
print("Moving to the background!")
}
Text("Hello, World!")
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
print("Moving back to the foreground!")
}
Text("Hello, World!")
.onReceive(NotificationCenter.default.publisher(for: UIApplication.userDidTakeScreenshotNotification)) { _ in
print("User took a screenshot!")
}
}
}
}
通常のレイアウトに単純な緑の背景を使用していますが、色なしで区別が有効になっている場合は、黒の背景を使用してチェックマークを追加します。
struct ContentView: View {
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
var body: some View {
HStack {
if differentiateWithoutColor {
Image(systemName: "checkmark.circle")
}
Text("Success")
}
.padding()
.background(differentiateWithoutColor ? Color.black : Color.green)
.foregroundColor(Color.white)
.clipShape(Capsule())
}
}
SwiftUIによる特定のアクセシビリティニーズのサポート
Supporting specific accessibility needs with SwiftUI
accessibilityDifferentiateWithoutColor「色なしで区別する」
通常のレイアウトに単純な緑の背景を使用していますが、色なしで区別が有効になっている場合は、黒の背景を使用してチェックマークを追加します。
accessibilityReduceMotion
もう1つの一般的なオプションは、モーションの削減です。
import SwiftUI
struct ContentView: View {
@Environment(\.accessibilityReduceTransparency) var reduceTransparency
var body: some View {
Text("Hello, World!")
.padding()
.background(reduceTransparency ? Color.black : Color.black.opacity(0.5))
.foregroundColor(Color.white)
.clipShape(Capsule())
}
}
/*
struct ContentView: View {
@Environment(\.accessibilityReduceMotion) var reduceMotion
@State private var scale: CGFloat = 1
var body: some View {
Text("Hello, World!")
.scaleEffect(scale)
.onTapGesture {
if self.reduceMotion {
self.scale *= 1.5
} else {
withAnimation {
self.scale *= 1.5
}
}
}
}
}
*/
/*
func withOptionalAnimation<Result>(_ animation: Animation? = .default, _ body: () throws -> Result) rethrows -> Result {
if UIAccessibility.isReduceMotionEnabled {
return try body()
} else {
return try withAnimation(animation, body)
}
}
struct ContentView: View {
@Environment(\.accessibilityReduceMotion) var reduceMotion
@State private var scale: CGFloat = 1
var body: some View {
Text("Hello, World!")
.scaleEffect(scale)
.onTapGesture {
withOptionalAnimation {
self.scale *= 1.5
}
}
}
}
*/
/*
struct ContentView: View {
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
var body: some View {
HStack {
if differentiateWithoutColor {
Image(systemName: "checkmark.circle")
}
Text("Success")
}
.padding()
.background(differentiateWithoutColor ? Color.black : Color.green)
.foregroundColor(Color.white)
.clipShape(Capsule())
}
}
*/