I’m using xcode 7 , I’ve a storyboard controller with an UIContainerView
When I’m trying to create an outlet to the controller there is this error "Use of undeclared type UIContainerView"
it’s not a bug of xcode 7 because there is the same error on xcode 6
i need to create an outlet because when i switch the segmented control i have to programmatically change the embed of the container
It's an error or i mustn't create an outlet for a container? It's seems that there is not something called UIContainerView in the library, it's strange
There is no such class called UIContainerView. You need to create an outlet of UIView and connect that to your container view.
You can switch the content of container view like:
// Property
#property (nonatomic, weak) IBOutlet UIView *container;
#property (nonatomic, strong) UIViewController *first;
#property (nonatomic, strong) UIViewController *second;
// Method that removes first vc from view and shows second vc
// Assumes first and second properties already initialized
- (void)showSecondVC
{
// Removes first view controller
[self.first.view removeFromSuperview];
[self.first willMoveToParentViewController:nil];
[self.first removeFromParentViewController];
// Shows second view controller
[self addChildViewController:self.second];
[self.second didMoveToParentViewController:self];
self.second.view.frame = self.container.bounds;
[self.container addSubview:self.second.view];
}
It is confusing because IB lablels it as UIContainerView, but it's type is really just a UIView.
UIContainerView is not a class, so you are getting error. Instead use UIView. Container view is actually a concept in storyboard, that allow you to do similar programming stuff:
Initialise a second view controller
Add it as child view controller
Add its view at location of container view with same frame.
When you add a container view then all above stuff is done automatically.
If you want to switch to different view controller then you will create multiple container view. Show and hide container views based on UISegmentedController's selectedIndex
Related
I want to segue back from ViewControllerTwo to ViewControllerOne. I created a button that is responsible for doing that, but my problem is that the button is part of custom UIView class that is added to ViewControllerTwo, the button is not a part of the main view of ViewControllerTwo.
So in the custom UIView class I have the method that reacts if the button is clicked...
-(void)buttonClicked{
[SecondViewController performSegueWithIdentifier: "ShowFirstViewController" sender:nil];
}
When I do this I get an error: "performSegueWithIdentifier not a method of class" which makes sense.
So how can I segue between two viewcontrollers where the button responsible for the segue is not actually part of either view controller and is in a different class.
I think you can have a delegate call back to your SecondViewController and implement the performSegueWithIdentifier in the delegate callback method in SecondViewController.
It goes like this:
Above your custom UIView class interface create a protocol like this
#protocol CustomViewDelegate <NSObject>
- (void)buttonDidTap;
#end
Then create a property in your interface
#property (nonatomic, weak) id <CustomViewDelegate> delegate;
In your custom UIView *.m add this
-(void)buttonClicked{
[self.delegate buttonDidTap];
}
Conform the protocol to your SecondViewController like this
#interface SecondViewController: UIViewController <CustomViewDelegate>
set the delegate in your viewDidLoadMethod like this
-(void)viewDidLoad{
[super viewDidLoad];
self.yourCustomView.delegate = self;
}
implement this method inside the view controller .m file
- (void)buttonDidTap{
[self.performSegueWithIdentifier: "ShowFirstViewController" sender:self];
}
I'm more of a swift guy i think this should work fine.
iOS 9.3, Xcode 7.3, ARC enabled
This is what I'd do to troubleshoot:
Step 1: Make sure that you have a proper storyboard identifier for the view controllers you wish to segue between. The views simply attach to the view controllers, custom or not.
To do this, go to "*.storyboard" show the Utilities (right pane) and navigate to the Identity Inspector. Make sure you have "ShowFirstViewController" entered in the Storyboard ID field.
I am trying to use the .text of UITextField in my first view controller in another .text of UITextField in my second view controller, but my firstPage.firstTField.text turns out to be (null) in my second view controller even though I printed _firstTField.text in my first view controller and it printed out the input that was entered.
What may be the problem? Why is null?
FirstViewController.h
#property (weak, nonatomic) IBOutlet UITextField *firstTField;
SecondViewController.h
#property (weak, nonatomic) IBOutlet UITextField *secondTField;
SecondViewController.m
#import "FirstViewController.h"
- (void)viewDidLoad {
[super viewDidLoad];
FirstViewController *firstPage = [[FirstViewController alloc] init];
_secondTField.text = firstPage.firstTField.text;
}
You should treat a view controller's views as private. That's part of the appearance of the view controller, not it's function, and if objects outside of the view controller expect the views to look a certain way then when you change the appearance of the view controller's views it breaks other code. Bad.
In this situation it's worse. It just doesn't work, for the reason #nhgrif explains. You just created a new FirstViewController object, and it's views don't even exist yet. (A view controllers views are not created until the system is asked to display the view controller to the screen.)
You should create a property in your view controller that exposes the string(s) you need to read/write and use that instead.
However it's strange that you would create a new instance of a view controller and then immediately try to read text from one of it's fields. How can it possibly have useful data if the view controller was created on the line before? What are you expecting to happen?
I have aded a new View in my app, its just a .xib file
On button click i am calling this new view... AS
UIViewController *newView = [[UIViewController alloc] initWithNibName:#"Welcome" bundle: [NSBundle mainBundle]];
[self.view addSubview:newView.view];
It call successfully the new view.
I have set some labels and button newView that are shown on button click.
now the problem is this,
1- i have to send or pass some data to newView from main and also
2- when i connect a UILabel using CONTROL Drag in interface builder on selecting File's Owner Of newView with desired Label it gives me error on button click
'[<UIViewController 0x89d05b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Users.'
'User' is the UILabel type variable In my .h file that is declared as
#property(nonatomic ,retain) IBOutlet UILabel *Users;
any suggestion or help would be appriciated
You're creating a UIViewController instead of your custom UIViewController subclass. What you should be using is:
MyViewController* vc = [[MyViewController alloc] initWithNibFile:...]
Also note that if you're using child view controllers, you should be calling addChildViewController with the newly created view controller so that the UIViewController methods are properly propagated to the child view controller.
One last note, none of this will work reliably before iOS 5, as up to that point child view controllers were strongly advised against.
It also sounds like you're not using a subclass for the child view controller, if you add properties or actions, you have to use a subclass.
i have two UIViewController class with xib from interface builder, and i want create another UIViewController with xib that contains this two view, it's possible and how i can achieve this feature?
You can't add View controller A and B's views to view controller C in an XIB because there is a fair amount of housekeeping code you need to do to set up the parent/child view controller relationship.
However, if you were to use storyboards, and you are running in iOS 6 or later, this would be trivial. There is a new "container" view in iOS 6. You just add a container view to your scene, and then control-drag from the container view onto another view controller's scene, and IB sets up an embed segue that does all the housekeeping for you. In my view this feature alone is enough to justify moving to storyboards.
You add two UIView in your third UIViewController xib and you link these UIView with IBOulet.
#property (nonatomic, weak) IBOutlet UIView *firstView;
#property (nonatomic, weak) IBOutlet UIView *secondView;
After that you add your UIViewController in theses subviews in the viewDidLoad for example :
- (void)viewDidLoad
{
[super viewDidLoad];
MyFirstViewController *myFirstViewController = [[MyFirstViewController alloc] initWitNibName:#"MyFirstViewController"];
MySecondViewController *mySecondViewController = [[MySecondViewController alloc] initWitNibName:#"MySecondViewController"];
[self.firstView addSubview:myFirstViewController.view];
[self.secondView addSubview:mySecondViewController.view];
}
Improve it with #property of First and Second ViewController and Lazy loading.
I have a main view which has a UISlider on it.
From the main view I add a subview using:
gameView *myViewController = [[gameView alloc] initWithNibName:#"gameView" bundle:nil];
[self.view addSubview:myViewController.view];
The subview is created on top of the main view.
When I remove the sub view using:
[self.view removeFromSuperview];
the main view underneath becomes visible.
I want to be able to update the value of the UISlider on the main view, from the sub view, before I call [self.view removeFromSuperview]
Is it possible?
Basically the question can be generalized to how to update an IBOutlet on the main view from the sub view.
Help is greatly appreciated.
Many thanks!
Yes, it's possible.
And there's a few ways to do this. Here's how I would do it:
First, make your parent view controller's UISlider a property that can be accessed by other objects.
Secondly, give your gameView object an instance variable that you'll link to the parent view (let's call it id savedParent;)
Then, before you do removeFromSuperview, you can simply do something like:
ParentViewController * parentVC = (ParentViewController *) savedParent;
if(parentVC)
{
// some float value of whatever you want to set the slider value to
parentVC.slider.value = 0.5f;
}
Also, why are you instantiating a whole View Controller object (gameView) if you simply want to add a subview? When you do your removeFromSubview call, the view gets removed but your gameView view controller isn't released (and might even be getting lost & leaked in memory, leading to a crash). If you want to do a subview, subclass UIView. If you want to push a new view controller, push the whole controller (and not just the view it contains).
Here is another way:
I'm not sure what the slider is representing, but you need to create an object that represents this
#interface MyGameThing : NSObject
#property (assign) CGFloat myValue;
#end
#implementation MyGameThing {
CGFloat *_value;
}
#synthesize myValue = _myValue;
#end
You then need to pass that object to both of your view controllers (or make it a singleton).
Then, on ParentViewController, in the viewWillAppear, just set the slider to the new value.
Daniel.
(p.s. don't just add view controllers views to the superview, use presentModalViewController / dismissModalViewController or a navigation controller).