W Objective-C niestandardowe powiadomienie to zwykły NSString, ale nie jest to oczywiste w wersji WWDC Swift 3, jak to powinno być.Jak utworzyć niestandardowe powiadomienia w Swift 3?
Odpowiedz
Można również użyć protokołu do tego
protocol NotificationName {
var name: Notification.Name { get }
}
extension RawRepresentable where RawValue == String, Self: NotificationName {
var name: Notification.Name {
get {
return Notification.Name(self.rawValue)
}
}
}
a następnie zdefiniować swoje nazwiska powiadomień jako enum
gdziekolwiek chcesz . Na przykład:
class MyClass {
enum Notifications: String, NotificationName {
case myNotification
}
}
i używać go jak
NotificationCenter.default.post(name: Notifications.myNotification.name, object: nil)
ten sposób nazwy powiadomień zostanie oddzielona od Fundacji Notification.Name
. I będziesz musiał tylko zmodyfikować swój protokół w przypadku zmiany implementacji dla Notification.Name
.
Notification.post jest zdefiniowany jako:
public func post(name aName: NSNotification.Name, object anObject: AnyObject?)
W celu C nazwa zgłoszenie jest zwykły NSString. W Swift jest zdefiniowany jako NSNotification.Name.
NSNotification.Name jest zdefiniowany jako:
public struct Name : RawRepresentable, Equatable, Hashable, Comparable {
public init(_ rawValue: String)
public init(rawValue: String)
}
To jest trochę dziwne, ponieważ chciałbym oczekiwać, że będzie wyliczenia, a nie jakąś niestandardową struct z pozoru nie więcej korzyści.
Jest typealias w powiadamianiu o NSNotification.Name:
public typealias Name = NSNotification.Name
Mylące jest to, że zarówno Powiadamianie i NSNotification istnieć w Swift
Więc w celu zdefiniowania swój własny powiadomienia zrobić somethine jak:
public class MyClass {
static let myNotification = Notification.Name("myNotification")
}
Wtedy to nazwać:
NotificationCenter.default().post(name: MyClass.myNotification, object: self)
Dobra odpowiedź. Kilka uwag: * To trochę dziwne, ponieważ spodziewałem się, że będzie to Enum * - Wyliczenie to zbiór * zamknięty *. Jeśli "Notification.Name" było wyliczeniem, nikt nie byłby w stanie zdefiniować nowych powiadomień. Używamy struktur dla typów typu "enum-like", które muszą umożliwiać dodawanie nowych członków. (Zobacz propozycję [swift-evolution] (https://github.com/apple/swift-evolution/blob/master/proposals/0033-import-objc-constants.md).) – rickster
* Mylącą częścią jest to, że zarówno Powiadomienie i NSNotification istnieją w Swift * - "Notification" jest typem wartości (struct), dzięki czemu może korzystać z semantyki Swifta dla value (im) zmienności. Ogólnie rzecz biorąc, typy Fundacji upuszczają swoje "NS" w Swift 3, ale tam, gdzie istnieje jeden z nowych typów wartości fundamentowych, aby go zastąpić, stary typ referencyjny pozostaje w miejscu (zachowując nazwę "NS"), dzięki czemu można go nadal używać, gdy potrzebujesz semantyki referencyjnej lub jej podklasy. Zobacz [propozycję] (https://github.com/apple/swift-evolution/blob/master/proposals/0069-swift-mutability-for- foundation.md). – rickster
Pozwól mi wyjaśnić: Oczekuję, że nazwy powiadomień będą wyliczone, podobnie jak błędy. Możesz zdefiniować własne wyliczenia błędów i dostosować je do ErrorType. – hexdreamer
Jest czystszy (chyba) sposób to osiągnąć
extension Notification.Name {
static let onSelectedSkin = Notification.Name("on-selected-skin")
}
I wtedy można go używać jak to
NotificationCenter.default.post(name: .onSelectedSkin, object: selectedSkin)
Używam powyższego kodu. To jest właściwość statyczna. –
To jest świetny sposób, aby to zrobić. Upvote – crashoverride777
Bardzo czysto, bardzo mi się podoba –
To jest po prostu odwołać
// Add observer:
NotificationCenter.default.addObserver(self,
selector: #selector(notificationCallback),
name: MyClass.myNotification,
object: nil)
// Post notification:
let userInfo = ["foo": 1, "bar": "baz"] as [String: Any]
NotificationCenter.default.post(name: MyClass.myNotification,
object: nil,
userInfo: userInfo)
You można dodać niestandardowy inicjator do NSNotification.Name
extension NSNotification.Name {
enum Notifications: String {
case foo, bar
}
init(_ value: Notifications) {
self = NSNotification.Name(value.rawValue)
}
}
Zastosowanie:
NotificationCenter.default.post(name: Notification.Name(.foo), object: nil)
Prostszy sposób:
let name:NSNotification.Name = NSNotification.Name("notificationName")
NotificationCenter.default.post(name: name, object: nil)
NSNotification.Name(rawValue: "myNotificationName")
Zrobiłem własną implementację miksowania rzeczy tam i tam i uważam to za najwygodniejsze. Dzielenie na który każdy że może być zainteresowany:
public extension Notification {
public class MyApp {
public static let Something = Notification.Name("Notification.MyApp.Something")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(self.onSomethingChange(notification:)),
name: Notification.MyApp.Something,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@IBAction func btnTapped(_ sender: UIButton) {
NotificationCenter.default.post(name: Notification.MyApp.Something,
object: self,
userInfo: [Notification.MyApp.Something:"foo"])
}
func onSomethingChange(notification:NSNotification) {
print("notification received")
let userInfo = notification.userInfo!
let key = Notification.MyApp.Something
let something = userInfo[key]! as! String //Yes, this works :)
print(something)
}
}
Zaletą korzystania teksty stałe jest to, że możemy uzyskać kompilator, by sprawdzić, czy nazwa jest prawidłowa. Zmniejsza potencjalne problemy i ułatwia refaktoryzację.
Dla tych, którzy lubią za pomocą teksty stałe zamiast cudzysłowami w nazwach powiadomień, kod ten załatwia sprawę:
enum MyNotification: String {
case somethingHappened
case somethingElseHappened
case anotherNotification
case oneMore
}
extension NotificationCenter {
func add(observer: Any, selector: Selector,
notification: MyNotification, object: Any? = nil) {
addObserver(observer, selector: selector,
name: Notification.Name(notification.rawValue),
object: object)
}
func post(notification: MyNotification,
object: Any? = nil, userInfo: [AnyHashable: Any]? = nil) {
post(name: NSNotification.Name(rawValue: notification.rawValue),
object: object, userInfo: userInfo)
}
}
Wtedy można go używać tak:
NotificationCenter.default.post(.somethingHappened)
choć niezwiązany do pytanie, to samo można zrobić z sekwencjami scenariusza, aby uniknąć pisania cytowanych ciągów znaków:
enum StoryboardSegue: String {
case toHere
case toThere
case unwindToX
}
extension UIViewController {
func perform(segue: StoryboardSegue) {
performSegue(withIdentifier: segue.rawValue, sender: self)
}
}
Następnie na kontrolerze widoku, nazywają to lubią:
perform(segue: .unwindToX)
jeśli używasz niestandardowych powiadomień String-tylko, że nie ma żadnych powodów, by przedłużyć klas ale String
extension String {
var notificationName : Notification.Name{
return Notification.Name.init(self)
}
}
- 1. Nie można utworzyć zakres w Swift 3
- 2. jak utworzyć instancję klasy z ciągu znaków w swift 3
- 3. Jak napisać informację klawiaturowe w Swift 3
- 4. Wdrożenie layoutAttributesClass() w Swift 3
- 5. Swift: niestandardowe inicjalizatory ViewController
- 6. Niestandardowe sortowanie w Pythonie 3
- 7. Jak utworzyć niestandardowe okno chrome w wpf?
- 8. Jak utworzyć niestandardowe formanty w języku C#?
- 9. Jak utworzyć niestandardowe paski przewijania w IE?
- 10. Jak utworzyć niestandardowe okno dialogowe w vscode?
- 11. Sprawdź ustawienia użytkownika powiadomienia push w Swift
- 12. Uwijanie Uibutton w Swift 3
- 13. Jak korzystać z UnsafeMutablePointer w Swift 3?
- 14. Jak używać wyrażeń regularnych w Swift 3?
- 15. Jak obrócić obraz w Swift 3?
- 16. Swift - jak utworzyć prawidłową sekcjęForSectionIndexTitle?
- 17. IOS Swift - niestandardowe nakładki kamera
- 18. Swift, iboutlet i niestandardowe formanty
- 19. componentsSeparatedByString() Błąd w Swift 3
- 20. Gest przesuń w Swift 3
- 21. swift 3, PHFetchResult.enumerateObjects error
- 22. NSLocale Swift 3
- 23. UIView.animate - Swift 3 - zakończenie
- 24. Wyłącz powiadomienia/wyskakujące okienka Gnome 3/zintegrowane powiadomienia
- 25. managedObjectContext in Swift 3
- 26. Jak utworzyć instancję NSViewController w Swift?
- 27. Jak utworzyć tablicę klasy w Swift
- 28. Jak utworzyć NSMutableDictionary w swift 2.0
- 29. Jak można programowo utworzyć SplitViewController w Swift?
- 30. Jak utworzyć prywatną funkcję w Swift?
To jest dokładnie sposób, w jaki początkowo sądziłem, że powinno działać - powiadomienia powinny być wyliczone. Dzięki za podstęp! – hexdreamer
Nie ma problemu! Zmodyfikowalem kod tak, aby zawierał konformację rozszerzenia na 'NotificationName', więc własność' name' jest dodawana tylko do wyliczeń zgodnych z protokołem. –
Ściśle równoważne, ale bardziej logiczne IMO, można zdefiniować rozszerzenie na NotificationName (zamiast RawRepresentable) w ten sposób: 'extension NotificationName gdzie Self: RawRepresentable, Self.RawValue == String {' – jlj