【问题标题】:Load viewcontroller with nib using generics使用泛型加载带有 nib 的视图控制器
【发布时间】:2016-11-18 12:23:41
【问题描述】:

目前要加载具有相同 nibname 的视图控制器,我使用如下代码

let recommendationVC : RecommendationVC = RecommendationVC(nibName: "RecommendationVC", bundle: nil)

我觉得指定 nibname 是不必要的,因为它与控制器名称相同。所以我决定使用泛型并使用泛型推断类型和笔尖名称

protocol NibIdentifiable {
    static var nibNameIdentifier: String { get }
}

// MARK: - Indentifies each storyboard from its classname.
extension NibIdentifiable where Self: UIViewController {
    static var nibNameIdentifier: String {
        return String(describing: self)
    }
}
extension UIViewController :NibIdentifiable
{

}

extension UIViewController {
    func instantiate<Controller: UIViewController>(_: Controller.Type) -> Controller where Controller: NibIdentifiable {

        guard let controller = Self(nibName:Controller.nibNameIdentifier,bundle:nil) as? Controller else {
            fatalError("Could not dequeue cell with identifier: \(Controller.nibNameIdentifier)")
        }

        return controller
    }
}

但在尝试创建 VC 实例时,

 let recommendationVC :RecommendationVC = UIViewController.instantiate()

接收错误 无法推断通用参数“控制器”

这种方法有什么问题?

【问题讨论】:

  • 让推荐VC :RecommendationVC = RecommendationVC.instantiate() 试试这样
  • @KonstantinKryzhanovsky 我试过了。面临同样的问题
  • 当 nib 名称与类名相同时,您甚至不必指定它。只是做let recommendationVC = RecommendationVC() 应该可以正常工作。
  • 你可以在这里查看我的答案stackoverflow.com/a/44215068/919545

标签: ios swift generics uiviewcontroller nib


【解决方案1】:

为 UIViewController 添加扩展

extension UIViewController {
    static func instantiateFromNib() -> Self {
        func instantiateFromNib<T: UIViewController>(_ viewType: T.Type) -> T {
            return T.init(nibName: String(describing: T.self), bundle: nil)
        }

        return instantiateFromNib(self)
    }
}

然后就这样使用

让 myViewController = MyViewController.instantiateFromNib()

【讨论】:

  • 谢谢!这对我有用,尽管我没有使用内部功能;我直接打电话给return self.init(nibName: String(describing: self), bundle: nil);
【解决方案2】:
class Rec : UIViewController  {
    let r : String = "1231231"
}

protocol NibIdentifiable {
    static var nibNameIdentifier: String { get }
}

// MARK: - Indentifies each storyboard from its classname.
extension NibIdentifiable where Self: UIViewController {
    static var nibNameIdentifier: String {
        return String(describing: self)
    }

    static func instantiate() -> Self {

        guard let controller = Self(nibName:Self.nibNameIdentifier,bundle:nil) as? Self else {
            fatalError("Could not dequeue cell with identifier: \(Self.nibNameIdentifier)")
        }

        return controller
    }

}

extension UIViewController : NibIdentifiable {
}

let x : Rec = Rec.instantiate()

这必须有效。

就我而言,我使用一些 Storyboardable 协议。并从特定的故事板启动控制器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    相关资源
    最近更新 更多