ViewController linked to storyboard of a different project? - ios

I have a ViewController class that is a subclass of UIViewController in an old xcode project. I want to use that same ViewController class in a new project so I am copying the .h and .m files to folder of that project. However, when I look at the .h file, the IBOutlets are automatically linked to the storyboard of the old project. I don't see anything in the .h or .m files that is pointing to the storyboard file of the old project. Why is this happening? Am I doing something wrong?

The connections (the little circles on the left side of the editor) are made by the storyboard or xib files and not by the .h or .m files.
The easiest solution to break that connection would be to change the class name (NewViewController or something of that nature). If that creates too many problems you could change the names of all the connections which would also sever the connection.
Basically, just find a way of making the circles on the left side of the editor empty rather than full.

Related

Where do I detect where the outlet is from in Xcode?

I downloaded a project from GitHub and I'm experiencing some problems when detecting where a referencing outlet comes from.
This is an UIImage called "backgroundImage".
This is a UIViewController called "WalkthroughPageContentViewController".
"backgroundImages" has two outlets references, one of which is connected to the "WalkthroughPageContentViewController" UIViewController.
But there isn't any #IBOutlet connection here.
So where does the first referencing outlet come from?
I had a quick look at this project, and the answer is that the referencing outlet doesn't come from anywhere. It's broken. If you examine the destination, the you'll see that Xcode knows this is a problem:
And if you open up the WalkthroughPageContentViewController.swift file, and add an outlet called backgroundImage, then close and reopen the file, you'll find it's magically been linked back up to the Storyboard:
So, I'd surmise that at some point, there was an outlet in the file called backgroundImage, which was hooked up to the Storyboard, but then it was later deleted, leaving the project in this state.
This is pretty common when editing projects in Xcode. The Storyboard connections are basically just stored in XML in the .xib file, and there's no magic two-way connection between them and the code at design time, so if you delete the lines of code that they point to, you'll end up in this state.

Xcode 6: can't connect any IBOutlet to ViewController

