Can I subclass a custom view controller - ios

I made a subclass of UITableViewController named CalendarTableViewController.h and .m. It shows a list of events within specified range (e.g. all events in 2014). I'd like to have two more view controllers (for month and day) and stack them on top of the first view controller.
Because all three view controllers have similar properties and behaviors, I'd like to subclass my custom view controller. Is this possible?
I'm about a year into developing with Xcode, so I may be missing something stupidly simple. But, all I know is how to subclass UITableViewController. How do you subclass your own custom view controller?
I would appreciate if you could share your wisdom.
Yoshi

In the world of object-oriented programming, objects are categorized into hierarchical groups. Rather than using distinct terms for the different hierarchical levels such as genus or species, objects are simply organized into classes. In the same way that humans inherit certain characteristics as members of family, a class can be set to inherit functionality from a parent class.
When one class inherits from another, the child inherits all the behavior and properties defined by the parent. It also has the opportunity either to define its own additional behavior and properties, or override the behavior of the parent.
Long story short, yes, you can and you should create subclass(es) in such cases. This is how you do in Objective-c in .h file (in your new class)
#interface MySecondController : CalendarTableViewController {
}
In Swift
class MySecondController: CalendarTableViewController {
// subclass definition goes here
}
I hope it helps

Related

View Controllers and Multiple Views

