IBAction From UIView's File Owner Not Working in UIViewController - ios

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.

Related

I can't connect the IBAction of UIButton into the ViewController class

When I try to link the UIButton object to the ViewController class in order the create an IBAction, Xcode doesn't show me the window for creating it.
I have to say that It only happens with the second ViewController of the NavigationController, because with the first one it works.
I believe it should be a Xcode bug...
The situation is the one below:
In order for CTRL-drag to work, the ViewController must be told which ViewController class to use.
Once that is done, you can use split view and Control-drag from the button to the code. Xcode will not let you Control-drag to the wrong file.
You cannot control-drag from a button on View Controller 1 to the class file for View Controller 2.
I'm not sure if I see it all in the right way, but you have code for one view controller, which is called ViewController. In this view controller you have an action method for the button via avanti and an action method for the button via indietro. However, the buttons are not in the same scene of your story board. You have the first scene with the button via avanti linked with the ViewController.swift file (Controller initial scene), but the second scene (Controller finale scene) is not linked to your the ViewController.swift file, which it shouldn't. You have to create a new view controller file for every scene in your storyboard and put the action methods in the view controller files that are linked with the appropriate scene. It is also preferable not to call your view controller swift files ViewController.swift, but give them a meaningful name.
Hope this helps.
Kind regards,
MacUserT
the thing you are trying to add is the self.view which is already added in UIViewController Class. try adding another control like button or another UIView

Can't set view outlet in xib

I have a xib file that includes a view controller but I have the same problem as this link: problem
In this answer they can easily set outlet because view has a circle that is clickable.But in my case the view outlet is not even clickable.So I can't set the outlet.What to do now?
The correct way to use initWithNibName:: is to have a "View" IB document where you have the desired VC view outlet as a root element. You need to set the "File's Owner" "Class" to your UIViewController subclass and connect it's view outlet:
Also, don't present modal VC from self at viewDidLoad: at the time of this method execution the VC is often not yet presented itself, viewDidAppear: is more fitting for such tests.
I had this same problem, but neither this nor any other solutions seemed to work - what I wound up doing was setting the custom class to UIViewController, linking the view as described in the question link, and then changing the class back to the actual custom class name I had intended. The link stayed and everything worked from that point on.

Present UIViewController from another UIViewController

I have a UIViewController named ViewControllerHome and when the user touches an image on the screen I would like to display a second view which is a Membership Card. I am doing the following from the touch of the image:
membershipCardViewController = [[MembershipCardViewController alloc] initWithNibName:#"MembershipCard" bundle:nil];
[self presentViewController:membershipCardViewController animated:YES completion:nil];
When the code executes an exception is thrown on the presentViewController line.
I have an .xib with a ViewController that contains a view and a UIImageView of the Membership Card. I set the class of the ViewController to my MembershipViewController.
Once that shows up I will dismiss it on a touch.
Can anyone tell me what I am missing? I thought I had all the steps correct to present the view controller.
Thanks for the help.
In the MembershipCardViewController's nib file, its view (what ever view it is controlling) is connected to the view controllers view outlet.
To do this control drag from files owner to the view you want to connect it to (the grey view in this case)
And you should get this:
Files owner should point to your MembershipCardViewController. Every view controller has a pointer to a view. I'm going to guess that you added some custom view after deleting the stock one. Control drag from files owner to that view to make the outlet. (If this outlet returns nil, an exception will be thrown).
To be safe, make sure file's owner (in the nib) is pointing to MembershipCardViewController
(This probably isn't the problem but it sounds like you may have started with an empty nib).
To do this, click on files owner, and select the identity inspector on the right. Make sure the class says MembershipCardViewController
I answered another question before about this Am I right in saying initWithNibName:bundle is used to manually load nib files and that initWithCoder would be used as an alternative?
This explains what is actually going on.
The purpose of your XIB is to archive the view of the controller. Having the controller class set is only part of the required information, you also need to connect any IBOutlet relationships between the controller and the views.
As standard any subclass of UIViewController provides an outlet called view. You need to ensure that it's connected. Otherwise when you load the XIB the view doesn't get set and you get an exception.
There are a number of ways to make the connection. Check this.
See also loaded-nib-but-the-view-outlet-was-not-set-new-to-interfacebuilder.

Reuse childs from custom UIVIewController using storyboard

I have a storyboard with a navigation controller that leads to an UIVIewController that I want to reuse. That UIVIewController has a ParentUIViewController that has all the basic functionalities for all the UIVIewControllers that I am reusing.
Currently I am copying and pasting (meh) and then I change the class of the UIViewController to the ChildUIVIewController that I want to use (ChildUIViewController extends ParentUIViewController).
But this sounds like a bad solution. Everytime I want to change the ParentViewController visually I need to update, manually, all other ChildViewControllers.
I have tried to create a xib for the ParentViewController but the xib isn't loaded because I need a xib with the name of the ChildViewController. I have created it and then said the class is the ParentViewController but it crashes in the segue.
EDIT
I have created an example of the status of my problem
https://github.com/tiagoalmeida/storyboardexample
Note that the ParentViewController has a set of logic way more complicated that is not illustrated there. Also note that I am also using a TableView. I hope that this can illustrate the problem.
Keep the logic on the parentViewController and the UI Part on the child UIViewControllers. If you need to create a new UIViewController, you will create a child that will have a corresponding XIB (or get rid of XIBs and create the interface by hand).
Have you considered looping back into the same UIViewController via a "phantom button"?
Have a look at this: UIStoryboard Power Drill, Batteries included
Essentially you can drag a Bar Button Item into the little black bar under the View Controller in Storyboard (the 1 with View Controller, First Responder, and Exit icons; sorry, I don't recall what this is called exactly), then you can control+drag from that button back into the UIViewController for a Push segue. This should create a loop segue in your Storyboard. All you need to do next is give that segue an identifier, programmatically call it from your code using [self performSegueWithIdentifier:], then implement -(void)prepareForSegue: and use [segue destinationViewController] to conditionally set the title and perhaps some flags so you can identify when to use different kinds of fetches (or other code variations) in the same Class code.

How to make a connection to UIContainerView

I have a standard extended UIViewController (called ParentViewController, or PVC), and want to have a container or child view which will be driven by ChildViewController or CVC.
I see that programmatically, that in PVC I can call addChild:CVC and manage calls such as didMoveToParentViewController, etc.... However, I am hoping that there is a way to do this with Interface Builder.
So I laid out an instance of PVC, then dragged a ContainerView onto PVC's view which creates a segue to a child window. In that window I assigned the class type of ChildViewController. This looks great so far, but how do I reference this programmatically from PVC? Let's try the usual: In PVC class extension, I have declared:
#property (nonatomic, strong) IBOutlet ChildViewController* cvc;
When I switch to IB, and highlight the PVC instance, and select the connections inspector, I see my cvc property but I cannot hook it up to my containerView instance (even though its class type is set appropriately). It allows me to drag (draw the line), but does not let me actually hook it up. Why??
I am thinking that this just isn't possible with IB, but perhaps I'm looking at this incorrectly?
I have read Apple's docs on child views and am prepared to do this programmatically if I can't get IB to do what I'm intending.
cvc is a child view controller of PVC, so you can get a reference to it with the childViewControllers property, which you would do in code rather than hooking up an outlet in IB. In PVC's viewDidLoad method, do this:
self.cvc = (ChildViewController *)self.childViewControllers[0];
Xcode will not allow you to hook up outlets between two different controllers, so even though cvc is embedded as a child view controller, it's still a different view controller.

Resources