After upgrading to Xcode 6, I opened an old project (that contains a subproject, so it has many targets)
and I noticed that no link from my Storyboard ViewContoller to the relative Objects works.
For example I have a ViewController with a TableView inside and now I cant do can't do anyhing with it because the connection is missing, I can't even redefine a new IBOutlet in the VC because the arrow in the storyboard from the VC won't connect to anything.
To be more clear:
The class is defined in the Custom Class section, so I can't find the problem
What should I do?
Btw I'm using obj-c not swift, I found some related answer but all about swift.
You can also see that the link between the parent view and the custom class is broken (not visible anymore) which is a huge problem.
I had the exact same issue with the app i'm working on actually, updating XCode from 5.xxx to 6.1. The workaround that worked for me was to remove the reference of every view controller and re-add them to the project...
To everyone facing that issue, here's the (annoying) trick :
Step 1 : select both .h and .m view controller files
Step 2 : remove the reference of those files
Step 3 : re-add the files to your project tree
Step 4 : open the storyboard, eventually re-build the project and smile
I can understand those things could be reaaally annoying, but it worked for me... Hope it will help someone else !
In your storyboard hierarchy select the View Controller,
In the right pane Custom Class section Class, select the drop down and your desired view controller.
I've experienced similar behaviour in Xcode 6.1.1 when trying to add the first outlet to a new view.
Tried removing the references and adding the files again as suggested above with no success.
What I did find worked was writing the first property on the new view by hand. I just popped in:
#property NSString *temp;
I could then attach my outlets in the normal way. Just delete the temporary property once you've added your first outlet.
Hope this helps.
It seems typing the outlet first (swift):
#IBOutlet weak var someViewOutlet: UIView!
and then dragging from IB the outlet to the far right type in the above code works.
Restarting Xcode resolves the issue (sometimes). Using Xcode 6.1
Maybe I can help
In my case the problem was that the viewController.swift file was not connected to the StoryBoard. The solution is to click in the Upper border of the view on the storyboard beside the 3 icons (View Controller, First Responder and Exit)...now look over in the Utility Area choose Identity Inspector, and in "Custom Class" choose the custom view controller.
Hope this helps. Xcode is hard!!
Here's the proper solution i believe.
If you renamed the controller in code, you need to update the .xib file.
I could not find a way to do it in the interface builder, so do this:
Open the .xib file with a text editor: right click the file > open as > source code
In the <objects> node find the <placeholder> node with the property placeholderIdentifier="IBFilesOwner" and replace the value in customClass="MyOldControllerName" with your new controller name: customClass="MyNewControllerName"
And all your IBOutlets will work as normal again.
Thanks to everyone who commented.
It is a bug of Xcode 6 / 6.0.1. Downloaded and installed the 6.1 version and the problem disappeared.
Maybe try to delete the outlet from the menu in the storyboard (in your screenshot) and drag it again of the element.
Okay, let's check iff it is the lack of a module name.
In your storyboard ViewController, type in the name of module. (the project name)
2.Clcick outside in another field. When you go back to the module field it may say none, but now there will be a dropdown menu entry for your project name.
Select your project name and see if everything is good.
If there are still issues I will post photos.
Seems to be a workspace issue. Try to remove project form a workspace and add it again. It helped in my case.
I had this, affected all projects on my machine, swift and objective c and drove me mad for ages. Finally also noticed that I could not use the refractor to rename classes either.
The fix for me was:
Close xcode
Delete ~/Library/Developer/Xcode/DerivedData (just doing this on its own did not work!!)
Delete all user data for all my projects using the following from the directory that contains all my projects e.g. /src (be careful with this command!):
find . -name 'xcuserdata' -exec rm -rf {} \;
If you want to do it by hand just do the following for all your projects
Delete .xcodeproj/project.xcworkspace/xcuserdata
Delete .xcodeproj/xcuserdata/.xcuserdatad
Get Spotlight to re-index the drive all my projects were on (not sure if this was required
Re-boot machine
Everything sprang back into life !
I was having this same issue.
It turns out I renamed my view controller class and file name. In storyboard, I had the stale value in the right pane, Custom Class -> Class. So the IBOutlets were not aligning because there were none in the missing class, which is where it was expecting to find the defined outlets.
Filling in the correct class name of the View Controller in the Custom Class field in the right pane fixed my issue.
XCode needs to be more verbose if you have a bad class name in the Custom Class fields.
no one solution fixed my same problem...
But i have solved by:
close xcode
renaming the folder of the project
open xcode
and then the outlets will be back again
I hope that this solution is the right one for the people who have the same problem
In Xcode 6.3 I needed to close Xcode and restart the Mac. Restarting Xcode alone didn't do it for me.
I've had 6.3 for a long time and my problem was with new projects I was creating to test some things. Definitely not an upgrade issue this time.
I have Xcode 6.3 and saw similar issue. Finally few edits in .h file resolved my issue. If your interface has IBOutlet defined as
#interface NavigationViewController :UIViewController
{
IBOutlet UILabel *lblName;
}
change this to and in .m file add #synthesize lblName;
#interface NavigationViewController :UIViewController
{
__weak UILabel *lblName;
}
#property (nonatomic, weak) IBOutlet UILabel *lblName;
I was having this same problem, with no view outlet available to link to. The only way I was able to fix it was to change the owner class of the XIB file to "UIViewController," make the link, and then change it back to my intended custom view controller class. The link stayed and all was well.

Can you have two implementations of a ViewController with the same name for differen targets?

(This is a simplified description of a very large project)
I have an XCode project that has two targets. The only difference between the two targets is there is a different implementation of a a viewcontroller for each target.
The view controller has a xib and is just a simple view with a UITextView inside. Let's call it TextReportViewController.
Implementation "A" has printing, so it has a button that allows you to print the contents of the UITextView. It is in a group called "A".
Implementation "B" has email, so it has a button that allows you to email the contents of the UITextView. It is in a group called "B".
Target "A" includes in its "compile sources" the .m file from group "A" and "Copy Bundle Resources" takes the xib from group "A".
Target "B" includes in its "compile sources" the .m file from group "B" and "Copy Bundle Resources" takes the xib from group "B".
I added "B" after "A", that is, before I decided I wanted another target things were working with "A".
When I edit "B" xib file and I examine the "file's owner" and in the identity inspector I click on the arrow for the custom class type it goes to "A's" .m file, not "B's" .m file.
When I look at the outlets for the file's owner it is a combination of the outlets from "A" and "B".
I added a control to "B's" xib and in the assistant editor I had the "B's" .h file shown and I drag a button to it to create an IBOutlet and it puts it in "A's" .h file instead.
What will I have to do to make sure target A is using A's .h file and xib file and target B is using B's .h file and xib file.
Note that when I added target "B" it made a folder called "B". So the files are located like this:
Root:
TextReport:
TextReportViewController.m
TextReportViewController.h
TextReportViewController.xib
B:
TextReport:
TextReportViewController.m
TextReportViewController.h
TextReportViewController.xib
Also when I am editing the "B" xib file and I show the assistant editor and select "automatic" to show the .h and .m files, it shows four, the two .h files and the two .m files.
I suspect you can't have this kind of setup. Even though each of your targets uses a different copy of your VC, you have to have both copies of the files with the same name in your Xcode project. This is when the confusion begins. When you specify the owner of a xib in IB, you provide the name of the class, but not the path to the file where it's defined. So you can't really know which of the two files is being used.
I'd suggest using different names for different targets.
This is a late answer, posting it for the record.
I ran into the same situation and searched for a solution. Since I found no way to tell Xcode Interface Builder to ignore other target files, I set up this workaround:
Say that in an iOS target, one have a class ViewController and want to make an MacOS version for a MacOS target storyboard while using part of its original implementation.
first make a category to host all common methods : ViewController+common and add mutual include to keep iOS target up and running
Then in MacOs target directory, create a ViewController_X class to implement target variant. This class imports the common category
Since the common category imports the original ViewController.h one need to create a stub version of ViewController.h on MacOS side. This stub file is a header only file like this:
#import "ViewController_X.h"
#compatibility_alias ViewController ViewController_X;
Now in the MacOS story board, use the ViewController_X classe and only see the relevant IBOutlets.
Also, any common files including ViewController.h will see the appropriate class for its target.

"loaded the "XXX" nib but the view outlet was not set." - again

Firstly I have inspected all of the other questions on this topic: the answers provided seem to be:
make sure you set the file's owner to your custom view controller class (which I have done)
make sure you have a referencing outlet from the view to the file's owner (which I have)
My code is compiled to a static library, and I export the .a file and xib file.
My example app that uses it includes the xib in its bundle ("copy bundle resources" in build phase)
In my library code I have a function in a separate UIViewContoller subclass to create the view controller from the nib:
- (void) presentCustomController
{
self.vCtrl = [[CustomController alloc] initWithNibName:#"CustomController" bundle:nil];
...
}
When I run the example app, I inspect the _view member of self.vCtrl, and it is 0x0000, and of course this is what causes the exception in the posting title.
My understanding was that the view to which that member points was 'auto generated' from the xib file, and it's children were the controls that I have put in it (buttons etc).
What part of my understanding has fallen down? Is the problem related to the fact that it is in a static library?
Thanks for any help.
If you are 100% that you connected your View to the File's Owner then I suggest you do the following:
Clean the project (cmd+shift+K) or Clean Build Folder if you prefer (cmd+shift+alt+K)
Quit Xcode
Restart Xcode
That should fix it hopefully.
Do you have multiple targets?
make sure you set the file's owner to your custom view controller class (which I have done)
I have come across a similar issue where I thought that I was setting the file's owner's custom class, however, IB was not actually setting it. Open the XIB as its raw xml and search for the custom class name.
For me it was because the .m of the view controller was not included for my specific target. To fix this check all the boxes in the target membership pane.

Storyboard uiviewcontroller, 'custom class' not showing in drop down

I have a UIViewController I created in my apps storyboard, as well as a custom UIViewController subclass which I added to the project (and is correctly in the compile phase for my target). However when I go to set the 'Custom Class' property on the view-controller in Storyboard my custom class does not show up on the list.
Checked that the class is part of my app's target, not tests'
Double checked that it is correctly a subclass of UIViewController
Compiled program just to make sure xcode was working with latest information
Restarted xcode
What would cause my class to not show up in the 'Custom Class' drop down?
Two ways I found that solve the problem but they are work arounds:-
Just type the view controllers name in the text field, or
close the project and then reopen it and in the project initialization it places the file on the list.
If you still have your problem or for those who could have the same problem:
Make sure to select on your storyboard your "ViewController" instead of your "View" (which is automatically selected when you click on the view in the storyboard). The difference between those two is that when the view controller is selected, a blue rectangle pop up around your app. To be sure to select the view controller, open the document outline and select it directly in your storyboard hierarchy.
I would try the following:
Check that the file implementing the class is part of the build phases (check under target > build phases)
Add the .m file to build phases (if it isn't already).
Restart Xcode.
You can fix this by editing the XML of your Storyboard.
Right-click your My.storyboard entry in the Project Navigator panel and select the Open As->SourceCode menu choice. Find your view controller entry in the XML, and add the attribute customClass="MyController".
Save the storyboard.
Right-click your My.storyboard entry in the Project Navigator panel again, and select the Open As->Interface Builder - Storyboard menu choice.
The custom class entry will now contain your MyController class name.
Make sure your class inherits from UIViewController.
#interface ClassName : UIViewController
In Xcode 8, a few of my classes had the wrong path (case sensitive) specified for their file locations.
MyProject/mysubdirectory/MyViewController.xib (.m, .h)
vs:
MyProject/MySubdirectory/MyViewController.xib (.m, .h)
Really not sure how it ended up in that state, but my project exhibited the exact same behavior as above (no outlets/actions displaying in IB), and fixing that path fixed the problem.
I fixed this two different ways. One way was by I opened the .pbxproj file and fixing the case sensitive issue manually. The other way that worked was by tapping the folder icon under the Identity and Type section of the File Inspector tab of the file, and re-selecting the file there.
Click on a different view controller in the storyboard, then click on it's custom class pulldown to confirm the new class is listed, but don't select it. Click back on the new view controller you made and you should see it now listed in its custom class pulldown menu. odd, eh? just forces a refresh I think.
I had been having the same issues as described in this problem. However, none of the suggested answers fixed it for me. My project compiled OK without warnings or errors, but, in the .h file there were no 'outlet' indicators to indicate that my outlets had been linked to storyboard elements.
Additionally, attempts to create new outlets in my code, by right-click and dragging into my header file, were not recognising my header source as a potential target for this operation. And furthermore, my Class did not make an appearance in the Custom-Class dropdown for the ViewController's property inspector panel.
And yet, the project compiled OK.
Closer examination showed that I had defined my own class in the following manner...
#interface KJBMainDataViewTrackConMk2<UIScrollViewDelegate> : UIViewController
which apparently compiles nicely.
But, if this is changed to the following, (moving the protocols to the end)...
#interface KJBMainDataViewTrackConMk2 : UIViewController<UIScrollViewDelegate>
Then everything springs to life. All outlets are suddenly indicated as being 'connected' with a storyboard element. And right-click dragging starts to work again, and my custom class appears in the custom-class drop-down in the property inspector panel for the storyboard ViewController!
Other answers here probably represent the most likely causes of this condition, but, I felt it worth mentioning at least this one other potential cause.
I had the same problem, but none of the other solutions worked for me. The issue for me was that I had a Mac and iOS target, both with their own versions of the same view controller. For example, I had a .h/.m pair of files named FooViewController for Mac and another .h/.m pair of files named FooViewController for iOS. Each pair was properly included with their respective targets, but for some reason Xcode does not like it and my view controller would not show up in the Custom Class dropdown in the view controller in the storyboard. I ended up renaming my class in the iOS view controller and it immediately showed up in the dropdown.
In my case, I drag a new TableViewController object to the storyboard, but I add a new file which's subclass is "UIViewController".... Then, I add a file which's subclass is "UITableViewController", problem solved!!
For those of you who are still having this problem after trying all the way around is probably because you clicked the View instead of ViewController.
You have to choose the file when ViewController is clicked.
This solved my problem.
I happened to come across this problem, and had no luck after trying the previous suggestions. Finally I found the reason is the header file's type is set to C++ header. After changing it to C header (like all the other header files), the class appears in the drop list. Don't know why though... Possibly helpful for others so I post it here.
Storyboard is looking for the custom class but physically its no there and its not displaying the custom class name in the list and also not displaying the outlets . Following solution perfectly worked for me.
Just copy your code some where else.(Lets say on desktop)
Open your existing code.
Delete the custom class file.(Move to trash)
Now add files from copied project folder (From desktop)
Don't forget to check "Copy if needed" check box
Open the story board and bingo you will get your custom class files in dropdown
be sure initially not adding the CustomViewController to any group or folder. place it in the root of your app.
none of the above(or below :) helped me. though I found that
after adding new viewcontroller to storyboard (just by dragging it in)
and adding my class by File\New\File\Objective-C Class, give it a name, no XIB, Next, Create
if I select my viewcontroller in storyboard and try to assign my class to it - my class is not there
BUT
if I click on a view that is in the viewcontroller itself then click on a class dropdown menu in Custom Class
AND THEN
select viewcontroller (click on a bar below the viewcontroller) and now again click on a class dropdown in Custom Class my newly added class magically shows up.
weird, must be a bug with refreshing. Xcode Version 5.1 (5B130a)
Make sure you select View Controller to which you want to attach your class. The easy way is open Document Outline and choose your view controller (When you tap on it form the Storyboard sometimes it simply doesn't choose the object you meant).
for my case, somehow bundle resources got deleted, so I added back and worked!
Build Phases -> Add Build Phase -> Copy Bundle Resources
find your file
Then drag and drop your file there
Then make sure your target membership is checked.
In my case, I selected the wrong UI.. so I deleted the class file and created a new one and selected the correct parent class
I had to restart XCode 7.3 (7D175)
What worked for me was, click on the file in the Project Navigator, then, in the File Inspector under "Identity and Type" beneath the "Location" dropdown box, click on the little folder icon and then select the file in the popup window.
Try to clean your project, and also restart your Mac. One peculiar thing that I did was change all the Custom Classes names and build the project again. It worked!
For macOS projects, creating a new class generated a class inheriting from NSObject instead on NSViewController.
Change from
import Cocoa
class AppsViewController: NSObject {
}
to
import Cocoa
class AppsViewController: NSViewController {
}
I was fairly frustrated with this issue as none of the answers above had solved my problem.
In my case: I was in the middle of working on swift view controller file and was making active changes (such as creating a custom collection cell class). I had not finished the code block and left it open like so :
class tableViewCell: UITableViewCell {
}
class collectionCell:
class viewController: UIViewController {
override func viewDidLoad(){
super.viewDidload()
}
}
Note the incomplete code block 'collectionCell2'
This was enough for xcode to not recognize my viewController file as such.
Once I completed this block the file reappeared in my xcode as an option.
Very silly and simple.
Make sure the view controller is matching with the same Type in the storyboard .
In my case swift file name was different then swift class name i.e
file name was ViewControllerTest.swift
and class name was ViewController.swift
after changing both to common name solved my problem
Restart Xcode after above changes
Make sure the class name of the ViewController is the name that you want. i.e.
class MyCustomNameViewController: UIViewController {
.
.
}
Changing just the filename is not enough.

Resources