[英]How do I implement a Swift protocol with a generic constrained type property?
[英]How to initialize a class with a property that is constrained to a generic type and a protocol in Swift
我正在使用符合UIViewController
协议的Glideable
初始化我的Glide
class,如下所示:
class Glide : NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate {
private var card: (Glideable & UIViewController)?
init(parentViewController: UIViewController, configuration: GlideConfiguration, card: Glideable & UIViewController) {}
}
因此,当您创建此 class 的实例时,您传递了一个也符合UIViewController
协议的Glideable
。 现在我想稍微改变一下,如果你有一个UIViewController
包裹在一个UINavigationController
,如下所示:
let navCardView = UINavigationController(rootViewController: CardViewController())
然后我用navCardView
初始化我的Glide
class ,它不再只是UIViewController
而是UINavigationController
但我还想确保CardViewController
协议Glideable
。
使用 Generics 实现此类架构的任何帮助都会有所帮助。 我似乎无法理解如何使泛型类型受限于协议。
任何想法将不胜感激。 谢谢。
我不确定您到底要做什么,但通常您应该使用枚举来表示 swift 中的异构类型。 Here is how you can use a enum to handle the two cases, navigation controller and no navigation controller as well as make the class generic to a specific kind of view controller:
import SwiftUI
import PlaygroundSupport
import Combine
protocol Glideable { }
typealias GlideableViewController = Glideable & UIViewController
final class Glide<SomeGlidableViewController: GlideableViewController>: NSObject, Glideable {
private enum Wrapped {
case viewController(SomeGlidableViewController), navigationContoller(UINavigationController, SomeGlidableViewController)
var glideViewController: SomeGlidableViewController {
switch self {
case let .viewController(viewController): return viewController
case let .navigationContoller(_, viewController): return viewController
}
}
var navigationController: UINavigationController? {
guard case let .navigationContoller(navigationContoller, _) = self else { return nil }
return navigationContoller
}
}
private let wrappedViewController: Wrapped
init(glideableViewController: SomeGlidableViewController) {
wrappedViewController = .viewController(glideableViewController)
super.init()
commonInit()
}
init?(navigationController: UINavigationController) {
guard let glideableViewController = navigationController.topViewController as? SomeGlidableViewController else {
return nil
}
wrappedViewController = .navigationContoller(navigationController, glideableViewController)
super.init()
commonInit()
}
private func commonInit() {
print("This class wraps a VC of type: \(SomeGlidableViewController.self)")
print("The wrapped VC is \(wrappedViewController.glideViewController)")
if let navigationController = wrappedViewController.navigationController {
print("It is wrapped in a navigation controller")
} else {
print("It is not wrapped in a navigation controller")
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.