View Controller Loads Twice - How Do I Fix It? - ios

The Problem Cause
When I added a new Swift class file to my iOS project, I decided I was indecisive and renamed it, deleted it, and created a new file. I think that I was actually so indecisive that I renamed it a few times.
The Problem
Now that viewController loads twice. I can literally see the transition happen twice and, during testing, I can see my viewDidLoad run twice in my console.
Common Fix
I know the first solution to check for is duplicate segues / segue calls. Check your document outline to see if there's more than one segue. In my case, it is definitely not a segue problem in the storyboard or the viewController.
My Uncommon Situation
I found someone who had the same load-twice problem and it was because of the rename:
They said it was the renaming I did that is at the root of my problem and it is not easy to fix because the duplication is now in my XML file. But where is this XML file and how do I edit it to erase the original instance of the class? I have no idea.
So how do I solve this loads-twice issue? I just want my viewController to have a normal segue!

Resolved my issue!
If you messed around with a class's name (or it's file name) and have the same "loads twice" issue that I was having, you might be having a hard time solving it. The only suggested solutions I found said to create a new project from scratch and copy stuff over. BUT, instead...
Here's the simplest solution ever:
Rename the class of the viewController that's loading twice! Don't worry about the file, but the view controller class within it. Your XML file probably has duplicates of the original class name, but rename your class to something entirely new and you should be okay.

Delete Segue and declare it the right way.
I faced the same problem. The reason was I ctrl dragged from the TableViewCell to target ViewController.
So I deleted the segue simply by clicking on it and pressing the delete key on my keyboard.
Then ctrl dragged from the ViewContoller of the first view to the second ViewController.
The wrong way to declare Segue
The Right way to declare Segue

It happened to me also. My case was for Creating a segue from my UIButton and performing it from source code.
If it matches to your case then just create the segue direct from the ViewController to your desired ViewController.
The perform the segue. It works.

I recently created the same problem where my view was loading twice. I have a tabbed app. The view controllers for each tab uses a Content View with a segue. For some reason I had set the Custom Class for the View Controller and the Content View Controller to the same custom class.
I don't know how both got set, probably something I did and forgot. If you are seeing a view controller load twice and the above answers didn't help, check to see if you have the parent view and the content view using the same custom class.

Related

IOS/Storboard: Is it Safe to Copy and Paste View Controller within One Storyboard with Autolayout

I have a view controller in storyboard with a lot of elements and autlayout constraints that also has segues from another VC and I need to make a similar VC.
Is it safe to copy and paste a VC to create a duplicate? I would cut and past from the navigator pane, not the actual storyboard.
The VC in question is wired to a class. The cloned VC will get its own class and I don't mind deleting the connections. I just don't want to mess up storyboard.
When I was first experimenting with Storyboard, I tried this a couple times and it seemed to corrupt early projects so I'm wary. Are there any safeguards that should be taken first?
Thanks in advance for any guidance or suggestions.
It's totally feasible to copy ViewController. Actually instead of copying VC, you are copying and paste scene.
In the following , I paster a bunch of tableviewController scene from the top scene.
After copy/paste, the new scenes are completely independent of each other even with the original tableviewController scene.
If you need to change to other customized vc, just change the name here. Now the new scene is configured to your own new vc class and again has nothing to do with the original vc.
One thing needs to remember: if your original vc has storyboard identifier, you may need to change after copy/paste.
If you have too many identifies, you may consider to paste the scene to another storyboard. Then you can use an reference storyboard to help you connect.
Short answer is YES from the navigator pane or the canvas and Autolayout constraints will be preserved in your cloned VC.
When you select your cloned VC in Interface Builder, you can edit it's custom class in the Identity inspector.
If your cloned VC as a different class, you should definitely clean up the outlet connections and the IBActions.

How can I link an outlet from a view controller to an other?

I am working on an app that uses parse so I used the "starter project" as a base and worked from there.
The issue I am facing is that the ViewController is controlling the login screen a well as others such as the tableView and mapView witch I added later.
As this is the case if it would be possible I would link the map outlet by simply dragging from the code to the map but obviously this is not possible, How could I solve this problem (I understand I may be looking at the problem the wrong way but any help would be appreciated)
here is the code with the map outlet
here is what the layout looks like
The MVC model, Model-View-Controller model, isn't intended to have an action in one view touch the controller of another view. In InterfaceBuilder, you should only ever be able to attach actions to the controller for that specific view.
In general, if you set the file owner to ViewController, then you can only link IBoutlets to that view controller not make to another one.
your map is available in your MapViewController not ViewController, so you need to give the reference/IBoutlet of map need to assign the MapViewController, if you want to implement in ViewController, you need to create new one map
No you have to create different file for each controller.
you cant add outlet of all in one controller

