I am new to iOS development. I have a story board with 2 view controllers, I link them up to UIViewController classes, it works when I try load the second class from the first class (like a splash screen going into the main menu) but then the 'menu' does not load the view from the storyboard. It loads a black screen. I have assigned the class to the viewcontroller in the right hand sidebar of the storyboard and coloured the screen red to see if it loads the class, it does, but if I take the red out, it loads a black screen, not the desired screen from the storyboard.
Screen 1's (Splash)'s code:
func switchScreen() {
let secondViewController:vcMainLogin = vcMainLogin()
self.presentViewController(secondViewController, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "switchScreen", userInfo: nil, repeats: false)
}
Screen 2's (login / menu)'s code:
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.redColor()
// Do any additional setup after loading the view.
}
It is loading because the colour of the screen turns red, but when I take that out it loads black, not the screen from the storyboard.
You need to instantiate the view controller from the storyboard and not create it via the initialize function. To do this you need to assign your view controller a storyboardID in interface builder (view -> utilities -> identity inspector). In this example I load a view controller with a storyboard ID of "VC2" from the storyboard named "MainStoryboard".
let mainStoryboard = UIStoryboard(name: "MainStoryboard", bundle: NSBundle.mainBundle())
let vc : UIViewController = mainStoryboard.instantiateViewControllerWithIdentifier("VC2") as UIViewController
Here is the equivalent objective-c code for reference
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"mainStoryboard" bundle:[NSBundle mainBundle]];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VC2"];
I am not yet used to Swift. However, it looks ot me as if you load just instanticate a brand new mcMainLogin view controller instead of initializing it from a nib file or loading it from a story board. Naturally it would be empty (black).
Go back to the references or wait for somebody with Swift experience to tell you how to load the view controller from the storyboard.
If you create all your view controllers programmatically and do the navigation programatically then there is no need for storyboards at all. You'd be far better of either complying to the storyboard concept including navigation at least in 90+ % of all navigation events or work with individutal nib/xib files.
Related
Hi I'm new to iOS Development, I'm developing an iOS Application in that I want to use same footer throughout the app. Now I'm creating different uiviews in every controller but this is not optimal way. How can I create single uiview and reuse it in app. I'm using storyboards.In my footer I have four buttons
Create your reusable view as a XIB and load it programatically where ever you need it. This answer shows how to handle XIBs.
This should work fine for your footer.
For more complex reusable views, which make sense to have their own UIViewConroller:
create the viewController in storyboard
instantiate it like this:
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
add it as child viewController like this:
func add(childViewController controller: UIViewController, embedViewIn containerView: UIView) {
controller.willMove(toParentViewController: self)
addChildViewController(controller)
containerView.addSubview(controller.view)
// addCustomConstraints
}
You can later remove the child viewController like this:
func remove(childViewController controller: UIViewController) {
controller.willMove(toParentViewController: nil)
controller.view.removeFromSuperview()
controller.removeFromParentViewController()
}
You have to use custom tabBar, Have a look at https://github.com/hartlco/MHCustomTabBarController this link, I have implemented it its easy to understand.
In my app I use side bar as in facebook. when the user slides out the side bar a uiimageview is displayed. when user taps on the image it takes hm to a different viewcontroller. the problem i am facing is that I have created sidebar programatically and the other view to which I want to navigate the user is created using storyboard. So my source view is created programatically and destination view is created using storyboard. So can someone explain me if there is any way of using "Segue" in this scenario. Since i can not create segue using storyboard I need to do it programatically but even after a lot of googling i could not find the answer.
Well, to get another instance of another storyboard programmatically you can use something like:
let newController = UIStoryboard(name: "MyStoryboard", bundle: nil).instantiateViewControllerWithIdentifier("MyIdentifier") as! MyViewController
and then you push to your navigation controller, or add as a child view controller or something...
If you don't wanna bother with identifiers you can just use the instantiateInitialViewController instead of instantiateViewControllerWithIdentifier
Might help
"userSB" is the viewcontroller storyboard identifier
#IBAction func tapSearchCriteria(_ sender: Any?) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let aVC = storyboard.instantiateViewController(withIdentifier: "userSB") as? AViewController
aVC?.modalPresentationStyle = UIModalPresentationStyle.custom
aVC?.transitioningDelegate = self
aVC?.udelegate = self
self.present(aVC!, animated: true, completion: nil)
}
I have just made a small transition so my project loads a different storyboard as its main (did it in the info.plist).
I have my new storyboard to keep my viewController that are responsible for login screen etc. Just to make it more clear.
After the login button is tapped I want to initiate a navigationController from another storyboard:
func instantiateViewController(fromStoryboard storyboard: String, withIdentifier identifier: String) -> UIViewController! {
let storyboard = UIStoryboard(name: storyboard, bundle: nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier(identifier)
return viewController
}
#IBAction func loginButtonTapped(sender: UIButton) {
let viewController = instantiateViewController(fromStoryboard: "Main", withIdentifier: "MainNavigationController")
presentViewController(viewController, animated: true, completion: nil)
}
Everything works correctly but one thing is driving me nuts.
After presenting the MainNavigationController from Main.storyboard its view hierarchy is not maintained.
What I mean is, the labels and buttons which supposed to be on top of another, full screen UIView (but are not its child and so they should remain) are now behind it.
What might be causing this and what is the simplest way to make them appear on top (as they do whey I open main.storyboard)
EDIT
I added a line of code in the rootView of the MainNavigationController in its viewDidLoad method:
self.view.sendSubviewToBack(wholeScreenView)
and it solved the problem.
However, does anybody know why do I have to code it myself and the views are not like in the Main.storyboard?
The storyboard is not configured the way you think it is. Your wholeScreenView is in fact in front of the other views, in the storyboard. The other views (the labels and buttons) are not subviews of wholeScreenView; they are subviews of the main view, and so is wholeScreenView. It is a later subview, so it is in front of them.
I'm trying to program an iOS App in Swift, where there would be a splash screen before the tab bar screen.
I've looked at:
http://sweettutos.com/2014/01/08/present-a-login-screen-before-the-tab-bar-controller-in-a-uitabbarcontroller-based-app/
Loading a Welcome Screen (Splash Screen) before TabBarController
but both of them require a nib file and I did all my UI in storyboard.
Here's my main question:
The code on the website has something like this:
ControllerName(nibName: "NibName", bundle: nil);
Is there any way I could do the same thing without the nib file and use storyboard?
Assuming that you have the TabBarController already in storyboard, you would add another view controller next to it.
Then you would click on the new view, and in the attributes inspector, check off "Is initial View Controller".
That makes that new view the first thing that comes up when the app is opened. To go to the tabBarController, I would probably have some button on that first view that just has a segue(control drag) to the TabBarController.
What you can do is the following the example in which the tab bar view controller is set as initial viewcontroller you can
Drag and drop another UIViewController from the Object Library into the storyboard object library.
Click on the UIViewController and assign it a StoryboardID
StoryboardID.
In your first view controller class you can access the storyboard and create an instance of the new view controller, that you dragged and dropped before, using the storyboard id, you can do it this in the viewDidAppear override function and present the new view controller modally.
override func viewDidAppear(animated: Bool) {
let myStoryboard = self.storyboard
let modalViewController = myStoryboard?.instantiateViewControllerWithIdentifier("ModalViewControlllerID")
presentViewController(modalViewController!, animated: true, completion: nil)
}
To instantiate programmatically a viewController from a storyboard in a similar way as you would do from a xib with ControllerName(nibName: "NibName", bundle: nil), it's:
UIStoryboard(name: "StoryboardName", bundle: nil)
.instantiateViewController(withIdentifier: "ControllerName")
But you must not forget to set the arbitrary identifier of your viewController in the storyboard under Storyboard ID:
Drag navigationController and viewController to storyboard and make navigationcontroller as initial viewcontroller then push tabbarcontroller from viewcontroller.
Thanks,
Nada Gamal
I just needed to do the same for my project. Here is my solution.
I created a ViewController and made it the Storyboard Entry Point in the Main.storyboard. I previously had a TabViewController with all kinds of setup and needed only 1 change there.
TabBarController should have a StoryboardID, I named my "TabBarID".
I created a new LaunchViewController swift file with that new ViewController added to my Main.storyboard and assigned it in Main.storyboard.
Here is that class. Very simple with a timer that once over the threshold will then present the TabBarViewController in fullscreen.
class LaunchViewController: UIViewController {
var timer = Timer()
var time = 0
var threshold = 2
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundTheme(theme: .orangeWhite)
Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)
}
#objc func updateTimer() {
time += 1
if time > threshold {
timer.invalidate()
guard let storyboard = self.storyboard else {
//failed to find storyboard
return
}
let tabBarController = storyboard.instantiateViewController(identifier: "TabBarID")
tabBarController.modalPresentationStyle = .fullScreen
present(tabBarController, animated: true, completion: nil)
}
}
}
I am trying to open next viewController after choosing photo from gallery. I can get image from gallery, but after that I dont know how to open controller next to it. !.This is photo of that storyboard
You can put an UITapGestureRecognizer inside your UIImageView using Interface Builder or in code (as you want), I prefer the first. The you can put an #IBAction and handle the tap inside your UIImageView, Don't forget to set the UserInteractionEnabled to true in Interface Builder or in code.
To present the next view controller you can do it in code like below or just using Interface Builder using a segue through the UITapGestureRecognizer you set before (it's up to you).
To present the view controller manually like in the following code you need to set the Storyboard ID for you view controller like in the following picture (in the Identity Inspector panel):
#IBAction func imageTapped(sender: AnyObject) {
// Set the storyboard name by default is Main
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
// Instantiate the ViewController with the name you set before like in the image
let nextViewController = storyboard.instantiateViewControllerWithIdentifier("ViewControllerB") as! UIViewController
// present the nextViewController
self.presentViewController(nextViewController, animated: true, completion: nil)
}
I hope this help you.