Reputation: 99
In my application identifiers coming from the server and we are using them as view controller identifiers. Here I would like to check whether the ViewController with a specified identifier available or not. If available then only push to that controller otherwise just return. I have written code as below.
let identifier = Constants.menuSections[indexPath.section-1][indexPath.row-1]
if let vc1 = (self.storyboard?.instantiateViewController(withIdentifier:identifier)){
let navi = BaseNaviViewController(rootViewController:vc1)
navi.navigationBar.tintColor = .white
navi.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
sideMenuController?.embed(centerViewController:navi, cacheIdentifier:identifier)
}else {
return
}
Here I'm getting an error saying
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Storyboard () doesn't contain a view controller with identifier 'abc''
Upvotes: 0
Views: 973
Reputation: 99
Finally, I got a solution
extension UIStoryboard {
func instantiateVC(withIdentifier identifier: String) -> UIViewController? {
// "identifierToNibNameMap" – dont change it. It is a key for searching IDs
if let identifiersList = self.value(forKey: "identifierToNibNameMap") as? [String: Any] {
if identifiersList[identifier] != nil {
return self.instantiateViewController(withIdentifier: identifier)
}
}
return nil
}
}
And I have used this method like below
let identifier = Constants.menuSections[indexPath.section-1][indexPath.row-1]
if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateVC(withIdentifier: identifier) {
let navi = BaseNaviViewController(rootViewController:viewController)
navi.navigationBar.tintColor = .white
navi.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
sideMenuController?.embed(centerViewController:navi, cacheIdentifier:identifier)
}
else {
ServerService.ShowAlertMessage(ErrorMessage: "No controller Available", title: "Oops . . . !", view: self)
}
Upvotes: 2
Reputation: 13577
If I am not wrong, You’re trying to achieve dynamic screen redirection as per storyboard identifier
and You get storyboard_id
from Array.
Earlier, I have worked with the same kind of requirements and also suffering from the same issue. Unfortunately, there is no solution to stop to crash if storyboard_id
not exist.
At that time, I have added an empty storyboard_id
if destination ViewController is not available, Before redirection, I was checked if storyboard_id
is empty and then Skip redirection code.
let identifier = Constants.menuSections[indexPath.section-1][indexPath.row-1]
if identifier.count == 0{
return
}else{
let vc1 = (self.storyboard?.instantiateViewController(withIdentifier:identifier))
let navi = BaseNaviViewController(rootViewController:vc1)
navi.navigationBar.tintColor = .white
navi.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
sideMenuController?.embed(centerViewController:navi, cacheIdentifier:identifier)
}
Thanks
Upvotes: 0
Reputation: 21
This method will return nil if the identifier doesn't exist, so just check for that with an NSAssert.
Upvotes: 0
Reputation: 16200
You can store all the identifiers in enum like this:
enum Identifier: String {
case viewcontroller
var storyboardName: String {
switch self {
case .viewcontroller : return "Main"
}
}
}
if let validIdentifier = Identifier(rawValue: "vc") {
let storyboard = UIStoryboard(name: validIdentifier.storyboardName, bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: validIdentifier.rawValue)
}
Upvotes: -1