UIWebView IBOutlet Connection issue

So I'm going to try to explain my issue as best I can.
I have 2 View Controllers on a Storyboard. One is the "main" VC and the second is a "EULA" VC.
The main view controller has a UIWebView which loads the primary UI and works fine. This controller uses code to perform a Modal segue to the EULA VC which is created in the interface builder. This also works fine.
Now here lies my problem. The EULA view controller also has a UIWebView on it but I can't seem to connect this view controller to any connection by means of CTRL + drag. The "main" UIWebView is connected to ViewController.h
This is how I create my connection with CTRL + drag:
My question is why am I able to connect the first UIWebView on the Main view controller but not the other UIWebView on the EULA view controller? What am I missing?
Have you set up the EULAViewController.h as the custom class for the ViewController in Interface builder? Select the UIViewContoller in Interface Builder and in the third tab make sure the class is correct. Here is a screenshot explaining what I am saying:
Also make sure you have selected the correct file in the right pane, both red boxes should show the name of your custom UIViewController subclass:
I am think this is a bug in XCode or what. But this is very rare issue. I also got this issue sometime. So posting a solution which can make you little nervous to implement. But it works for me sometimes. You can try it . -
Just create a new UIViewController subclass in your project and name it something slightly different than the first. Then, copy/paste all code from old non-working UIViewController into the new UIViewController subclass (.h and .m) and change all relevant symbols according to the new UIViewController subclass name. After doing this I found everything worked as normal in terms of trying to control-drag wiring the buttons.
Happy coding. :)
Recreating the class files, renaming the view to something else then back to EULAViewController AND following these steps I was able to fix the issue.
Close the project you are working on with.
Delete the【DerivedData】folder of you project. (This folder may
inside your project's folder, or inside
~/Library/Developer/XCode/DerivedData/(your project)/ ) or somewhere
else that were setup by you.
restart you project.

Two UITabBarControllers sharing one ViewController (as tab content)?

