I'm trying to implement a page menu in my app using the pod from this pre-built page menu pod from github
In the instructions, it says:
var controller : UIViewController = UIViewController(nibName:"controllerNibName", bundle: nil)
controller.title = "SAMPLE TITLE"
controllerArray.append(controller)
things are all set up but i need only "controllerNibName". I am not using storyboard. And haven't made any xib file yet with viewController. so how can i get the NibName of viewController.
controllerNibName string is a file name of your XIB. Where you have done all the UI which is related with your UIViewController.
If your viewController class name and xib file names are same then you can directly allocate the UIViewController. It will pick the xib automatically.
Assume UIViewController name is PageOne & xib name also should be PageOne.xib
let pageOne = PageOne()
if your xib name is different from your view controller name
For Example : Page1.xib
let pageOne = PageOne(nibName:"Page1", bundle: nil)
There is a nice way to get a name of nib (if nib name is equal to controller name i.e. MyViewController.xib and MyViewController):
let controllerName = String(describing: MyViewController.self)
var controller : MyViewController = MyViewController(nibName:controllerName, bundle: nil)
Related
I have the following code which is intended to change views. This code is executed when my 'UITableViewRowAction' is selected and is intended to navigate to a different UITableViewController. However, I am getting the error below and I do not understand what I am doing incorrectly.
let storyBoard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let selectFolderViewController = storyBoard.instantiateViewController(withIdentifier: "SaveArticleTableViewController") as! SaveArticleTableViewController
self.navigationController?.pushViewController(selectFolderViewController, animated: true)
The error that i am getting in the console is:
Could not cast value of type 'UINavigationController' (0x106f5c898) to 'lifesci_PubMed.SaveArticleTableViewController' (0x104dbb658).
All my ViewControllers are embedded within a Navigation Controller
It's very likely that you have not properly set the custom class of the view controller in Storyboard. Here's an image ...
You would type "SaveArticleTableViewController" in that slot.
It's quite possible you have other problem as well, but that will get you going.
The error is actually quite descriptive here:
Could not cast value of type 'UINavigationController' to 'SaveArticleTableViewController'
At first I thought that this was because your view controller SaveArticleTableViewController is not actually set with a custom class. If you're using Interface Builder, make sure you've set the class type in the view controller's property inspector:
If you're doing it in code, make sure your custom class is inheriting properly.
But taking a leap of a guess, your target is "UINavigationController", but your custom class name that it's trying to cast to suggests that your target is a table view "SaveArticleTableViewController". Moreover, I'd bet that this is the tableview that is the source not the destination. I'd double check that you're actually instantiating the right view controller - typically you'd name this something like "SaveArticleDetailViewController", or guessing by your code, maybe it's "SelectFolderViewController", but that's up to you.
For example:
let storyBoard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let selectFolderViewController = storyBoard.instantiateViewController(withIdentifier: "SelectFolderViewController") as! SelectFolderViewController
self.navigationController?.pushViewController(selectFolderViewController, animated: true)
This also requires that you set self.navigationController to the containing nav controller.
I am struggling to figure out how to load a xib from within a storyboard using Swift in XCode.
My main storyboard (Called TabBarNav.storyboard) is a Tab Bar View controller with 4 items (Home, Weight, Meals and Calories).
I have created a seperate XIB UIView called ViewWelcome.xib with corresponding class file ViewWelcome.swift.
The Home items view controller has a class file called "ViewControllerHome.swift"
When the Home tab bar item is touched I want to replace the existing view with the one within ViewWelcome.xib.
In ViewWelcome.xib I have made the files owner ViewControllerHome but when I run the app it is still showing the view that was created with the Home item when I originally created the storyboard.
Reason I am doing it this way: (A Mix of storyboard and xibs) I wanted each section (Home, Weight, Meals and Calories) to be seperate from the storyboard so that the SB doesnt become cluttered and to also later avoid merge issues in git when more than one person works on interface files.
Simplest way is to create & add your nib view in viewDidLoad
func viewDidLoad() {
super.viewDidLoad()
// create and add view from nib
if let viewWelcome = UINib(nibName: " ViewWelcome", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? ViewWelcome {
viewWelcome.frame.size = self.view.size
self.view.addSubview(viewWelcome)
}
}
Otherwise refer to this
This is working for me . Give a try . .
let newView = Bundle.main.loadNibNamed("ViewWelcome", owner: self, options: nil)?.first as! ViewWelcome
self.view = newView
I have a UIViewController that looks a bit like this:
class ProfileViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, ... {
...
convenience init(name: String) {
print("Init with student: \(name)")
self.init()
}
...
}
I have a corresponding Storyboard layout for this, embedded in a UINavigationViewController, linked to a UITabBarController. This seemed like the easiest way to design the layout, and is great for when there's only one instance of this VC required (which is how the app was originally designed).
I'd now like to create multiple tabs from this single design (between 1 and 3), and pass the VC init information programatically, but I'm unsure exactly of the best way to do this - as you can see above I've added a convenience init function based on some reading I've done as that seemed like a good place to start.
It's easy enough to create new named tabs based on the storyboard layout like this:
for user in (users)! {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "profileNC")
controller.tabBarItem.title = user.name
newTabs?.insert(controller, at: 0)
}
self.viewControllers = newTabs
But, doing it this way I don't get to call the init function to pass the UIViewController the information it needs to display correctly.
How can I create my ViewControllers, link the layout to the Storyboard and use the custom init function? Is this even possible?
Any suggestions gratefully appreciated!!
When using a storyboard you cannot use a custom initialiser. You will need to either set the property directly or use a configuration function on the view controller instance after you have created it.
I want to create a specific xib for every screen size, but with one UIViewController.
How can I connect few xibs to one class?
MyClass is your UIViewController
1. Create different xibs
myclass_iphone4
myclass_iphone5
myclass_iphone6
2. Each xib will have as file's owner MyClass to link the outlets
3. Load MyClass dynamically:
let deviceSize = //iphone4, iphone5, ....
let viewcontroller = MyClass(nibName: "myclass_\(deviceSize)", bundle: nil)
Let me know in the comments if it could be ok for you.
Imagine i have a BaseViewController. Then i have 2 scenarios, New and Edit, where both shares the same UI and the most of logic. So i created class NewViewController and EditViewController, subclassing BaseViewController. The problem comes when i try to instantiate "BaseViewController" from the storyboard cause i want to specify which implementation is.
if isEdit {
storyboard.instantiateViewControllerWithIdentifier("baseVCIdentifier") as! EditViewController
} else {
storyboard.instantiateViewControllerWithIdentifier("baseVCIdentifier") as! NewViewController
}
Then i get an error:
Could not cast value of type 'Test.BaseViewController' (0x10ee5e0f0) to 'Test.EditViewController' (0x10ee5f000).
I dont wanto to have both ViewController on the storyboard since i dont want to redo the same UI 2 times.
You can do this using instantiateViewController(identifier:creator:).
I assume you have the view controller in a storyboard, with identifier template. The class assigned to the view controller in the storyboard should be the superclass:
let storyboard = UIStoryboard(name: "main", bundle: nil)
let viewController = storyboard.instantiateViewController(identifier: "template") { coder in
// this passes us with a coder for the storyboard, we can now init the preferred subclass.
if useSubclass {
return SpecialViewController(coder: coder)
} else {
return BaseViewController(coder: coder)
}
}
Here is the documentation
You can't do that. Instead of sub classing create 'interaction manager' classes, or state manager classes. The base view controller would then be provided with a manager instance as part of the segue and it would forward all UI interaction to the manager for processing. You then have a single VC in the storyboard as is required and you can supply a new or edit manager. The managers can also have specific instance variables which the view controller doesn't care about.