StoryBoard handling inherited view controller - objective-c

I am new to storyboard. I used to make my view using code. I have a question.
I created a view controller
#interface FunctionViewController : UIViewController
And I have use my code to add
a full screen button (alpha : 0.5)
a popup-like view in the middle (not full screen)
Then I created another Viewcontroller
#interface PlayFunctionViewController : FunctionViewController
and add some views on the popup-like view
I want to recreate these stuff by using storyboard.
How can I build these using interface builder and storyboard so that
I don't need to layout the full screen button and the popup-like view in every subclass of FunctionViewController?

You can't inherit the layout of a superclass in a subclass in a storyboard, i.e. if you visually lay out elements in a view controller in a storyboard and connect them to code, subclasses of that view controller, and even other instances of the same class, will have to be laid out individually, and will not automatically be populated or updated.
In other words, in a storyboard, you will have to manually lay out and connect all your interface elements in every individual instance and subclass that you add to the storyboard. This gives you flexibility in that you can reuse multiple instances of the same class throughout your app and lay them out differently, but it does not give you the ability to inherit layouts.
If you want to inherit your layout in subclasses, do your layout programmatically in the viewDidLoad of your superclass, and then all of your subclasses will have those interface elements, even if you design and lay them out in your storyboard (they will not be visible in the storyboard, but they will appear when you build and run your app).
Basically, if you want to have interface elements that are the same in a class and all its subclasses, create them programmatically, and they will exist in all instances and subclass instances, even if you create and design the instances themselves in your storyboard.
You can mix code and storyboard, so you can create some elements in your storyboard, but others that need to be present in all instances and subclasses, in code.

I ran into a similar issue, and though it was time consuming but creating a delegate and reusing it in multiple view controllers was a much better solution. Although that beats the whole point of 'Inheritance'.

Related

Base UIViewController with UICollectionView

I am having UIViewController which I want to use as a base controller for other view controllers. Base controller has a UICollectionView which has all the UICollectionViewCell prototype and some other stub views designed in storyboard.
All the child view controllers have one thing in common which is UICollectionView and has their own views in storyboard. I want to use the prototype cells designed in base view controller's collection view to populate child view controller's UICollectionView. I don't want to copy paste prototype cells from base controller's collection view to child controller collection view.
Base controller perform some actions on cell selection which are common to all child controllers. Child controller should be able to ask for any prototype cell from base controller, child will decide which cell to populate using cell identifiers.
I should be able to instantiate child controllers instead of base controller using their storyboard identifiers. I want to do maximum things in storyboard.
How this can be accomplished? Please suggest or any other better approach.
I am programming in Objective-C.
After digging a lot I found that its not possible to re-use prototyped UICollectionViewCell so I ended up creating separate XIB for each collection view cell.
This is what I did:
Created XIBs for collection view cells.
Wrote a base class BaseViewController which has a UICollectionView IBOutlet declared in its .h file. BaseViewController class confirms to UICollectionViewDelegate and UICollectionViewDataSource protocols.
2.1 In BaseViewController viewDidLoad method, registered all cell XIBs to UICollectionView.
2.2 Implemented delegate and data source methods which handle generic events. If needed child class can override those methods and perform specific tasks.
Create child view controllers in storyboard which have UICollectionView.
3.1 Connected UICollectionView to super's UICollectionView IBOutlet defined in .h file.
Now all done! Now I could dequeue any cell that is registered in super or if child view controller wants some specific cells it can prototype them in its own UICollectionView in storyboard and do the job.
Most of the times in my case didSelectItem was doing some generic operation in base class which were common to all child view controllers so I just dont implement it or if want to perform some other operations in addition to generic operations I implement the method and call super's implementation and after that do my stuff. All cell size and layout related methods are implemented by base view controller. Now I could create a new child view controller with collection view with minimal code and proper event handling.
Hope this helps someone. Thanks.

What's the advantage of using UIViewController as owner of xib?

Most of the time, owners of xib is a UIViewController.
I sort of use it my self.
Still I am confused why.
I suppose, the viewDidLoad and viewWillAppear is kind of the main selling point.
Is that it?
What are the advantage of using UIViewController as owners of an XIB?
A UIViewController object is the main way for views to appear within an iOS window.
Apple provides this as a fundamental, foundational building block (along with so many others) which you can use to build upon quickly and get your app out to market.
And when you subclass UIViewController, you're able to do lots of beautiful customizations which can be collected and eventually turned into (hopefully decent) products. When you subclass a UIViewController, you need to set the "owner" of a XIB file to that subclassed view controller (e.g. ThioViewController), so that way the app knows what object (and user interface) is being instantiated.
Hopefully this isn't too super abstract of an explanation.
First, spend a bit time to understand MVC http://en.wikipedia.org/wiki/Model–view–controller
This is the milestone of Objective-C (not only) development.
UIViewController is controller for all your views (inside this viewController). It provide starting point for you to create views on the screen, manipulate the views, handle actions from views etc.
You can create UIViewController programmatically.
XIB is representation of the screen which you can comfortably operate in Interface Builder to create and customize design of your application screen or one of the screens.
Since XIB represent the screen(view) it must be the controller which controls all the view on the screen - UIViewController or UINavigationController or other type of controller depending of your needs.
Most of time you will subclass UIViewController and use it to achieve you goals.
UIViewController have several subclasses which inherit directly from it (UINavigationController, UITabBarController).
Also UIViewController hav several methods (some of them)
-(void)viewDidLoad
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
and
-(void)viewWillAppear:(BOOL)animated
Parameters
animated
If YES, the view is being added to the window using an animation.
Discussion
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Please check Apple documentation for more information
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

