How i chaining from two view on one nib file in ios - ios

I have one nib file and have two view on it, i want to know how cold i change view from one to the other.
thanks for help

Two methods you should be overly familiar with:
[parentView addSubview:childView];
[childView removeFromSuperview];
You should not just be thinking in views, which are arranged in a hierarchy, but also of view controllers, which have a different but vaguely related hierarchy of their own. Check out the View Controller Programming Guide
Also, the UIViewController Class Reference and UIView Class Reference are things you should be overly familiar with.

if you have two views on other view, and they lies under each other, you may use bringSubviewToFront method to show desired view.
you can also use hidden property of UIView object to show/hide custom view:
//method 1
[parentView bringSubviewToFront: myView1];
//method 2
myView1.hidden=YES;
myView2.hidden=NO;

Related

Accessing and manipulating parent view controllers views from a container view IOS

I am making an app where I have a container view that is half the screen of my view controller. From the container view controller's class I am trying to access and manipulate a view that sits out side of the container view. (picture below)
I am trying to access and add items to the scroll view from the container view class like so:
parent = (GFProfileViewController*)[self parentViewController];
UIScrollView *scroll = (UIScrollView *)[parent.view viewWithTag:222];
parent.titleHolders.contentSize = CGSizeMake(320 * 4,60);
UILabel *testLabel = [[UILabel alloc] init];
[testLabel setFrame:CGRectMake(0, 0, 100, 40)];
[testLabel setText:#"My Test label"];
[parent.titleHolders addSubview:testLabel];
scroll.backgroundColor = [UIColor blueColor];
how ever does not work. I tried even accessing the view from the parents "view with tag" method.
neither works.
I know the code is fine because when I move it to the parent vc all works as expected. I need to be able to manipulate the view from the container though. Can anyone help?
As nhgrif says, don't do that.
You should treat another view controller's views as private.
Again, as nhgrif says, create a public method in the parent view controller that takes the information needed and does the displaying itself.
If the view controllers are just being initialized then the parent view controller's view hierarchy may not exist yet. In that case you'd want to set properties to hold the value(s) you want to display, and then display them in your viewWillAppear method.
With storyboards and iOS >= 6, you can set up the child view controller using an embed segue, and then in your prepareForSegue method you can set the parent view controller up as the child view controller's delegate. That's a clean way to have the child communicate back to the parent. (I have a sample app on github that demonstrates this technique if you need a more detailed explanation.)
As far as programming ethics, correctness, good practices and whatnot, I think others have that covered. What you want to do surely isn't the clean way to go, but I often find myself going for such shortcuts, but you really need to know what you're doing, and if it isn't coming back to bite you later. The good thing is that it takes one line of code to achieve and has very low overhead. The problem is that such approach is highly dependent on the view structure, so if you change it, it will no longer work.
With that being said. What you tried doesn't work because the 'parentViewController' property isn't set on any arbitrary view. It should only be defined on the main view of the view controller, the one you can access from 'viewController.view'.
I will assume from your comment that your view structure is something like:
UIView
UIView
UIScrollView
Container
So basically starting from Container you need to go up one level and then down to UIScrollView like this:
UIScrollView = [((UIView*)[self.superview.subviews objectAtIndex:0]).subviews objectAtIndex:0];
I am unsure if you can search by tag from the upper view, since the one you're searching for is somewhere nested inside, farther than one level down. Assuming you can actually do that, this should also work and be more fail proof.
UIView *upperView = self;
while([upperView superview]){
upperView = [upperView superview];
}
UIScrollView *scroll = [upperView viewWithTag:222];

MVC with view built in code

I've been trying to interpret the lessons from CS193P, and have a few questions.
I'm building views in code, the way I do it is I have a UIView subclass where I put all the views in place in the init method. This class is initialized by the ViewController.
The question is then, what is the right approach from here - say i want to animate a button I placed at 0,0 to 100,100. I'd like to animate it from the ViewController, but i don't like the fact that i set the 0,0 position in the UIView class (in the initializer) and now i am setting a new position in the ViewController. I'd prefer there would be just one place knowing about the actual (x,y) positions of my views.
How am i supposed to go about this?
Move the positions in the initializer to the ViewController
Put a method in my UIView "-(void)AnimateToSecondPosition" where the actual "second position" is then up to the view?
Just let it go. It seems like this would be the right approach if i had placed the button in interface builder - i consider interface builder to be the view then...
Or maybe even a fourth option?
Please help me understand it better and not just give me the right answer ;)
I'd like to be able to compare my approach in some way to how you would do it using interface builder, so each of my views are public and accessable from the controller - this way i believe i could easily start using interface builder instead if i wanted, without changing the controller code, just hooking up the outlets.
I'm guessing the case would be the same for disabling, hiding and doing other things with the views.
Thanks in advance.
If you want to create a new View programmatically you should generally instantiate it in your View Controller using its designated initialiser:
UIView *testView = [[UIView alloc]initWithFrame:myFrame];
If you create a custom view it's totally fine and correct to put some configuration code in the init method, but it's your ViewController that should be in charge of deciding what to do with this view - it is his job! Using the MVC the View and the Model should never communicate directly (as you definitely learned in the first lesson of CS193P).
Therefore the same apply to the animations. You should animate the Views within your ViewController and not implement the animation in the View itself.
Therefore in my opinion you "second position" should be setup by the VC - if this has to be done when something happens to the view (e.g. someone pressing a UIButton) you should set a target/action to your VC and handle this within your VC.
ADDED:
Regarding building UIViews in the Interface Builder I don't know what you mean by "and let them go". Interface builder will create the views and add them to the specific superviews at runtime - as you can see in the example below you control the view hierarchy graphically on the left. For instance in this case there is a UIView (which I coloured green for clarity) and two buttons. One is a subview of the main view while the other is a subview of the green UIView.
Once your ViewController is loaded the view hierarchy is automatically loaded to self.view - in fact if you run the following code in your VC when it is loaded you will see the list of self.views subviews in your console.
for (UIView *view in self.view.subviews){
NSLog("%#", [view description]);
}
If you know already that you need to change some attributes of a specific UIView you setup via Interface Builder (e.g. we know we want to change programmatically the color of the green UIView in the example above) you should create an outlet which allows you to have a reference to that view in your code. You do it by crtl-drag from the storyboard to your ViewController code - see the example below.
When you have done that you can refer in code to this as any other property, with the difference that it has been created by Interface Builder.
Hope this helps.
You can add an -setButtonFrameToSecondPosition to the view subclass, which simply updates the frame of the button, and then call that from the view controller via one of the +[UIView animate:...] methods.

