iOS Subclassing from single nib file and inheritance of IBOutlet connections - ios

I'm really really new to iOS programming in particular and MVC programming in general.
I have a project which uses a single nib for multiple subclasses (all of the base class that the nib was originally created for). The nib just contains a collection of buttons stored in an IBOutlet connection. I want the buttons to show and do different things when clicked depending on which subclass is referencing the nib.
Say, for instance I have a base class called BaseClassViewController, with a nib BaseClassViewController.xib which has one property
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *buttonCollection
Now I have a subclass called SubClassViewController which is a subclass of base class.
My question is if I call in an instance of the SubClassViewController [super initWithNibName:#"BaseClassViewController" bundle:nil], the right nib is loaded. Do I also inherit the IBOutletCollection property of the base class and all the connections between the collection and the .xib of the base class?
If not, is there a way to do this for a single xib without creating a new property in the subclass and reestablishing connections with the xib for the subclass? This would seem to defeat the purpose of inheritance in this simplified example.
My ultimate goal is to have the buttons do different things when clicked in different phases of the app. One possibility that I was thinking of is to create some kind of property in a single view controller that will determine what clicking will do, something like:
-(IBAction) buttonClicked:(UIButton)sender{
if([modeString isEqualToString:#"Mode1"]){
\\Do something
}
...
}
but this is very organization unfriendly and I wanted to have other methods for each subclassed view controller. Is there a better way for this than subclassing? Should I just have a different nib for each subclass even though they would be the same for each? Should I do something else?

Related

providing common functionality for different viewcontrollers in objective c

I have many viewcontrollers which needs to have some common functionality related to navigation.
Earlier I made a base class BaseViewController(extending UIViewController) which have all common functionality (like doing some tasks on viewDidLoad etc) and all my viewcontrollers extends BaseViewController.
The problem is that some of my viewcontroller should be subclass of UIViewController and some of UITableViewController, so I can not use above approach.
One way could be to write base class for both and duplicating code. Is there any better way without duplicating code.
While you can get around this by using delegation or helper objects, I would make the case for just not using UITableViewController. It is only a very light subclass on top of UIViewController, providing a table view, conforming to the delegate & data source protocols, and adding a property or two for selection & refresh.
While I wouldn't normally suggest recreating something that the framework has already done for you, it may (in your case) make your code more easy to understand if you just keep everything inheriting from a common base class and add a table view to one of the subclasses.
If you do think this would be a reasonable approach, the UITableViewController documentation overview gives a detailed description of exactly what & where these behaviours are implemented, so mimicking its exact setup is trivial.
Adding a table view to UIViewController
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#end
In your storyboard, drag a "Table View" from the object library and drop it on top of your View Controller scene's "View" in the Document Outline - this will replace the root view with a UITableView.
Then just hook it up:
ctrl-drag from the view controller to the table view to hook up the view and tableView outlets
ctrl-drag from the table view to the view controller to set the delegate and dataSource outlets.
Done - no magic required.

associate existing classes with storyboard

I'm new to iOS developing so please forgive me if the question is too naive. I'm writing an app based on some other's code, and the author the original code generated all UI elements programmatically (no xib/nib files). I want to modify the interface and go with the storyboard approach, so I have to associate the existing classes with the new view controllers I have on storyboard. I changed the "Custom Class" to the existing class via interface builder. But I keep getting this error:
2014-03-12 22:49:56.187 Reader[9064:a0b] The app delegate must implement the window property if it wants to use a main storyboard file.
Any thoughts? I hope I don't have to start over from scratch.
It means exactly what it says. Go to your app delegate file, usually named something like XXAppDelegate.h, then declare the property in the app delegate class like so:
#property (strong, nonatomic) UIWindow *window;

Ios single xib with multiple views

I've noticed that i can put in a single xib multiples UIView; the main view is associated with the file's owner, but how to reference other views in the xib?
My need: i've a xib view splitted with a fixed top part and a bottom part made by a tabbar with three tab buttons: by clicking each button i need to load a subview, so my idea is to put other sub-views in the same xib on other views and load them on demand. How to accomplish this?
Thanks
You can just create IBOutlets in your header files and associate them with the additional views, just like any other Interface Builder component (or even just ctrl-click and drag your views to your code, if you're working in XCode's automatic assistant mode).
For example, let's say you have a view controller called FooViewController, and a matching FooViewController.xib interface file:
#interface FooController : UIViewController
#property (nonatomic, retain) IBOutlet UIView *additionalView;
#end
...and then you can just connect your additional view up to its corresponding outlet (which will appear in IB under the file owner). It's really no different to hooking up a UILabel or UIButton.
One thing to note though - you say "my idea is to put other sub-views in the same xib on other views and load them on demand". All the views inside your XIB file will actually get created at the same time, so it's not really loading on-demand. I doubt, unless you're doing something crazy, that this will be an issue for you in practice.

Should UIViews have properties?

Using proper MCV with Objective-C can a UIView subclass have #propertys?
i.e. in the .h file
#class MyViewSubclass;
#interface MyViewSubclass : UIView
#property (strong, nonatomic) UILabel *labelLabel;
#property (strong, nonatomic) UILabel *valueLabel;
#end
or should this be done in a UIViewController subclass?
Thanks in advance.
It is most common to subclass UIViewController to manage the labels, fields, images, and other views within a view hierarchy. However, if you are creating a reusable component view that will be used throughout your application, then it's perfectly appropriate to subclass UIView and add properties to your subclass.
From Apple's iOS App Programming Guide:
View controller objects manage the presentation of your app’s content on screen. A view controller manages a single view and its collection of subviews. When presented, the view controller makes its views visible by installing them in the app’s window.
The UIViewController class is the base class for all view controller objects. It provides default functionality for loading views, presenting them, rotating them in response to device rotations, and several other standard system behaviors. UIKit and other frameworks define additional view controller classes to implement standard system interfaces such as the image picker, tab bar interface, and navigation interface.
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/AppArchitecture/AppArchitecture.html#//apple_ref/doc/uid/TP40007072-CH3-SW1
It's good for views to have properties, but don't mix model logic into a view. The properties in a view should describe how the property looks, not what the property holds. I would avoid having a property named valueLabel in a view.
An example of view property names is UITableViewCell. It has properties imageView, textLabel, and detailTextLabel.
It's perfectly reasonable for a UIView subclass to have properties. You might need them to implement layoutSubviews, for example.
It is perfectly reasonable, also if you want to create a reusable component that allows for interaction and better flexibility, take a look at UIControl (which is a subclass of UIView)

IBOutlets to other view controllers in storyboard

I want to switch between multiple view controllers with a UIPageViewController. These view controllers are static though so i want to design them in my storyboard. Since one can't use relationships or segues to connect them to the UIPageViewController but a datasource, I need to have a datasource object with an IBOutletCollection holding the pages:
#property (retain, nonatomic) IBOutletCollection(UIViewController) NSArray* pages;
Although, I am not able to connect this outlet to the view controllers in question. I guess thats because view controllers in a story board are treated completely independently like they were in different nib files. Is there a solution though? I don't want to design these view controllers in code.
An IBOutlet is probably not the way to go about this. The best way to do so in my opinion would be to get the nib file using an identifier that you specify in storyboard and then in the viewDidLoad method, type this in and replace the variable name and identifier with the applicable names.
UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:#"myIdentifier"];
Hope this helped you get it working.

Resources