I'm working on my first iOS app and am trying to understand something about Views and View Controllers.
My question is this: In an App like Instagram there's an 'Activity' tab in the main Tab Bar Controller. The activity tab has a UISegmentedControl for "Following" & "You" which display similar data, but query different records. Would the data in each of these UISegments be controlled by a separate controller? (FollowingController and YouController, for example).
What about instances like viewing locations on a Map, and you want to have a Map view and a List view? Would there be a MapViewController and a ListViewController, or would one View Controller manage all of this, and different views would be loaded conditionally based on what the user selects?
No, you could use a single UIViewController and/or UITableView (depending on how you would like to present your data) and just change the dataSource based on Segmented Control's option.
For more information, please check UITableViewDataSource for instance. In case of Table View, dataSource is nothing else than an array of some data.
Another approach besides Table View / Collection View would be to put Container View in UIViewController which would use just a single UIViewController instance. For more information refer to the documentation. Especially, take a look at the picture:
For your second question - no again. You can have a single UIViewController and place instances of MapKit and/or list (aka UITableView). You can do that in Storyboard by dragging an instance of MapKit like this:
And your single UIViewController might look like this:
Sounds like inheritance to the rescue here.
If you have a UISegmentedControl for "Following" and another UISegmentedControl for "You" then it there is the possibility that the best architecture will be to use inheritance and have two separate controllers for each of those UISegmentedControls, with names FollowingSegmentedViewController and YouSegmentedViewController, this way your separate controllers know the type of data they are loading and working with ("You" data or "Following" data) and other special considerations or differences between your "You" UIView and your "Following UIView like one being a map and one being a table.
And then for common UISegmentedControl functions and properties you have a base class that both your FollowingSegmentedViewController and YouSegmentedViewController inherit from, call it BaseSegmentedViewController or whatever is appropriate for your app and archiecture.
This inheritance allows you to share common UI elements (via #outlets) and other methods/functions between FollowingSegmentedViewController and YouSegmentedViewController but then also address differences between the two specifically in their distinct controllers.

Inheritance of view

I'm new to iOS and I'm trying to understand how the platform works, so excuse me if I make any dumb questions.
My question is based on the problem present in this post:
Inheritance on view controller Objective c
So far, I understand I can inherit controllers, but can I inherit a view? I think the answer is NO. If that is the case, what is the best way to solve the following problem?
I have a card matching game. Now, I have to expand the game to have a similar card game but with a different deck and rules.
Therefore, I want to reuse the code and have a main controller and 2 inherited controllers that redefine the creation of the deck. Now I need to have 2 different views because the two games have a different number of cards. So, what is the best way to do this? Would I have to copy all the controls from one view to another and modify what's needed?
You can inherit a view just fine. Just create a subclass of UIView when you add a new file and then import that subclass.
Regarding your question, I feel like the best way to approach it would be to have a subclass of UIViewController called something like CardsController which has a deck property and can manage the display and change of cards based on a set of rules defined by you. Then, subclass that view controller further for each of your two games, since they both make use of cards.
You can subclass any kind of object, controllers, views, whatever
ex:
#interface MyCustomView : UIView
#end
If your two different views share a lot of code, then you shouldn't create them separately. They should have a common parent with the common methods and both of them inherit from this generic uiview

When to use Categories Objective-C?

If I have a method to attach an animation to an UI Element, instead of copy/pasting the code for this method into many viewcontrollers, can I just create one class to hold the method and then import it?
I assume it doesn't make sense to use a category in this instance because I need this method in multiple viewcontrollers, and a category is an extension of a single viewcontroller.
A category is an extension of a class, not of a specific instance of a class. And, any modification that a category makes to a class is available to all subclasses (as with other methods on classes in OOP).
So, if you add a category on NSObject, basically all classes in your entire app have access to the methods in that category - hence you need to be very careful what methods you add there.
Whether you add a category or a helper class is personal preference in a lot of cases, both will work.
Edited 9 April 2015
You have two basic choices:
Create a category, or create a custom subclass.
Categories
Categories allow you to add methods to an entire class, even classes for which you don't have the source code. Categories are especially useful for adding new methods to system classes where the system creates the object inside frameworks, where you can't change things to create a custom subclass instead.
You can add a category to a base class like UIView, and the methods you add become available to that class and all it's subclasses. So you could add an animation category to UIView and then all UIView objects including image views, buttons, sliders, etc, would gain the methods defined in that category.
Categories help you get around the fact that there is no multiple inheritance in Objective-C. (In the example above of adding animation behavior to UIViews, you can't create a subclass of UIView AnimationView, and then create a UITextView that inherits from both UITextView and AnimationView and also create a UIImageView that inherits from AnimationView.)
There are a couple of significant limitations to categories:
They can't really override the code of already-existing methods. (They can, but you can't call the super implementation, and if there are multiple categories with implementations of the same method, the results are undefined, so you should not do this.)
Categories can't add new instance variables to the classes they extend. (There are ways to simulate this using a technique called associative storage, but that's beyond the scope of this post
Custom subclasses
A custom subclass can override existing methods. It can also add new methods, properties, and instance variables. However, it can't add methods to an existing subclass like a category can.
Why use categories by example :
Lets say you have a base Class Engine that is inherited by Classes like Car, Bike and Scooter. Company was start-up and willing to add a functionality of maintenance that wasn't provided earlier.
Engine of Car, Bike and Scooter will be maintenaned under same policies. So it is better to add more functionalities on into Engine class instead of each Vehicle. In doing so we are not supposed to alter the Engine class for it may not be available to alter. Just create a category
Engine+Maintenance
and all the functionalities you put in maintenance will be available in all the subclasses. A better approach.
Categories are a way to split a single class definition into multiple files. Their goal is to ease the burden of maintaining large code bases by modularizing a class. This prevents your source code from becoming monolithic 10000+ line files that are impossible to navigate and makes it easy to assign specific, well-defined portions of a class to individual developers
Categories are an alternate of sub-classing. When we add a method to an existing class, it becomes a part of that class methods. So, any instance of that class can access that method. However, it doesn't mean that when you add a method to some existing class like NSString or NSArray, the class is going to add your method to its definition universally. It only means that inside that project, your NSString or NSArray class will have another method defined by you, and any class(inside that particular project) that is sub-classing it, or creating an instance of that class will have that method as a part of that class' definition.
So, you can add your animation to your desired UI Element by adding a method through category to that UI Element's UIView class. Let's say your UI Element is a button. Now, if you create an category for the UIButton then, whenever you create an instance of UIButton, you can automatically have a method to animate it.
Subclassing is one way to add functionality to an object, but avoiding unnecessary subclassing by using a category will help reduce the amount of code and keep your projects more organized.
https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html
categories are a subclass of specific class.for example if you want to change text color, background and font of label without programming code,then you have to make a catogories of UILabel class.

Should I use a protocol or category with associative objects to give my child view controllers properties?

Im building a custom view controller container and im figuring out which to use to give my children view controllers properties, similarly like UINavigationController grabs a view ontroller's title property, and left and right bar button item. What are the pros and cons of each? Note, i have seen the category method used more such as in te excellent View Deck Controller (https://github.com/Inferis/ViewDeck) and a bunch of other components
EDIT
viewDeck and other controllers use associative objects in conjunction with the category to pull this off.
I'd recommend not using a category: there are a number of XCode/LLVM compiler issues with adding libraries/frameworks that use categories to XCode projects (see https://developer.apple.com/library/mac/#qa/qa2006/qa1490.html). Protocols work cleanly for this sort of thing, in my opinion.
I'm not sure that I would use either. I think I would create a base view controller class with the properties, and then have all your child view controllers inherit from this class. Categories can contain methods but not storage, so no ivars or properties (that have a backing ivar).

iOS - dealing with large and growing UIViewController classes

I have a UIViewController that over time has had a lot of delegate events added to it which has made the controller class quite large. The UIViewController class contains quite a few view-management methods that are called from the event-delegate methods to manage the UIView that the controller is managing.
I am now adding further UIActionSheet delegate events to the class. My controller class is getting large and I'm thinking that I should break out the UIActionSheet delegate events and place them in a separate delegate class. This separate delegate class will then have to call back into the view controller class to get the view controller to adjust the view accordingly, using the view-management methods within the view controller. (The view controller accesses a separate model object that the view is representing).
I can see pros and cons to adopting this break-out approach. It feels wrong to be adding more and more delegate events to the controller, but creating separate classes for different categories of events that then need to call back into the controller also seems to introduce an unnecessary layer of complexity and obfuscation. The large controller class is 'simple and straightforward' but feels wrong, whilst using numerous different delegate classes will be somewhat more complex and involved but will result in smaller classes.
Can anyone provide some words of wisdom on this topic, and perhaps point me towards some iOS-specific reading on the matter?
Many thanks.
My approach to this matter is:
Make it work
Make it cleaver
Back to 1.
(Or 1 and 2 both in same turn if you are experienced in a field)
So if code works app looks good but you find that ups some class has 100 methods in it so try different design patters (if you haven`t already) and use those cleaver ideas to make code separation into different classes, delegates, encapsulate them if necessary et.
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html
Just in case link to Cocoa Design pattern suggestions and i am from time to time looking into Pro objective c design patterns for ios. Might be not the best book out there but it is based on "Gang of four" design patterns book in ios context.
Hope this helps at least somehow,
Cheers
In the end I created quite a few additional classes for dealing with specific UIActionSheet instances. I created a base class and then subclassed this for each UIActionSheet requirement within the main controller.
The end result looks tidy, and doesn't add too much complexity.

Resources