Non-'@objc' method 'presentationController(_:viewControllerForAdaptivePresentationStyle:)' does not satisfy optional requirement of '@objc' protocol 'UIAdaptivePresentationControllerDelegate'
@objc
を追加しようとしましたが、助けにはなりません@objc protocol P1 : UIAdaptivePresentationControllerDelegate {
}
extension P1 where Self : UIViewController {
func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
return UIViewController()
}
}
class A : UIViewController, P1 {
}
私はあなたの質問に答えることができると思いますが、それはあなたが好む答えではありません。
TL; DR:@objc
関数は、現在プロトコル拡張に含まれていない可能性があります。代わりに基本クラスを作成できますが、これは理想的なソリューションではありません。
まず、この質問/回答( Cancel Swift Objective-cでアクセスされるプロトコルの拡張機能で定義されたメソッド )は、プロトコル拡張機能が内部でディスパッチされる方法のために、プロトコル拡張で宣言されたメソッドはobjc_msgSend()
関数からは見えないため、Objective-Cコードからは見えません。拡張機能で定義しようとしているメソッドはObjective-Cに表示される必要があるため(UIKit
が使用できるように)、@objc
を含めないことを叫びますが、一度含めると、@objc
はプロトコル拡張で許可されていないため、大声で叫びます。これはおそらく、プロトコル拡張が現在Objective-Cから認識できないためです。
@objc
を追加すると、エラーメッセージに「@objcはクラスのメンバー、@ objcプロトコル、およびクラスの具体的な拡張機能でのみ使用できる」と表示されることもわかります。これはクラスではありません。 @objcプロトコルへの拡張は、プロトコル定義自体にある(つまり要件内にある)と同じではなく、「コンクリート」という言葉は、プロトコル拡張が具体的なクラス拡張としてカウントされないことを示唆しています。
残念ながら、これにより、Objective-Cフレームワークでデフォルトの実装を表示する必要がある場合、プロトコル拡張機能を使用できなくなります。最初は、Swiftコンパイラが準拠する型がクラスであることを保証できなかったため、@objc
がプロトコル拡張で許可されていないと考えました(UIViewController
を明示的に指定した場合でも) 。そこで、class
要件をP1
に設定しました。これは機能しませんでした。
おそらく唯一の回避策は、ここでプロトコルの代わりに基本クラスを使用することですが、クラスは単一の基本クラスのみを持ち、複数のプロトコルに準拠するため、これは明らかに完全に理想的ではありません。
このルートに進むことを選択した場合は、この質問( Swift 3 ObjCオプションプロトコルメソッドはサブクラスで呼び出されません )を考慮してください。 Swift 3の別の現在の問題は、サブクラスがスーパークラスのオプションのプロトコル要件実装を自動的に継承しないことです。その質問に対する答えは、@objc
の特別な適応を使用して回避します。
これはSwiftオープンソースプロジェクトで作業している人々の間ですでに議論されていると思いますが、 AppleのBug Reporter を使用することで確実に認識できます。 Swiftコアチームへの道、または Swiftのバグレポーター 。ただし、これらのどちらでも、バグが広すぎるか、既知であることがわかります。 Swiftチームは、あなたが探しているものを新しい言語機能であると考えるかもしれません。その場合、最初に メーリングリスト をチェックアウトする必要があります。
2016年12月、この問題 報告された Swiftコミュニティに。この問題は、中程度の優先度で未解決としてマークされていますが、次のコメントが追加されました。
これは意図されたものです。プロトコルへの適合後に拡張機能を追加できるため、すべての採用者にメソッドの実装を追加する方法はありません。ただし、拡張機能がプロトコルと同じモジュールにある場合は許可できると思います。
ただし、プロトコルは拡張機能と同じモジュールにあるため、将来のバージョンのSwiftでこれを行うことができる可能性があります。
2017年2月、この問題 公式にクローズされました Swiftコアチームメンバーの1人による「Wo n't Do」として、次のメッセージが表示されます。
これは意図的なものです。Objective-Cランタイムの制限により、プロトコル拡張は@objcエントリポイントを導入できません。 NSObjectに@objcエントリポイントを追加する場合は、NSObjectを拡張します。
NSObject
またはUIViewController
を拡張しても、望みどおりにはなりませんが、残念ながら可能になるようには見えません。
(非常に)長期的には、@objc
メソッドへの依存を完全に排除できる可能性がありますが、Cocoaフレームワークは現在Swiftで記述されていないため、その時間はすぐには来ないでしょう(そして、安定したABIになるまではできません)。