繁体   English   中英

如何使用受限于泛型类型的属性和 Swift 中的协议初始化 class

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM