Switching to New View Controller does not Activate XIB File - ios

I'm new to Swift, and the class I took taught me without storyboards, so just putting that as a caveat.
I'm trying to build my own app now, and I'm trying to push a new viewController onto the main navigation controller. This works fine, but when I go to the new viewController, it doesn't ever load what I put in the xib file. That is, I know it's going to the right place because I can change background color, etc., in code, but I've put some elements in the xib and they're not showing up. I saw this discussion: Load ViewController Swift - Black Screen and did what it said, but it's still not helping.
Here's my push code:
var viewController = CreateViewController(nibName: "CreateViewController", bundle: nil)
self.navigationController?.pushViewController(viewController, animated: true)
What am I doing wrong?
Alternately, and this is probably a better question — I haven't gotten that far yet. Should I just try to learn storyboards? It's not that complicated of an app and everyone seems to say storyboards are better...

Related

Permanently hide an item on Interface Builder via code

I have a weird question. Wasn't able to find a solution via search neither in SO nor via google.
I have a UIView in my UIViewController which is lead by a storyboard.
This UIView is set, via Interface Builder, to hidden.
Based on certain logics at some point i need to reveal this UIView.
Pretty easy: myView.isHidden = false
problem is that each time my UIViewController loads, it overrides whatever has happened before -such as un-hiding the view- and set the view to hidden again.
Is there a smart way to permanently hide or should I go for UserDefaults storing the value and loading it in ViewWillAppear each time?
Thanks for any possible suggestion.
note: I'm coding in Swift3 syntax
*******************EDIT*******************
To make it more clear:
I'm have a bunch of custom pop-ups which sits on a dedicated storyboard file. Each of the pop-ups has a UIViewController.
These popups are basically achievements popups. They have 3 stars, all of them hidden by default (via IB properties on the 3 UIImageView that they holds).
Along the app, if the user reach a certain kind of achievement, I'll be calling the related UIViewController from that storyboard file and showing (un-hiding) the related achieved star. Just like that.
Main VC:
let viewController = UIStoryboard(name: "AchievementsPopUp", bundle: nil).instantiateViewController(withIdentifier: "Category1PopUp")
viewController.modalPresentationStyle = .overCurrentContext
self.present(viewController, animated: true, completion: nil)
On the related class file, I'm un-hiding via code the star and presenting to the user. Once the user dismiss the popupVC going back to the main one, the "un-hide" property is lost for that UIImageView.
I've solved using a property on UserDefaults which works pretty well.
The problem is that I had to create 15 different properties (5 screens with 3 stars each) and manage the related code which turned to be a little messy :-)
If there are smarter solutions I'll be happy to implement!
You should take a look at Apple's documentation for Preserving and Restoring State.
The preservation and restoration process is mostly automatic, but you need to tell iOS which parts of your app to preserve. The steps for preserving your app’s view controllers are as follows:
(Required) Assign restoration identifiers to the view controllers whose configuration you want to preserve; see Tagging View Controllers for Preservation.
(Required) Tell iOS how to create or locate new view controller objects at launch time; see Restoring View Controllers at Launch Time.
(Optional) For each view controller, store any specific configuration data needed to return that view controller to its original configuration; see Encoding and Decoding Your View Controller’s State.

Swift: Seeking advice on accomplishing specific flow between storyboards/viewcontrollers

So I am working on an app and am finally getting to a point where I am starting to build actual modules instead of playgrounds and utility apps for tests. So I really want to do this right since I am jumping into the real deal right now. I was hoping to get advice that will help me accomplish my goals for the apps "flow" without me hacking something together that will come back to bite me later.
So imagine I have a home screen(a single view controller) that can branch to multiple storyboards. The mechanism I want to trigger transitions is the user grabbing an image on the home screen with their finger, and flicking it off the screen. When the image is no longer on screen, I'd like to transition to a storyboard that corresponds to that image. For instance, the user might flick the "settings" image to open a settings panel.
[home storyboard] -- [user flicks image off screen] --> [alternate storyboard]
I have already accomplished this kind of, but with the way I am doing it now I am unsure how to be able to navigate back from the second storyboard back to the home storyboard. It also seems unclean and hacky to me.
Right now it is set up as such:
Home is its own storyboard - main.storyboard
Home contains one simple viewcontroller
Alt is another storyboard - alt.storyboard
Alt contains a navigationcontroller
How can I facilitate things such that Alt's navigation controller will recognize that it was just in the Home storyboard, so that it will provide a "back" button for navigating back home?
Or, if anyone has any advice as to how I might accomplish this in a neater way, I would greatly appreciate it. I want each "module" (ie alt.storyboard's contents) to be in different storyboards for organizational sake.
Here is the code I use to seque to my second storyboard:
if !(recognizer.view!.window == nil) {
print("object left window")
let viewController: UIViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("Alt"))! as UIViewController
self.presentViewController(viewController, animated: true, completion: nil)
}
Thanks so much for taking the time to check this out, let me know if I have not been clear enough.
you could put the main viewcontroller (from Home storyboard) itself into a navigation controller and simply push the initial viewcontroller from the storyboard you want to reach (in your example Alt storyboard) with a custom transition. so the viewcontrollers from all the other storyboards except of Home should not be embedded in a navigation controller!

