which one should i choose, subclassing or categories - ios

I have UIlabel and includes few customisation of it . and this label is used in so many screens in my application. i tried with both subclassing and categories in prototype.
which is preferred one to use in this case. subclassing or categories.

Scenario - 1 : If you want to change something which happens as part of framework calls during the lifecycle of a UI object? - use subclass.
Scenario - 2 : If you want something application wide, something which is in addition to the existing functionality, and you don't care if this becomes available to all instances of this pre-existing instances of the framework class?
 - use categories.

You should use Subclassing instead of category. Category should be used when you want to alter the behavior of every instance of class while Subclassing should be used when you want to alter behavior of specific instance or objects.
Category is harmful also in some cases as you are manipulation existing class so it is better to use Subclassing where possible!!

Related

What is the design pattern being used in this video?

I recently watched this video tutorial on how to create a custom UIPickerView, and I successfully implemented the UIPickerView in my project. However, I would like to make some changes to the UIPickerView that appears within my app.
For starters, is the custom UIPickerView outlined in the video an example of subclassing?
Second, is it possible to modify an instace of the custom UIPickerView to have a different text label other than Done? And if so, would I have to modify the KCModalPicker.h/m files?
Thus bringing me to my third question, if I modify the KCModalPicker.h/m files then every other instance of the class in my project will inheret the changes, so what is a way to keep the base class as is, but be able to add customization to the class, so things like how many columns the UIPickerView has is dependant upon the instance that is obstantiated, and not dependant upon the KCModalPicker.h/m files?
UPDATE
The source for the ModalPicker class I am referring to, can be found here,
https://github.com/subdigital/nsscreencast/tree/master/025-custom-picker-component-part-1
I don't want to watch a video in order to answer your question, and suspect others feel the same way. (I hate watching development videos because they are long and tedious. I don't need somebody explaining in great and painful detail how to do something. Let me skip to the parts I'm interested in.) You should describe the scheme that is used so that we can answer your questions about it.
If that video describes a class KCModalPicker, it might subclass UIPickerView, or it might contain a picker view (that would be a "has-a" relationship, not an "is-a" relationship. The KCModalPicker is probably a modal view controller that has a picker view inside it.)
If you want to modify a class, like KCModalPicker, but don't want to change all instances, then yes, subclassing would probably be a good way to go. Create a subclass called something like MyModalPicker that inherits from KCModalPicker and changes the behavior however you need it to.
EDIT:
After looking at the files on Github, it looks like the project has a class BSModalPickerView which is a subclass of UIView, and contains a UIPickerView. As described above, this is a "has-a" relationship. The BSModalPickerView class has a picker view inside it that it manages. So no, this project does not appear to use subclassing.
The demo program has a view controller that uses the BSModalPickerView method presentInView:withBlock: that displays the picker as a subview of the view controller's main view.
It looks like there is also a method presentInWindowWithBlock: that will display the picker view directly in the window.
If you want to modify the behavior of some BSModalPickerViews and leave others alone, creating your own custom subclass of BSModalPickerView would be a reasonable way to do that. You could also modify the root BSModalPickerView to have more setup options (extra properties or parameters that you pass in the init method).
BTW, your question asks about KCModalPicker.h, but the class I see in the github link you posted is BSModalPickerView. Not sure what the discrepancy is.

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.

What is the need of subclassing UIView

I have a question that why should we create a class derived from UIView when I can put as many UIViews in any view controller and can access them with IBOutlet.
Is there any special functionality which we get after subclassing UIView.
May be its not a valid question, But I seriously wish to know the answer.
Any help will be appreciated.
Thanks In Advance.
example:
#Interface CustomView: UIView
{
}
Mostly you subclass UIView or any UIComponent for customization. When you subclass you can override drawRect method and do your own customization.
See the best practices for subclassing UIView here.
It simply depends! What if I want to draw some custom shape on my view? I can just subclass a UIView and use drawRect: make whatever I want and then use it. So, the reasons are numerous but really depends on your desire.
To support further. Refer the below link:
https://softwareengineering.stackexchange.com/questions/209576/what-are-the-reasons-to-create-uiview-subclass
Subclass is required only when you need to add some extra properties, behaviors, like the view should have some glossy effect, round rect corner etc.
However from UIView or from any other Cocoa Classes (foundation or UIKit or any other kit) they give you most of the required-common features, but at times as per your requirement you need to put something extra. For this purpose you extent the class by
Subclassing or Inheritance.
Class Extension.
Categories.
Custom views is easier to reuse. You can incapsulate some logic inside view (drawing logic for example) and then reuse this view.
In my current projects book pages are shown in several places. So it is very convenient to incapsulate page-presentation/drawing in one UIView.
There are several use cases that can be applied to UIView inheritance, such as:
implementing a custom control
extending UIView with methods that implement specific functionalities (although it can also be done by using a category, although that works in a different way and usually applies to different use cases)
group correlated views into a single view, to improve usage, expose a clean interface and deal with views management internally
create a base view that you want to reuse in other UIView inherited classes, without having to implement the custom look and/or behavior on each subclass
Below some examples
Custom control - You want to implement a 4 states flat push button, which 'advances' to the next state on every tap. Each state is visually represented in a different way, for instance by changing the label, the border, and/or the color. Note: in this example it would be better to extend the UIControl or UIButton, which are both subclasses of UIView
Extension - You want a view that has a rounded border, a title and a body section, with the title having a bigger font and on inverted colors (white text on dark gray background).
Grouping - You have a panel where you want to display a user profile, with several labels and values (i.e. User Name: myusername), a profile picture, dynamically laid out.
Base Class - you have a set of views that share a common look, with a rounded border, a title at top right overlapping the border, and an internal panel where to lay out content. You create a UIView subclass called SOMyPanelBaseView, and then inherit other classes from it, automatically inheriting the look
In many cases (but not all) you can skip inheritance and implement everything in a view controller, but besides being a not good object oriented design (the view is highly tied to the view controller), it makes the view controller over complicated. By inheriting from a UIView instead you implement the view functionalities in a separate class, and plug those functionalities into the view controller.
Also, an UIView inherited class can be reused - whereas if you implement everything in the view controller, you can't unless you copy and paste code around.
To sum up, I think your question can be generalized as: why should I use inheritance in object oriented programming?
The same reasons behind using inheritance in OOP is the same as using it in a specific case, in our case for UIView. The topic is described pretty well on wikipedia

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