Swift: Load .xib from storyboard, views not loaded - ios

I'm trying to load a ViewController (a custom UIViewController subclass) from an .xib in Swift via the storyboard (I created a ViewController instance in the storyboard and deleted its view).
The ViewController itself loads, but nothing in the .xib loads with it.
In other words, my .xib looks like this:
ShapeView is a custom UIView subclass.
But if I look at the view which is actually loaded:
override func awakeFromNib() {
log.info("view \(self.view)")
}
self.view is just a generic UIView -- it's not my ShapeView.
If I try creating an #IBOutlet and connecting my ShapeView to it, the same thing happens -- the property bound to the outlet is nil:
If I use Obj-C for my ViewController class keeping everything else the same (the .xib and storyboard), it works as expected.
How do I set up and/or load the .xib in Swift via the storyboard to get the correct behavior?

Related

ViewController's subview's IBOutlets nil in viewDidLoad from Storyboard

I have a UIViewController that gets instantiated from a Storyboard.
In this view controller lays a MyView that is actually just a UIView from a Xib file.
In the view controller, I set my view as being a class of MyView and link it to an IBOutlet in my view controller class.
MyView contains a UILabel.
When in the view controller, in viewDidLoad I try to set myView.myLabel.text = "test" I get a fatal error: unexpectedly found nil while unwrapping an Optional value, myLabel is nil.
Can't figure out what's wrong.
Even in awakeFromNib() and in required init?(coder) my outlet is nil.
Any idea why and how to fix it?
Double check to make sure your link between storyboard and code is ok. I had this once when broke the connection and all I had to do was reconnect it.
See if you are using CustomViewClass in xib i would like to tell you first declare property as #IBOutlet var viewObject: CustomViewClass! in your Vc.swift & then give outlet opposite in storyboard & then inner subviews outlet declare in the CustomViewClass.swift
Now you are feel free to access in the your Vc.swift that innersubviews outlets of your CustomViewClass like
viewObject.myLabel.text = "test"
Don't forget to give Custom Class from identity inspector for file's owner Vc & your view CustomViewClass
Still if you have any doubt feel free to ask in comment.

IBAction From UIView's File Owner Not Working in UIViewController

I have a ViewController that loads a subview which is a UIView in a xib file. I connected the File's Owner to ViewController by adding the ViewController class as the File's Owner to the UIView xib in interface builder. Then I cmd + dragged from the UIView to the ViewController and created an IBAction.
I double checked everything by checking the Received Actions of File's Owner in IB of the UIView. It shows that the button is connected to the function of the in my ViewController. When clicking the button nothing happens. I am unsure why this is. Any help is appreciated.
I created another project doing the same steps and that works perfectly fine.
Add deinit to your view controller and set a breakpoint, or print something out within deinit, and I'm pretty sure you'll find your controller has been deallocated, at which point your wired-up #IBActions aren't hittable.
Add to your ViewController...
deinit {
debugPrint("deinit hit")
}
Without your code...
I'm assuming you're showing the ViewControllers.view but not retaining a reference to the ViewController via a variable.
If you're not pushing the ViewController onto a navigation or tab bar controller's viewController stack, or managing pushes and shows via segues, you'd need to persist a reference to the actual ViewController instance somewhere in the form of a variable.

Load xib from Cocoapod in Storyboard

I have a storyboard where I want to embed a viewcontroller in a containerview. The ViewController and its xib are in a cocoapod I made. Is it possible to embed a viewcontroller and its xib from a cocoapod in a storyboard containerview?
I know that if you delete the viewcontroller's view (in the storyboard) then the storyboard will try to load the xib with the same name as the viewcontroller. However, this isn't working. The app crashes when the viewcontroller's outlets aren't linked up. I can only assume it's because the xib is in my cocoapod.
I've checked that the names match and all the appropriate custom types are set in IB (like changing File's Owner from UIViewController to MyCustomViewController). I added the xib to "resource_bundles" in the podspec too.

UIViewController inside XIB?