Swift - Elements missing when programmatically instantiating a view controller

First of all, I'm brand new to swift and iOS dev! I've decided to get started with it, and so far so good. Except for today.
So I first created a single view app, following the tuto, then I decided to see what happens if a added another view. Using segue to navigate between views seemed to work fine, so I wanted to see how I could navigate programmatically, having in mind that the "destination view" may be conditional on more than just a user pressing a button. So I added a first view to become my initial view controller, and I've found the following code online to transition to my other view:
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("home")
self.presentViewController(nextViewController, animated:false, completion:nil)
There was no problem, no error or console message, except for one little problem: some UI elements of the "destination view" (nextViewController in my case) are missing when the view loads! And some of them (but not all) show up after I click on some other elements of the view.. Note that there was/is no problem if I set the nextViewController as the initial one.
I haven't been able to find any clue on the internet about that problem, and I would greatly appreciate it if someone could point me in the right direction..
Oh well, 5 more minutes and finally an error message were enough to fix that problem!
I've found my solution on the following thread:
whose view is not in the window hierarchy
As it's said, moving my code from the viewDidLoad method to the viewDidAppear one fixed the issue. And I had the same error as the OP mentioned.

Which is the preferred way of doing tutorial page with UIPageViewController in swift for first time entering App only

I am relatively new to IOS interface design, and currently facing this problem:
I am having an app wanted to have a tutorial (UIPageViewController) ahead of the navigationcontroller, which will be the main controller on storyboard that the app will enter with.
Now, what I want to achieve is let the app run my Tutorial Pages ahead for first time of app running, then enter the NavigationController. If it is not the first time, user will go to NavigationController directly.
After some research, I found out there are at least two ways of doing it:
Programming the UIPageViewController totally on code, then in Appdelegate, having an if-else loop to do this.
Insert the UIPageViewController into the storyboard and do it.
So far those are two ways I can find out. For second however, I can't find an optimal way to handle "skipping the tutorial page completely". Or probably there is a better way of doing this. I want the app to be more optimal, and wondering what is the usual way of doing it for an IOS professional's choice.
Thank you!
(p.s. If the question is a repeated one or not clear, please leave me comments. Thanks again! It is possible bonus for if can show some links for github demo.)
The way I normally do this sort of thing is as follows:
Put the tutorial content in a separate storyboard.
In the initial view controller of the main storyboard, check a
dedicated variable in the NSUserDefaults to see if user has ever run
the app before.
If not, then programmatically load up the initial view controller of
the tutorial storyboard and present it.
This way, the main storyboard isn't loaded up with a bunch of view controllers that are only used once, and there is minimal code to write for the transition.
-- EDIT --
Below is a Swift version of the answer to this question: How can I load storyboard programmatically from class?
let storyboard = UIStoryboard(name: "Tutorial", bundle: nil)
let viewController = storyboard.instantiateInitialViewController()
presentViewController(viewController, animated: true, completion: nil)
this link has sample project for that but it is written in Objective-C.
https://github.com/MatthewYork/MYBlurIntroductionView

handle view controller of storyboard in AppDelegate class

I have a problem again. I work with storyboard in Xcode 6 with Swift as programming language. Before I want to present a view (with a view controller) on starting my app I want to test the internet connection and my server connection. If both connections are available I want to present a view1 and if not I want to present a view2. But I don't want to show a view with a spinner while checking the connection. So I thought I can manage it over the AppDelegate class. In the function func application() I want to decide which view (view1 or view2) is loaded at first. But for this solution I have to instantiate two view controllers that are connected to my two views in storyboard. I don't know if it is possible.
So my question, is it possible to instantiate these two specific storyboard view controllers in my AppDelegate class? And if it is possible, how can I do this by code?
If it is not possible, how can I solve my problem? At the moment I always show a view controller with a spinner (view0) and if connection is available I go to view1 and if connection is not available I go to view2 from my view0 controller like this:
override func viewDidAppear(animated: Bool) {
//some code
self.presentViewController(view1, animated: true, completion: nil)
//some other code
}
You can load a specific view controller from a storyboard with this call:
let viewController = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("SomethingViewController") as UIViewController
self.window?.rootViewController = viewController
But to be honest, it doesn't seem good to make the user wait with no information while you do the connection tests.
It would be better to show a temporary view controller during the waiting, unless those tests are really fast :)
Edit: corrected the code.
It's a hackish solution, as it will load a new rootViewController after initializing the original one I suppose. But it should work.
A more correct alternative would be creating the project as "empty application" and loading the storyboard by code, directly in the controller you want.

Resources