私は次のコードを持っています:
func registerNotification(name:String, selector:Selector)
{
NSNotificationCenter.defaultCenter().addObserver(self, selector: selector, name: name, object: nil)
}
func registerKeyboardNotifications()
{
let isInPopover = navigationController?.popoverPresentationController != nil
let ignore = isInPopover && DEVICE_IS_IPAD
if !ignore {
registerNotification(UIKeyboardWillShowNotification, selector: Selector("keyboardWillShow:"))
registerNotification(UIKeyboardWillHideNotification, selector: Selector("keyboardWillHide:"))
}
}
UIViewController
の拡張。このコードは、キーボード通知に登録するために多くのビューコントローラーによって再利用されます。ただし、Swift 2.2では、警告が表示されます。新しい#selector
構文ですが、この場合の実装方法はわかりません。
正しい解決策は、プロトコルを作成し、そのプロトコルに準拠するインスタンスに対してのみUIViewController
を拡張することだと思います。これまでの私のコード:
@objc protocol KeyboardNotificationDelegate
{
func keyboardWillShow(notification: NSNotification)
func keyboardWillHide(notification: NSNotification)
}
extension UIViewController where Self: KeyboardNotificationDelegate
{
func registerKeyboardNotifications()
{
let isInPopover = navigationController?.popoverPresentationController != nil
let ignore = isInPopover && DEVICE_IS_IPAD
if !ignore {
registerNotification(UIKeyboardWillShowNotification, selector: #selector(KeyboardNotificationDelegate.keyboardWillShow(_:)))
registerNotification(UIKeyboardWillHideNotification, selector: #selector(KeyboardNotificationDelegate.keyboardWillHide(_:)))
}
}
}
しかし、これは私にエラーをもたらします
trailing where clause for extension of non-generic type
拡張行。何か案は?
解決策は、拡張句の順序を切り替えるのが簡単でした。
extension UIViewController where Self: KeyboardNotificationDelegate
する必要があります
extension KeyboardNotificationDelegate where Self: UIViewController
extension Foo where ...
は、Foo
が
Self
が特定の(オブジェクト/参照)型である場合、または何らかの型制約に準拠している場合のデフォルト実装で拡張するプロトコル。例えば。
// 1
class Foo<T> { }
extension Foo where T: IntegerType {}
struct Foz<T> {}
extension Foz where T: IntegerType {}
// 2
protocol Bar {
associatedtype T
}
extension Bar where T: IntegerType {}
// 3
protocol Baz {}
extension Baz where Self: IntegerType {}
class Bax<T>: Baz {}
extension Baz where Self: Bax<Int> {
func foo() { print("foo") }
}
let a = Bax<Int>()
a.foo() // foo
あなたの場合、UIViewController
は非ジェネリッククラス型であり、上記の2つのいずれにも適合しません。
あなた自身の答えで書いたように、解決策は、デリゲートプロトコルを、Self: UIViewController
、UIViewController
を拡張しようとするのではなく。