How can I rewire a MainView-iPad.xib to the viewController? - ios

I am porting my Phone app to iPad.
I changed my target's "Devices" to Universal under "Summary".
I put the conditional (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad) to determine whether the app is running on iPad.
I created a new XIB dedicated for iPad and placed a view in there.
How can I rewire the IBOutlets back into the iPad version of the XIB?
Thanks

You probably need to define the class of the File's Owner:
Since you create a new XIB, it should be set to UIViewController, just select from the list your UIViewController's subclass.
The new image:
Just a small detail:
Avoid using this kind of stuff: (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad). It completely destroys your application architecture when creating a version for iPad and iPhone of the same application, which share the same code. Just sub-class the class you want. Keep the common code on the parent and the specifics in each sub-class.

select "Identity inspector" window on new Xib.
change class name to your viewController
then select file owner and your outlet automatically show up
there is the Controller class is same for both Xib

You don't need to rewrite any IBOutlets. But just assign the proper class to the xib's file owner and all the IBOutlets of that class is available to you and as you have used them in iPhone xib use them for iPad's xib.
Happy Coding :)

Related

How are .xib files being automatically associated and loaded with my ViewController?

I'm using Xcode 8 and Swift, not using Storyboards.
I hit Add->Cocoa Touch Class and check the box to generate a XIB.
I now have FooViewController.swift and FooViewController.xib. The xib has the class set under File Owner. As far as I can tell this is the only association between the XIB and the class. The generated class doesn't contain anything that loads a XIB.
I can create and display this view controller like so (from some other ViewController):
let foo = FooViewController();
self.navigationController!.pushViewController(foo, animated: true);
This works and it loads complete with the UI. What I don't understand is why. Most guides and tutorials online suggest that the ViewController needs to manually load a XIB.
What is happening in the default initializer for FooViewController?
Where is the XIB loading happening?
What if I want to override it and load the XIB myself? (e.g. maybe I want to use different XIBs for different devices. Not the best practice, I know, just an example.)
Back from the day in Xcode 4.5 when we used to create a Universal Application i.e.
for
iPhone
iPad
There used to be code in didFinishLaunchingWithOptions in AppDelegate Class to load different XIBs for target devices, so it did the same as you asked above. But given the evolution of Xcode and Cocoa Framework. It has come a long way from that where the compiler does a lot for us automatically.
Here in this specific scenario:
we have provided the file owner to XIB file, so when you are trying to present it, it goes ahead and searches in navigator/file available if a XIB is available for it, if it finds such a file, it loads the UINib from the bundle and loads it
if it doesn't it goes to the code to find if there is any
programatic view being created while we do super.viewDidLoad()
once it doesn't find anything, it generates a blank view for the same view controller.
If we look closely in the XIB file, there is a view outlet attached with main view available in the XIB but we have created no such outlet, so its connecting an autogenerated outlet for VC Source file with the view in XIB. If it makes sense.
Also please find some code below for reference from tableView Context:
let newAccountTableCellNib:UINib = UINib(nibName: "AccountTableCell", bundle: nil)
tableView.registerNib(self.newAccountTableCellNib, forCellReuseIdentifier: "AccountTableCell")
This should solve your query. Cheers!!

How do I associate a Storyboard UIViewController with my custom UIViewController class?