Situation: two UITabBarController's, each with their own tabs, but last tab in both is identical so want one UIViewController to show content.
Issue at runtime: Shared item only appears in one of the tab sets when shown.
Question: anyone know a way to make this work?
Link to external graphic of storyboard setup: (sorry, don't have enough reputation to post images here!)
Storyboard graphic
An Xcode project with that storyboard:
XCode Project
Each tab content item has it's own UIViewController class. They contain no code except the line to make the back buttons work.
(Yes, I know this is odd. Real situation is an iPad app where tab controllers are shown in popovers; popovers are "property editors" where different objects have different properties, but all share a common set of properties... thus one tab for "unique" props, one shared tab content for the "common" props all objects have.)
I've found a couple ways around this to get the effect I want, but if this storyboard worked it would be a much easier solution.
-- Other info, somewhat unrelated to question --
Alternate solution I'm using: TabBarControllers only link to one VC as tab content. When that tab VC loads, I use code to (a) instantiate shared VC from storyboard by identifier, (b) add that new VC object to the TabBarController via [tabController setViewControllers:list animated:NO].
(Another possible solution I like even less: not using a TabBarController, and presenting content VC's with my own "tab" graphic drawn into them, each showing "myself" as selected. Yuk.)
So I have a working solution, I'm just curious as to why this doesn't work (just a known thing in iOS API, or some magical property setting that might render it functional?)
You can't put the same view controller instance into two tab controllers. The problem is that a view (UIView) instance can only have one parent view (superview). When you try to add the view controller to the 2nd tab, the view controller's view gets removed from its first parent (the first tab) and then added to the 2nd tab.
I stumbled upon your thread while running into the same issue today...
The solution is to just make a duplicate of the view controller in story board and attach the duplicate to the other tab bar controller.
I just did it and it works...
I think the 'rdelmar' is right about this... copy it and set it ..!!
I ran across this same issue today. I managed to come up with a workaround that seems to do the trick. The key is to add a layer of separation between the tabbar and the controller you want to reuse. From each tabbar, I created a relationship to a distinct UIViewController with a container view. Then you can do an 'embed' segue from the container to the controller you actually want to reuse as the tab view. It is not quite as clean as a direct connection (not sure why that is not supported) since you do have to create a controller class for each reuse case. It is still a better solution than the nightmare of having to duplicate the actual tab view ( as well as any additional views that connect to it) for every use.
Hope this helps. Let me know if anyone needs more details.

Xcode: "Scene is unreachable due to lack of entry points" but can't find it

Xcode 4.5.2 gives me the following warning:
Unsupported Configuration
Scene is unreachable due to lack of entry points and does not have an identifier
for runtime access via -instantiateViewControllerWithIdentifier:.
Unfortunately I can't identify the incriminated scene. Selecting the warning in the Issue Navigator doesn't highlight anything in the Storyboard. I have a fairly complicated storyboard (30+ scenes).
Any suggestions?
In your storyboard, select each of the view controller (red arrow in image below) and look at the Storyboard ID field (red oval). None of the Storyboard ID fields should be blank. When you find one that is, that is the culprit.
While this thread is old, I didn't see an answer describing what worked for me, so here goes...
I had this error and visual examination of the storyboard showed that all of the view controllers appeared to be connected to the root view controller.
I tried naming all 17 of the view controllers in the storyboard (as in #bobnoble's answer). I used a naming convention based on the long name of the view controller, e.g. "jvc" for "Jobs View Controller". When I tried to build, I got an error message pointing to one of the view controllers as having a duplicate name. Tracking things down, I found that I had an actual duplicate of a view controller stacked exactly on top of its twin. I suspect it was cut-and-paste damage from a user interface experiment that I didn't back out completely.
Anyway, deleting the unconnected twin solved my problem. After that, I removed all of the VC names as they're not referenced in the code.
I just had this exact error with a simple single-scene Storyboard, and all I had to do to fix it was check the "Is Initial View Controller" checkbox for the 1 view controller in the Storyboard. I suspect Xcode used to check this box for you by default in this situation, but no longer does.
                                     
Check the box for exactly one of the view controllers in your storyboard and you should be good.
I'm afraid you'll have to go through all 30 of them, and check whether they have a Storyboard ID or a segue to that view controller. One of the two is required, both is also an option.
This issue can happen in one the following scenarios:
Case I:
If none of the scene in the storyboard is marked as "isInitialViewController".
Fix:
Identify the root view controller and mark it as "isInitialViewController" in your SB.
In this case storyboard id is is not mandatory.
Case II
There can be situations where you do not need to have a initialViewController in a storyboard. For eg: when using Multiple storyboards.
Fix:
In such cases make sure the "storyboard id" is correctly given and you refer to the first scene to used in the storyboard using this id. For eg:
UIStoryboard *myStoryBoard = [UIStoryboard storyboardWithName:#"MyStoryBoardName" bundle:nil];
MyViewController *myViewController = (MyViewController *)[myStoryBoard instantiateViewControllerWithIdentifier:#"MyViewControllerId"];
In this case "storyboard id" is mandatory.
Case III
You have your initialViewController connected. But still you get this warning.
This is because some of the scenes in the storyboard may not be connected with a "segue" and also they do not have a "storyboard id".
Scan your storyboard, see if a "segue" is needed. Connect the segue if that is missing.
If a segue is not needed make sure you need to give a "storyboard id" since it is the only way to refer the scene from your code, as shown in the example code above.
Hope this helps
You don't need to set Storyboard ID for all scenes or UINavigationController
Well I have around 50-60 scenes and I just got these warning so that I realise that only the controller(Scene) or NavigationController which is not connected with segue needs to set Storyboard ID.
You can see that in above image UINavigationController is not connected with segue, it was a culprit of that warning.
Just give it a Storyboard ID to remove this warning.
I had the same issue. I've got lots of views on my storyboard with a nav and tab bar controller. For me it was just be a warning to let you know that some of the views are not connected.
Make sure all your views are connected in some way to the root view controller. I was starting this project from scratch to eliminate this warning and noticed the same warning when a view wasn't connected.
Simplest way to find the offending scene:
Go to the issue navigator (in the left panel, next to the search button), and double click the error. A window will popup containing the offending scene centered in the middle of the window.
(This is actually generally true - double clicking any error will generally result in a popup containing the error centered - a neat little trick!)
Side note: Sometimes, XCode will incorrectly give this error for a scene that is the root view controller of a navigation controller (that is the initial view controller). Simple fix is giving this root view controller a Storyboard ID, compiling (error should go away), and then removing the storyboardID (no error anymore).
The easiest way to see which controller, or scene, is causing this problem is by:
Ctrl-clicking your .storyboard in the Project Navigator and selecting Open As > Source Code. This will bring up the underlying XML of the Storyboard.
In this view, the warning will be clearly related to a line in the XML that relates to the offending scene.
Now, in my case, the warning was particularly annoying because the "offending scene" had an identifier and a segue! I was able to remedy the problem by deleting the scene and then undoing the deletion. Not elegant, but worked. I saved my Storyboard before doing this. In retrospect, I should have made a copy and diff'd the before-after.
For me, it wasn't because of a Storyboard ID or a Segue. I was receiving this warning because I had not set the View Controller's Custom Class.
Select the View Controller on the Storyboard, then in the Utilities Pane, select the Identity Inspector icon. Under Custom Class, see what value is inside of the Class field.
If it just says UIViewController, then you need to type in the class name. This will be the name of your .h and .m files that make up your custom UIViewController subclass.
I came to this question today. I'm using Xcode 6.3 and the answer to the OP's question is quite simple now:
Select the View Controller you wish to be the first one, show the Attributes Inspector, and under the View Controller section, make sure
Is Initial View Controller
is checked. Voilà!
With Xcode 7 this can be handled easily. There is no need to manually go through all the scenes to find a problematic one.
First go to the Report navigator, where you can get more detail info about known issues.
Issue description can look like this:
Base.lproj/Main.storyboard:fPh-fe-F5F: warning: Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:.
With this info, you can copy object id, in this case it was fPh-fe-F5F, and search workspace for the occurrence of this string. String will be found in Main.storyboard file. Double click on search result and it will be opened Main.storyboard with selected scene. Once you know a problematic scene you can easily fix the issue, by setting storyboard ID or setting "Is Initial View Controller"
You can just set an identifier. On the attribute inspector on the right pane, you'll find a field called "Identifier". Just put any string in there , this should work
You can click on the navigation controller and under the attributes inspector click the button "is initial view controller", and this should work too.
i faced same problem and solved with put on storyboard ID any identifier for all viewController and NavigationController also; the error will be removed immediately
enjoy!!!
Maybe this XQuery will help you to find those nasty scenes
for $i in .//scene/objects/*[1][not(#storyboardIdentifier) or #storyboardIdentifier= '']/#id (: find every scene that has an empty storyboardIdentifier :)
where count(.//segue[#destination= $i])= 0 and $i!= ./document/#initialViewController (: filter the results to the scenes that are not destinations of a segue and exclude the initialViewController :)
return ($i, $i/../#customClass) (: return the storyboard-id and the customClass, if any :)
If you have xqilla installed, you would save the query to a file and use it like
xqilla <xqueryfile> -i <path to your storyboard>
I don't know if this hasn't been mentioned yet or not but another reason you could get this warning is if you have a segue going in the wrong direction. For example, in my project I was getting this warning but all my controllers were in fact connected. However, one of them had a segue that basically was trying present the parent from the child instead of the parent presenting the child. This caused the same warning.
I got this warning when i am having a UIViewController in Storyboard to which nothing is set.
I avoided this warning by setting Storyboard ID to it.
I had the same issue,but i realized that i was using container view and instead of deleting default view controller i deleted its segue.So view controller remained in storyboard and so was the warning. So this is one of the case where warning pops up if default view controller of container view is not deleted properly when you don't need it.
I tried everything described above to no avail. I had everything connected properly in IB, with exactly one UIViewController designated the root view controller. I had no identifiers but added them to all of my controllers.
The only way I could get the warning to disappear was by doing everything above (including a computer reboot and a clean build) then switching to an error-free branch of my project in git and back again.
Unsure which action fixed it, or which combination of actions, but it wasn't the clean build on its own. This might be a byproduct of Main.storyboard always changing upon simply being opened, which means I have to git commit -m "Stupid storyboard" more often than I want to.
Here is what worked for me:
Open the storyboard in a text editor.
Change version from 3.0 to 2.0 save and close it.
Open it again in visual studio. It will automatically convert and open the document.
I got the same error : For me the error was I did not initiate a view controller in my story board.
Fixing that removed that warning.
Simply giving all MVCs a storyboard id worked for me.

Resources