Subview vs childViewController

This is a general question but I'll ask it using a specific example to avoid confusion:
I'm developing an app that has a UIPickerView among other things on a single screen. I was wondering if it's appropriate the make a custom PickerViewController class to control my UIPickerView and then add my PickerViewController as a childVC...
OR should I just create an instance of UIPickerView in my existing VC and control it from there?
When should I do either of these options and what are the advantages of them?
Appreciate the help amigos.
If the UIPickerView is simoultaneously on the screen along with other UI elements, then you should just add it as a subview. The concept of a view controller is for when you start managing a completely different UI/window/set of elements (however you call it). If the picker view closely belongs to the functionality of the other elements, you should not create a separate view controller for it.
iOS 5.0 introduced the notion of child view controllers. Originally, any view controller except for UINavigationController and UITabBarController had to be modal and full screen. In iOS 5.0, you can now have several UIViewControllers present on one screen. This means that one UIViewController can have many children (UIViewController), where each child is responsible for controlling more specific views and models.

How to initiate display of one view from another?

Assume you do not have a UIController to do the job. From inside the UIView .. how would you replace self with another UIView?
It's not very clear what you are trying to do from your question. UIController is not a class, for instance.
Ideally your app should be structured something like this:
UIViewController subclass
Controls a set of objects that are all on screen at one time. For example, any number of UITextFields, UIButtons, UIViews and UILabels.
has methods (IBActions and other delegate methods) which are triggered by user interaction with the controls and inputs.
has IBOutlets which allow it to manipulate what the user sees on screen. For instance an IBOutlet attached to a UILabel allows changing the text when a user presses a button.
UIView is only generally subclassed if you need custom drawing code, or some kind of custom control. Don't put application logic here if you can help it, and you can usually help it.
You can have multiple UIViewControllers but they usually function very independently. Often View Controllers don't maintain references for other view controllers. If they do it's loose couplings like the delegate pattern.
Bottom line: if you have two views controllers that need to communicate with each-other, you need to have a reference to one from the other. This usually occurs in the form of a property on one or both of the view controllers, and is connected either by interface builder or at run time when you create them.
You can add another subview using self.addSubview: you may also want to check self.bringSubviewToFront:
For more information, check the docs:
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html

Putting an ADBannerView on top of a UINavigationController

I'm trying to put an iAd banner in an app that is based on a UINavigationController (it's not the standard nav-base app proposed by xcode, cause I don't need the table view).
I'd like to place an ADBanner on its bottom, to be always visible, no matter how the user pops and pushes views.
I studied the iAdSuite example in the apple sample code, but, though it's reported among the "best practices", I don't think it's the best practice for what I need. It basically declares an ADBannerView in the app delegate class and then implements the ADBannerViewDelegate methods for every single view the app needs. That means implementing the ADBannerViewDelegate methods over and over again on every view controller class you need! It doesn't seem too smart... :(
I'd rather prefer to have an approach more similar to what Apple itself does in the tab bar based app, where you have a part of the window always occupied by the tab controller and all the views switching above without affecting the tab bar view below.
You can't directly put an ADBannerView along with the nav controller in the app delegate, because ADBanner needs to be placed in a view controller (you get a runtime error otherwise).
I tried to subclass from UIViewController, implementing the ADBannerViewDelegate in this class, and place it in the rootViewController along with a UINavigationController but I'm not having good luck with this approach...
Has anybody found a good, simple way to to this? Any hint?
Thank you for any help...
You can have just one class for ADBannerViewDelegate, and just one instance of ADBanner itself. When the currently active view changes, remove ADBanner from the old view, add it as a subview to the new view.
EDIT:
to clarify, you don't need each view implement the ADBannerViewDelegate. You only should have one class implement it (that class doesn't have to be a view controller for that matter).
You would also need to maintain a somewhere a property that would point to the currently active view (e.g. you can update that property in your Navigation Controller's navigationController:didShowViewController:animated:, or come up with your own protocol for that if your views appear in a more complex way).
Then in your ADBannerViewDelegate you'd just resize the view currently pointed to by that current view property. The actual view doesn't even have to know it has an ad in it ;)