I'm running Xcode 7 beta 5 and I have a storyboard with a tab bar controller featuring 4 items. Each item is a UIViewController. I created a custom class that is a subclass of UIViewController.
When I go to the storyboard, click on one of the UIViewControllers, go to the Identity Inspector, click on custom class, and try to name my custom class it says,
"Launch screens may not set custom classnames"
Am I doing something wrong? I thought this was the way to associate a storyboard's UIViewController with your custom view controller.
The problem is that you are trying to assign a custom class to launch screen. Launch screens main function is to display a view until application loads (not to implement application logic). You should create a new view controller representing object in storyboard (this one should be displayed after application load) and assign a custom class to it.
As the error message says, custom classes are now forbidden in Launch Screens in Xcode 7. See e.g. here as well
If you are trying to customize your Splash Screen then you can create your first view controller as Splash Screen and then set a custom class there.
To tell the system that not to load launch screen just change the settings as mentioned below...
General Tab --> Launch Screen File --> Select "Main" (Basically it's Main Storyboard).
You can set a custom class to any storyboard component except the launchscreen.xib file.
This worked for me. I deleted LaunchScreen.storyboard and in main.storyboard I added the custom class which did not give any error later. Hope it helps someone else too.

How to distribute storyboard view?

I’m creating an open source plugin for a developer to use a custom screen in their Apple Watch Extension and want them to add it to their storyboard. How can I package it and instructing them to included in their application (storyboard)?
Maybe something like the include tag in Android (link).
You can only use one single Storyboard in an Apple Watch app, so if you have done UI in IB then you will have to copy the InterfaceController (You didn't make a UIViewController right?) that you made to their Storyboard.
If what you did was all programmatically generated, which i haven't tried yet, you can give them your .m and .h file and they can include it to their project, and then instantiate a new InterfaceController of that class.
You could create a separate xib file or just add your storyboard containing just the one view controller to the project. The implementers can then instantiate the view controller using instantiateViewControllerWithIdentifier.

IBOutlet to two viewControllers on two storyboards... is that possible

I have an app with two targets, for iPhone and for iPad.
This project is not using size classes.
On the iPhone version I have a storyboard that contains a viewController called “termsAndConditions”. This viewController has class files termsAndConditions.h and .m.
Inside termsAndConditions.m I have an outlet linked to a textView on the viewController.
Then I have the second target for iPad. I have the same viewController there called “termsAndConditions”. My idea was to use the same class files termsAndConditions.h and .m from the iPhone version with this other target. But there is a problem.
Remember that the outlet is pointing to the textView on the viewController of the iPhone storyboard? When I assign the iPad termsAndConditions viewController to use the same iphone class files, it apparently works, but when I try to access the textView on the iPad version nothing happens. On the other hand, when I pass the mouse over the outlet on the implementation, textViews on both viewControllers, on both storyboards, highlight.
Apparently the class file outlet is really linked to both textViews on different storyboards, but this appears to be fake.
Is there a way to do that or will I have to duplicate the termsAndConditions.h and .m with another name to use on the iPad storyboard? This appears to be a stupid solution.
thanks.
You may connect 1 object to your class per view controller. Double check that you set the classes correctly; I often accidentally autocomplete the incorrect class. Ex. TermsAndConditionsTableViewController instead of TermsAndConditionsViewController
This IBOutlet is connected to three different views and works correctly for me. Click on the dot to show the connections. Sometimes you need to make the connections again (rare but does happen).

How to connect iPad and iPhone UI XIB elements to same UIViewController

this may be a noob question, but I'm new to iOS programming and I didn't find an answer to my question elsewhere...
Following issue: I am programming a universal app for iPad and iPhone using IB and storyboards. The app is already set up correctly and I have an iPhone and iPad storyboard in my project and both are connected to the right (same) view controller as owner.
So far, so good...
My iPhone app is close to completion and I now want to add the iPad UI, which, apart from the layout and maybe some rearrangement of buttons and views to make use of the larger display, will have the same elements and functionality.
Now here's my problem: when I DragDrop my iPad UI element (e.g. a UILabel) to the view controller to connect it I (obviously) can't use the same name...because the iPhone one is already there.
If the item is called 'myTextField' on iPhone I'll have to call it e.g. 'myTextFieldiPad' for the iPad, which means I'll have to branch out every time I want to access the text field depending on the platform. Analogous for IBActions.
In a nutshell: same view controller, two practically identical XIB files for iPad and iPhone with identical UI elements, how?
Am I overlooking something?
Help to point me in the right direction would be highly appreciated...
Beschi
Don't create new properties using drag and drop.
You can connect controls from different xibs to the same property on your view controller using drag and drop, instead.
What I mean is, create your properties using drag & drop from iPhone's xib, and then connect your iPad xib controls to the SAME properties you created from your iPhone's xib.
Try create two classes which are children of your BaseViewController. First controller has name iPhoneViewController: BaseViewController, second - iPadViewController: BaseViewController. In IB for first (iPhone) xib you need connect first class. For second - second class. After that where you create viewcontroller you need check idiome. For iPhone create object of iPhoneViewController and for iPad - second.

Resources