我發現我的故事板變得非常複雜,並決定將它分成不同的故事板。但是我希望能夠自由地實例化一個UIViewController,無論我把視圖控制器放在哪裏。這樣,我就可以將View Controller從Storyboard移動到Storyboard,而無需記住我把View Controller放在哪裏,而且我也不必更新代碼,因爲它們全都使用相同的代碼來實例化具有該名稱的相同View Controller,而不管它駐留在何處。如何在Swift中獲取UIStoryboard數組?
因此,我想是這樣創造的UIViewController的擴展:
extension UIViewController {
func instantiate (named: String?, fromStoryboard: String? = nil) -> UIViewController? {
guard let named = named else { return nil; }
if let sbName = fromStoryboard {
let sb = UIStoryboard(name: sbName, bundle: nil);
return sb.instantiateViewController(withIdentifier: named);
}
else {
for sb in UIStoryboard.storyboards {
if let vc = sb.instantiateViewController(withIdentifier: named) {
return vc;
}
}
}
return nil;
}
的問題是,我無法找到屬性/方法返回故事板的實例列表像.storyboards
任何地方。有沒有解決這個問題的方法?我知道我可能有一個靜態的故事板名稱列表,但這樣,擴展名將不會是動態的,並且與項目無關。
任何人都可以幫忙嗎?謝謝。
編輯:
組合來自here的accepted answer和答案安全實例化視圖 - 控制(並返回零,如果沒有找到),這是我的代碼:
UIStoryboard + Storyboards.swift:
extension UIStoryboard {
static var storyboards : [UIStoryboard] {
let directory = Bundle.main.resourcePath! + "/Base.lproj"
let allResources = try! FileManager.default.contentsOfDirectory(atPath: directory)
let storyboardFileNames = allResources.filter({ $0.hasSuffix(".storyboardc")})
let storyboardNames = storyboardFileNames.map({ ($0 as NSString).deletingPathExtension as String })
let storyboardArray = storyboardNames.map({ UIStoryboard(name: $0, bundle: Bundle.main)})
return storyboardArray;
}
func instantiateViewControllerSafe(withIdentifier identifier: String) -> UIViewController? {
if let availableIdentifiers = self.value(forKey: "identifierToNibNameMap") as? [String: Any] {
if availableIdentifiers[identifier] != nil {
return self.instantiateViewController(withIdentifier: identifier)
}
}
return nil
}
}
UIViewController + Instantiate.swift:
extension UIViewController {
static func instantiate (named: String?, fromStoryboard: String? = nil) -> UIViewController? {
guard let named = named else { return nil; }
if let sbName = fromStoryboard {
let sb = UIStoryboard(name: sbName, bundle: nil);
return sb.instantiateViewControllerSafe(withIdentifier: named);
}
else {
for sb in UIStoryboard.storyboards {
if let vc = sb.instantiateViewControllerSafe(withIdentifier: named) {
return vc;
}
}
}
return nil;
}
}
限制所有故事板文件必須位於Base.lproj
文件夾中。我知道,這不是運行時間最有效的代碼。但現在,這很容易理解,我可以忍受這一點。 :)感謝大家誰幫助!
您可以在此行self.navigationController中獲取storyboards viewcontroller的導航堆棧數組 –
。viewControllers你可以得到你的viewcontrollers的導航數組 –
@JitendraModi你的意思是'self.navigationController.viewControllers'?我的意思是我想從UIStoryboard實例化新的viewController,而不是訪問導航堆棧數組上已經存在的viewControllers。 –