Mein bevorzugter Weg, dasselbe zu erreichen, ist mit .sink
von Combine. Dadurch müssen Sie Ihren Handler nicht mit @objc
markieren.
Erstellen Sie zunächst eine Benachrichtigung, wie Sie möchten. Ich verwende gerne ein paar Erweiterungen
extension Notification.Name {
static var tap: Notification.Name {
.init("tap")
}
}
extension Notification {
static func tap(_ point: CGPoint) -> Notification {
Notification(name: .tap, object: point)
}
}
UIKit / Benutzerdefiniertes Objekt
Erstellen Sie dann eine Registrierungsfunktion in einem Objekt, die NotificationCenter.default.publisher(for:)
aufruft:
import Combine
class TapNotifier {
var cancellables: Set = []
func register() {
NotificationCenter.default
.publisher(for: .tap)
.sink { [weak self] tapNotification in
// Dieser Block wird jedes Mal aufgerufen, wenn eine `.tap`-Benachrichtigung empfangen wird.
// Entpacken des gesendeten Objekts
guard let point = tapNotification.object as? CGPoint else {
return
}
// Rufen Sie Ihre Handlerfunktion auf
self?.tapped(at: point)
}
.store(in: &cancellables)
}
func tapped(at point: CGPoint) {
print("An \(point) getippt")
}
}
SwiftUI iOS 15
Der Publisher von NotificationCenter.default kann auch in einer SwiftUI-Ansicht wie folgt beobachtet werden:
extension Notification {
static var tap: Notification {
Notification(name: .tap)
}
}
struct TapsView: View {
@State var taps: Int = 0
var message: String {
"Button \(taps) Mal gedrückt " + (taps == 1 ? "Zeit" : "Zeiten")
}
var body: some View {
Text(message)
.onReceive(NotificationCenter.default.publisher(for: .tap)) { tapNotification in
// Dieser Block wird jedes Mal aufgerufen, wenn eine `.tap`-Benachrichtigung empfangen wird.
taps += 1
}
.onTapGesture {
NotificationCenter.default.post(.tap))
}
}
}
SwiftUI iOS 16+
struct TapsView: View {
@State var taps: Int = 0
var message: String {
"Button \(taps) Mal gedrückt " + (taps == 1 ? "Zeit" : "Zeiten")
}
var body: some View {
Text(message)
.onReceive(NotificationCenter.default.publisher(for: .tap)) { tapNotification in
// Dieser Block wird jedes Mal aufgerufen, wenn eine `.tap`-Benachrichtigung empfangen wird.
// Entpacken des gesendeten Objekts
guard let point = tapNotification.object as? CGPoint else {
return
}
taps += 1
}
.onTapGesture { point in
NotificationCenter.default.post(.tap(point))
}
}
}