Add view to the windows?

Ususally we add a view to the window using
[self.window addSubview:self.rootViewController.view];
I am wondering how many subviews can be added to self.window?
Also, I think we don't use create a class for UIView, rather we will rely on viewcontroller to create view , is that right?
There isn't really a limit to the number of subviews, though you would usually only add one subview to the window and then add other subviews to that view.
You can create subclasses of UIView, indeed there are many subviews provided by UIKit. The important part is the distinction between the responsibility of the classes you create and use. Using MVC means you have a view controller which maintains all of the control logic and updates the view. You also have a (subclass of) UIView which hosts the visual representation of whatever content is in your data model.

How to add childview programmatically in iOS?

I have googled for many days but don't find out. I just know how to do by IB, but not by programmatic way. I think [addsubview:view] is just only add sibling view, not parent-childview. Thanks guy for reading.
It is easy:
//allocate a view (or take it from IB or from where you want)
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(10,10,100,100)];
//add the view on the actual view (or any other view)
[self.view addSubview:newView];
So this is a parent-child case and not a sibling view.
In fact by [newView superView] you get the parent view.
You might be getting confused by the difference between subviews and child view controllers, which are what's used when we have Container View Controllers that manage & display a number of child view controllers.
Take a look at the "Implementing a Container View Controller" section of Apple's UIViewController documentation, and you'll see how they describe how child view controllers work.
And, to answer your question specifically, here are the four methods that involve Child View Controllers (from the documentation):
Here are the essential methods you might need to call:
1) addChildViewController:
2) removeFromParentViewController
3) willMoveToParentViewController:
4) didMoveToParentViewController:
And, of course, if you're really talking about subviews, there are a bunch of other people excitedly providing all sorts of answers to your question along this front. Hopefully you'll have the correct answer for your problem really quick.
You can subclass a class to achieve this.
Example:
#interface MSCustomView:UIView
Here UIView is the parent class and MSCustomView is the child class
The [UIView addSubView:] function adds a view as a child view to the view you call it on i.e
[view1 addSubView:view2] will add view2 as a child to view1.
In the Apple docs:
http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/addSubview:
addsubview does just that. If you'll keep adding subviews to the same View you will basically create more siblings to that subview
From the iOS Developer Library:
Views can embed other views and create sophisticated visual
hierarchies. This creates a parent-child relationship between the view
being embedded (known as the subview) and the parent view doing the
embedding (known as the superview).
https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/UIView/UIView.html
AddSubview add a view into parent hierarchy . IOS provide insertSubview too for ad child view. This
http://developer.apple.com/library/ios/#Documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html
provide a better approach to understand about it.
You can add sub view by [parentview addSubView:childView] in the syntax both childView and parentview will be of UIView type.

iPhone tableview drop-down menu

I have a view controller with a table view in it and several buttons. I would like to add an additional tableview on top of the view like this (or at least what it would look like if anybody wanted to be my friend :-)):
I don't want to just add this as a subview (like here or here)enter link description here since I don't want to check which table view is being used in my tableview delegate and datasource methods. I would rather use a separate view controller.
I don't want to use a picker because I need to display a bit of info with the items in the list.
I have no problem creating the view with the corresponding controller, but how do I add it on top of the current view, just hiding portions of it?
Thanks!
Apple has a sample code of TableView which deals with this issue. https://developer.apple.com/library/ios/#samplecode/TableViewUpdates/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40010139
Above URL is the link to download the sample code from Apple developer library.
Hope it helps.
This might be overly simplistic for your application, but I have found it to be effective when I have had to do something similar.
You can add this 'drop down menu' view controller's view to the main UIWindow of the entire application. You can add a UIGestureRecognizer on the window as well. If the tap is outside of the view, make it fade away and remove it from the view hierarchy.
Initially I simply added logic in my tableview datasource and delegate methods to destingwish between the two tableviews (as suggested by Scott Bossak above. But I have since switched to building my two views in storyboard and adding their view controllers as usual. However, to present the second table view I instanciate it like so:
SecondTableViewContriller *secondTVC = [self.storyboard instanciateViewControllerWithIdentifier:#"secondTVC"];
then add it as a child view controller:
[self addChildViewController: secondVC];
[secondVC didMoveToParentViewController:self];
I then implemented a protocol to pass the information back to the parent view controller once a row has been selected.

Resources