Currently have I implemented iAd and AdMob to each and every view controller in my Xcode project. I have about 6 view controllers and every time I switch back and forth between them one adbanner disappear and another appears. I want to make only one single adbanner for all view controllers. So even though its a transition between two view controllers, only one adbanner will be visible and it will not disappear and appear again.
But I also need to reach it from each class. So I can show it and hide it when I want to.
I would appreciate a ditailed step-by-step instruction.
INFO:
I am using storyboard. I am developing for iOS 6.0 and higher. I am using navigation controller.
So pass the banner view from one view controller to the next just as you'd pass any data. Install the view in the view hierarchy in each controller's -viewWillAppear method. You can pass the view between controllers in your -prepareForSegue method. If you're not sure how to pass objects between view controllers, search here -- here are many questions covering exactly that topic.
Related
I have a storyboard setup with the main view having a bunch of buttons and a container view and I would like for a different view to be loaded into that container view each time I press one of those buttons, kind of like a tab view controller works but without using one of those.
Also, later on I plan to have buttons inside those views that load other views replacing the views themselves.
Anyone can give me some hints?
Thanks
"Container View defines a region within a view controller's view subgraph that can include a child view controller. Create an embed segue from the container view to the child view controller in the storyboard."
You mentioned NSContainerView, so I assume you're trying to do this on macOS, not iOS. Here's a useful article and code project (for iOS 6, but I was able to set up switchable subviews in iOS 9 using this as a guide):
http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers
The important bits are using the embed segue, then wiring the view controllers together through a combination of viewDidLoad and prepareForSegue, and then finally loading one of the switchable view controllers (say one for each of your buttons) from the storyboard, where they are not connected to anything else.
I am new in developing iOS apps. I am trying to develop a multiple views app. My doubt is how to manage a multiple views app with View Controller, I mean, I do not want to use Navigation Controller nor Tab Controller.
My idea is to show a first View to choose the language, and after this, I want to show some different profiles in a table view. When you choose the profile, you get into a menu where you have some different functionalities (Once in this menu, I might use Navigation Controller).
My problem is that I don't know how to manage these two first views. I don't know if I have to declare them in the appDelegate, or if I can do it nesting one to other, I mean, I do the first view, and when I pressed the button, I declare the new view. Once in the new view, when I pressed a row in the table view, I make the another view.
I know it is a little bit confusing, so I hope you could understand it quite well.
EDIT:
I want to clarify that I am not using storyboards. My main doubt is what to do with all de view controllers, Do I have to declare all of them in the appDelegate? or Can I declare each view in every controller?
If you are using storyboards, you can use Segue's to navigate between the views, so you would show your first view, then you could tie a button to the next view (by control dragging in storyboard). If you want to transition programmatically you can use the performSegueWithIdentifier method. You could use the same approach to get from your tableViewController to your next viewController by using the performSegueWithIdentifier method from within the tableViewController's didSelectRowAtIndexPath delegate method (i.e. when a user taps a cell).
That should get you started. Good luck!
EDIT:
You really should be using storyboards. It's the way to do things these days. If you refuse, then the best approach is to create a container view controller that manages your "children" view controllers. You can find information on doing this, as well as the methods needed to present/remove child view controllers here:
Custom Container View Controllers
You can use navigation controller with "hidden" property.
self.navController.navigationBarHidden = YES;
If you want to have two different views and transition between them, you will want to use UIViewControllers presented modally. Here is Apple's Guide to this.
In an iPad application I have a tab Controller containing several view controllers. One of these view Controller (call it MainViewController) needs 2 table views side by side.
So I wrote 2 UITableViewController subclasses and from MainViewController, I alloc/init both subclasses of UITableViewController, and add the tableview from each to the MainViewController's view.
This means that UITableViewController subclasses's views are subviews of MainViewController's view.
This answer: https://stackoverflow.com/a/7684648/191463 says that doing that is incorrect and it seems Apple are starting to cut down on it.
I really do not want to have to put all the code from both UITableViewControllers in MainViewController, as it will make it much harder to read and in future could create duplicate code, if I want to use one of the tableview elsewhere in the app by itself.
Is this actually a problem, if it is how do I do it properly?
Apple isn't cutting down on it. This is the only way to create custom container view controllers prior to iOS 5. Apple actually listened to the developers and made it easier to do this sort of thing in iOS 5 with child and parent view controller methods, not to mention they made it so it worked hierarchically.
In most cases, this wouldn't actually be a problem in terms of applications crashing or performance or anything. It can be a problem in some cases, because let's say you have a child view controller. You add the view controller's view to your root view controller. Prior to iOS 5, child view controllers were things like navigation controller view controllers, tab bar controller view controllers, and modal view controllers. What happens when you have a button that calls [self.parentViewController dismissModalViewControllerAnimated:YES];? Technically, the view controller isn't being presented as a modal view controller, you added the view to the root view controller view.
In iOS5, you're able to add child view controllers to view controllers and are able to transition from one child view controller to another.
Now even if your view controller doesn't have a different parent, adding a "root" view controller to another root view controller isn't the best way to do it (especially since you don't get access to the parent view controller unless you explicitly create a parentViewController pointer in the child view controller). So in the end, Apple just made it easier and more decoupled.
It is OK to do it so long you take the responsibility of managing the viewController life cycle events
initWithNibName...
loadView:
viewDidLoad:...
.
.
viewDidUnload..
dealloc
memoryWarnings
orientation changes
So if you create a custom "container view controller" it becomes your responsibility to call all these methods on child viewControllers at the appropriate time. Think of it as "If you were to implement UITabBarController" what all will you have to manage regarding the children ??"
It quickly gets complex. Adding another viewController's view as subview is childs play.
iOS 5 does some of this stuff for you by specifying parent child relationship, however I still haven't seen any sample code anywhere yet to point to.
I'd say it is not incorrect or wrong to create view controller containers, especially when Apple engineers do that themselves. UITabBarController, UINavigationController or UISplitViewController - they are all view controller containers. More over many great apps with unique UX do that more common than you think. However the real issue is that it's quite hard to do it the right way, so e.g. view lifecycle, memory management and rotation handling is done properly along the hierarchy of views. Fortunately Apple guys did a decent job and iOS5 introduced lots of functionalities regarding controller containers:
UIViewController class reference
View Controller Programming Guide for iOS
If you're interested how above problems had to be addressed before iOS5, read these two very good blog posts:
Writing high-quality view controller containers
Using view controllers wisely
If I want to replace one screen of an app with another, but I don't use a navbar/tabbar controller, then I could just remove oldViewController.view from window and add newViewController.view to it. That's all, now newViewController will get rotation events, etc.
But UIView does not reference "its" controller, so how is this possible, how iOS know it should make newViewController an active one? Does iOS do some magic, it internally references controller from view or what?
UPDATE:
I think I was misunderstood: I don't ask how to make some view controller an active one - I know that. I'm just curious, how is it possible that I pass some view to UIWindow object ([window addSubview:view]) and it somehow finds view controller although view doesn't know its controller.
yeh I had the same question like you. and I figured it out.
UIView is derived from UIResponder. and UIView must subclass UIResponder::nextResponder.
Its default implementation is returning a view controller of the view (if it hadn't, it would be super view)
So, consequently view can see its controller. that means window know the topmost view and also
its controller.
good luck.
Unfortunately, iOS only send events to the first ViewController of the stack. You can try and present a new one on the top of others with video for example, it will never rotate.
If you don't use navbar/tabbar controller you will have to add and remove everytime from the Window to keep only one at the time if you wand to have events.
The main UIWindow class for your application will have a view controller set in its rootViewController property. That controller's view is the "main" view for the app. This is usually setup in the main .xib for the project. That view controller will receive the usual events like "viewDidAppear" or "willRotateToInterfaceOrientation". You can put up your own view over top of it if you want to, but you will need to manage those events yourself. Usually you don't do that though. You just use a UINavigationController or UITabBarController as your rootViewController and allow them to manage getting the events to new "pushed" view controllers, or you popup view controllers with "presentModalViewController".
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have just started developing iPhone applications and I am very confused by how the "view controller" aspect of the user interface works.
I did the "Your First iPhone Application" tutorial on the Dev Center. It has you set up your own view controller class and then initialize it using initWithNibName. So it seems that nib files contain view controllers. But it's also possible to have a nib file that just has a view, not a view controller. For example if you set up a TabBarController and then navigate to any tab other than the first one, there will be a gray box that says "view" and if you double click that you get to set up a view to go in that tab (but it's just a view, not a view controller, am I right?) So are views subclasses of view controllers or vice versa?
Another thing I am having trouble understanding is nested view controllers. The way I understand that you use a view controller (at least from the tutorial) is that you create your own custom view controller (or is it actually a view controller? In the tutorial I don't see where myViewController is actually declared to extend UIViewController) that has all the delegate methods in it, and then use initWithNibName to load the existing view controller into the custom view controller. (Right so far?) So suppose I create a nib file with a TabBarController at the root, and of course each tab will have a root view controller. So then I loadWithNibName the file and stick it in my own root view controller. Now how do I get access to all the "internal" view controllers so that I can assign delegate methods to them? Or is the recommended option to make the root view controller the delegate for both its own view and the views of all the subsidiary view controllers?
Here's another example. I am planning to have a TabBarController where for some of the tabs, the view controller for that tab will be a NavigationController. The way I understand navigation controllers is that you have to programmatically push a view on top of the stack when you want to drill down in the hierarchy. Suppose the view I pushed on is a view I originally created in Interface Builder (and loaded in using initWithNibName.) But of course the space to display the view is smaller than the space available for the view when I created it (because when I created it it was on a blank slate, while when I display it there's a navigation bar and a tab bar using up some of the screen.) So do the view controllers automatically resize the view to compensate? (IIRC, part of the documentation did mention auto-resizing somehow, but it seems like since the aspect ratio changes, scaling to the right size would leave the text looking "squashed".)
Finally is there some tutorial or explanation somewhere that explains clearly how the view controllers work? That also might help me answer my questions.
Docs on view controllers and learning related stuff
(1) Apple's UIViewController reference. Short and sweet (relatively).
(2) View Controller Programming Guide for iPhone OS. More wordy.
(3) Not view controller specific, but still: Cocoa Dev Central. Education with pretty pictures.
Nested View Controllers
The fact is that there are some key points that are a tad glossed over in the introductory docs. And I think a lot of the confusion arises from using the tab bar controller and navigation controller in particular.
For example:
You should not use view controllers to manage views that fill only a part of their window—that is, only part of the area defined by the application content rectangle. If you want to have an interface composed of several smaller views, embed them all in a single root view and manage that view with your view controller.
-UIViewController class reference
So, that certainly makes it sound like you should never nest view controllers, right? Well, from my experience, what they meant to say was something more like never nest view controllers, except maybe in a tab bar controller, or in a navigation controller, or in a navigation controller in a tab bar controller. But other than that, never nest view controllers.
View resizing
Another good question you raise: Is the coder responsible for sizing the view, or is that done by a view controller? And the usual answer is: yes, the coder is responsible for all layout and exact sizing of view elements -- except when that view is the first one added to a tab bar or navigation controller -- they tend to be somewhat aggressive about sizing your views for you. There are more details to know - things like autoresizing your view if the orientation changes - but this is a good rule of thumb to start with.
Views vs view controllers (and models)
Neither views nor view controllers are subclasses of each other. They're independent dudes. Generally, a view controller is more in charge, and tells the view what data to display, or where to position itself, etc. Views don't really tell controllers what do to, except perhaps to inform them of a user action, such as a UIButton calling a method in its controller when it gets pushed.
Here's a quick analogy to help understand the whole MVC model. Imagine you're building the UI for a car. You need to build a dashboard to display information to the driver - this is the view. You need sensors to know how fast it's going, how much gas you have, and what radio station is on - this data and direct data-handling stuff are like model objects. Finally, you need a system which knows when to turn on the low-on-gas light, or to turn off your turn signal when you turn the wheel far enough, and all the logic like that - this is the controller component.
Other stuff
A nib file is mostly a way to save view-related data that would make for ugly code. You can think of them logically as freeze-dried class instances, ready to use. For example, positioning a grid of 20 buttons that will be the UI for a calculator; a bunch of pixel coordinates makes for boring code, and is a lot easier to work with in interface builder. It can also accommodate view controllers because that code is also occasionally very boilerplate - such as when you need a standard, everyday tab bar controller.
About which view controllers control which views: Again, the tab bar and navigation controllers are kind of special cases, as they can act as containers for other view controllers. By default, you think of having just one view controller in charge of the full screen at a time, and in that case, there's no question that this one view controller is handling any delegated calls back from your view or other elements. If you do have some container view controllers, then it still makes sense for the most-specific view controller (the most nested one) to be doing all the dirty work, at least for the views which are not controlled by the container controllers (i.e. anything not the tab bar / navigation bar). This is because the container view controllers aren't usually considered as knowing about what they contain, and this agnosticism gives us better decoupled, and more maintainable code.
And, yes, in this context a view controller is always meant to be a subclass of UIViewController.
View controllers are simply that - objects that handle control of a view.
A XIB files doesn't "contain" a view controller. Instead it normally tells a XIB, what view controller it will be wired up to eventually - that's what the initWithNib call is doing, creating a view controller, getting the view out of the xib, and then attaching the view controller to where the XIB says it should connect to parts of the view.
There are nested view controllers technically when you use a navigation controller or tab bar, but your own view controller basically gets called as if it were the top level because those containers understand they will be holding other view controllers.
As for resizing - it's not a pixel resize, it's a container resize. The view controller resizes the master view it's hooked up to, then the auto-resizing behavior for any elements that view holds determines how they are resized - some things like lables might shift around, but by default do not shrink. If you click on the Ruler tab in IB you can see the current autoresize behavior for any object in a view - the center lines with arrows at both ends tell you if an object will allow resizing, and in which directions. The lines on the outside of the square tell you what side(s) the object will "stick" to, meaning the object will keep the same distance from those edges no matter how the container holding it resizes.
I'm not sure what the best book for IB is, but you probably cannot go wrong with a good fundamental Cocoa book which should explain autoresize behaviors.