Currently I'm struggling with creating a subclass of UIViewController or UINavigationController with XIB file as a view.
When I create everything from the Xcode's menu (New File -> Class -> With Nib... etc.) I get a XIB but only with a plain UIView but I want UIViewController instead.
I read somewhere that XIBs are only for a views and you have to handle controller in code, is it true? Because as you can read here it's possible to insert Navigation Controller component into XIB. But I have one problem with the code from this tutorial - I get empty view with empty UINavigationBar. When I do the same with regular View Controller I get info abut this controller being used more than once...
I'm not trying to force Interface Builder to do something unusual but I want to know if this is possible (it would be easier and nicer to modify view controller component insted of a content view)? And if it is, how to achieve this?
I have just checked to confirm whether it is possible and to my surprise it is! You can have UIViewControllers inside Xibs
The test was done in XCode 10.1, Swift 4.2.
I have never used it before, but i thought since it gives you the option from the item library to pick view controllers, it has to be possible. I have added one to my xib, and just like in the storyboards, i have linked it with class, set IBOutlets and IBActions and it all worked perfectly fine.
The key thing is to instantiate it like this:
// Method inside the `UIViewController` you want to present our view controller from xib
// The xib file is `XibViewController.xib` and it has only one item inside - `UIViewController` with custom class set to `XibViewController`
guard let xibViewController = UINib(nibName: "XibViewController", bundle: nil).instantiate(withOwner: self, options: nil).first as? XibViewController else { return }
present(xibViewController, animated: true)
here you can find my test project: https://github.com/stoqn4opm/XibViewController
An XIB file is used for building content that is viewable on a screen. A UIViewController is not viewable. It instead owns a view (which is viewable) created from an XIB or from code.
I think from what you are trying to do is use a storyboard which lets you visually layout your UIViewControllers to define there segue from each other (in your case in a Navigation Controller) which means show the next UIViewControllers view and put it in the UIViewController hierarchy.

Cannot create outlet connections to subviews in Interface Builder (Xcode 5)

I know this appears to be a duplicate of some other questions, but the answers are not working for me.
I have created a single view app.
In the storyboard I added a subview to my main view.
I have a label on my main view and another label on my subview.
I have created a class of type UIView and added it as the custom class for the subview.
I can ctrl-drag my label on my main view to the main view controller class. But when I try to ctrl-drag my label on my subview to my custom class, I cannot get the connection to occur.
I have even typed the property information and tried to make the connection manually to no avail.
Things have changed a bit in the latest version of Xcode's Interface Builder. Can somebody tell me what I am missing? There is literally no code here. I am just testing trying to connect outlets to a subview with a custom class.
The first image shows that I have set up the custom class and added a property but I cannot make the connection.
The second image shows the main view label is connected in the main view's controller.
The third image shows that there are no outlet connections for the subview's label.
You can manually write the IBOutlet property declaration in the #interface of the custom view subclass, and assuming you've defined the base class of your subview in IB, then you can drag from the outlet circle in the code back to the control in the scene.
Or, as you point out, Warren Burton suggested both this technique and another in his answer to this other question, Can't Wire to Subview in IB.
The issue has to do with the File Owner of the View Controller. It is probably set up as being IOViewController, thus you can only make property connections in that .h file.
What you can do, is create another .nib file for the subview and put the subview in there. Then in that .nib file, make the file owner IOSubview. Property connections will work just fine there. Then just add the subview to your IOViewController programatically. Just remember to load the nib file from bundle first.
This is what I did (in Swift):
I Created a new ViewController (e.g. class MyViewController: UIViewController {})
In StoryBoard, I expanded the 'Scenes' (i.e. the tree view of all UI components) and selected 'MyViewController'
Using the 'identity inspector' I assigned the 'MyViewController' class (as oppose to the default UIViewController)
After that I was able to assign an action.
I suspect that for Obj-C it is similar process.
You don't create outlets in the subclass, you create the outlet on the view controller it is on. You need to #import the subclass into IDViewController.h and create an outlet there.
IDViewController.h
#import "IDSubclass.h"
...
#property (strong, nonatomic) IBOutlet IDSubclass *outletName;
Zoom your storyboard to 100%. If you zoom out, to say 50%, then the outlet connection won't work.

Resources