I have one viewController and assigned a viewcontroller class in storyboard. I drag drop another UIView on the existing view controller. How to assign a different objective C or UIViewController class to that inner UIView?
As i understand your question is ,
you can assign new view to your viewController using
viewController.view=innerView
or if you want to add another viewController to current view you can use (Implementing UIViewController Contentment)
[self addChildViewController:newVC];
[newVC didMoveToParentViewController:self];
newVC.view.frame = CGRectMake(0,0,160,504);
[self.view addSubview:newVC.view];
Related
I am designing an iOS app with 10 main UIViewControllers in it. Each representing a different section of the app. Its basically for a company and shows info about the company.
One of the things I am doing on bottom section of the app (in all the different view controllers) is displaying a UIView which contains a map. This map shows a certain location.
Now it works, but the problem I have is that I have 10 copies of the same code and 10 copies of the same UIView.
Is there anyway I could make a small view controller with one class attached to it that would handle the map and then just create an instance of the view controller in all my 10 view controllers in my app?
I hope my question makes sense. Basically I want to know how I can go about reusing ONE UIView in all 10 of my ViewControllers. So I can just call it or something and it appears.
Update - this is basically what I am trying to achieve
Thanks, Dan.
View controllers can contain other view controllers. You can either use a container view in a storyboard or setup the relationship programmatically (see: Creating Custom Container View Controllers).
The storyboard container view is easiest, but the programmatic solution isn't too bad.
- (void)displayContentController:(UIViewController *)content
{
[self addChildViewController:content];
content.view.frame = [self frameForContentController];
// NOTE: You could also add it to any subview of self.view.
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
}
- (CGRect)frameForContentController
{
return CGRectMake(…);
}
- (void)viewDidLoad
{
…
MyMapViewController *mapViewController = …;
[self displayContentController:mapViewController];
…
}
- (void)dismissContentController:(UIViewController *)content
{
[content willMoveToParentViewController:nil];
[content.view removeFromSuperview];
[content removeFromParentViewController];
}
Final Note: Have each parent view create its own instance of the map view controller. Resist the temptation to reuse an instance of the map view controller between parents.
Update to address questions
So lets say I had 2 of the same view controllers open at once and they both were displaying the same imported viewcontroller then it wouldn't work right?
You can't do this. An instance of a view controller can only have 1 parent view controller. Create separate instances for each use.
So if I create different instances, I can reuse the same view lets say 5 times in one view?
Yes, if you create different instances, you can put as many as you need on a view.
Let me be clear, an instance is a distinct memory location created using a constructor.
MyMapViewController *mapViewController1 = [[MyMapViewController alloc] initWithNibName:#"MyMapViewController" bundle:nil];
MyMapViewController *mapViewController2 = [[MyMapViewController alloc] initWithNibName:#"MyMapViewController" bundle:nil];
or
MyMapViewController *mapViewController1 = [self.storyboard instantiateViewControllerWithIdentifier:#"MapViewController"];
MyMapViewController *mapViewController2 = [self.storyboard instantiateViewControllerWithIdentifier:#"MapViewController"];
Updated to demonstrate dismissing a container view controller.
Here is a method for a child view controller, so it can use to dismiss itself.
- (void)dismissFromParentViewController
{
[self willMoveToParentViewController:nil];
[self.view removeFromSuperview];
[self removeFromParentViewController];
}
Please try below method:
Create "map controller" super class with inherit to UIViewController and define your need common method and variables.
Inherit your 10 child class into "map controller" super class. And connect common IBOutlets and IBActions to super class.
You can access common methods and variable to super class from child class(10 view controller child class).
Please refer below code
#interface mapController : UIViewController
{
NSString *mapControllerVariables;
}
-(IBAction)mapControllerActions:(id)sender;
#end
#interface yourChileView : mapController
{
}
#end
I am developing an app in which a UIViewController (firstViewController) contains some UILabels, a UIButton, and a UIView (subView). The UIView should display the UIViewController (secondViewController) that contains some layers. I am unable to do this.
What should I do to display secondViewController within subView of firstViewController?
You should use UIViewController containment or parent/child view controllers. You can read details here.
The most basic version is:
UIViewController *parentVC = ...
UIViewController *otherVC = ... // it's view will be added as subview
[parentVC addChildViewController:otherVC];
[parentVC.containerView addSubview:otherVC.view]; // containerView is a view where your child view controller should go
[otherVC didMoveToParentViewController:parentVC];
If you only add other view controller's view as a subview, child view controller won't receive all the events. For example, if you use other methods suggested here (just add view as subview and nothing more), you won't get -viewDidAppear: message (and others) sent to your child view controller.
You can do that by adding view of another view controller as sub view in view as bellow
SecondVC *aObjSecondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondVC"];
[self.view addSubview:aObjSecondVC.view]
You can add it using the following line:
[self.subView addSubView:secondViewController.view];
I have a custom UIView which is a xib file and then a class that controls this view. I also have a storyboard which a lot of different view controllers inside. How do I perform a segue from the UIView to a specific UIViewController that is inside the storyboard?
Thanks
You can't do that. What you can do is give the UIViewController a storyboard ID, using the menu on the right of the interface builder.
Then call it programatically, like so:
MyCustomViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"MyViewController"];
[self.navigationController pushViewController:vc animated:YES];
You could put a ViewController into the Storyboard, set the class to your custom ViewController. Then, if you have class files for the view in the xib, set your custom view as the VC's view (already saves some code in loadView) and then just add a segue from the custom VC to the other view controller. To trigger that segue, you have to call [self performSegueWithIdentifier:#"identifierOfSegue"] in your custom ViewController.
I have created a special class of UIView that has certain properties, and I did so programmatically because it is usually blank but will at times contain other views. I know that if I create a UIView programmatically I can do something like [specialView addSubview: aView];
My problem is that there is a UIView that I created in storyboard and I need to add that UIView as a subview on my special view. I have connected it as a property in my ViewController but when I do the same code as above, nothing happens. Thoughts?
MyViewController *myViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MyScene"];
[specialView addSubview:myViewController.theViewToAdd];
And don't forget to give such an identifier to your scene (view controller) in Interface Builder.
Another solution is you can add the viewcontroller as a childviewcontroller.
func displayContentController(content: UIViewController) {
addChildViewController(content)
self.view.addSubview(content.view)
content.didMoveToParentViewController(self)
}
To remove :
func hideContentController(content: UIViewController) {
content.willMoveToParentViewController(nil)
content.view.removeFromSuperview()
content.removeFromParentViewController()
}
That UIViewController which houses the view you want may not be instantiated. So you would need to instantiate that controller and grab the view from there.
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).