Creating a custom popover for iPhone - what class do I subclass? - ios

I saw this question here (How to create popover in iPhone app?), and wanted to design a class that could create a popover object, I find all the libraries for popovers right now aren't doing quite what I'd like to do.
So I figure I'll create my own, but I'm a little new at it. Do I subclass UIView directly? Could anyone point me in the right direction for this task?

Subclass UIView. Implement the layerClass class method of your custom UIView subclass and return [CAShapeLayer class] (from the QuartzCore framework), or use your own subclass of CAShapeLayer instead of CAShapeLayer itself. In your UIView subclass' implementation of initWithFrame: you can set the view's layer's path to get the popover shape you want to display.

Creating a popover by subclassing is one of the way to achieve your goal, even its a simple matter of doing google as there are may solutions on StackOverflow about the same.
Take a look at this answer This will help you to proceed.

Related

Single drawRect implementation across multiple UIView subclasses

Across my app I have several different subclasses of UIView: UIDatePicker, UIPicker, UIButton, UITableView, UITableViewCell, UITextView, etc. etc... For each of these I'd like to add a very simple drawRect custom implementation that I have working great.
Is there a simple way to get multiple subclasses of UIView to all have the same drawRect implementation without creating a subclass and repeating the same code across each UIPicker, UIButton, etc. etc... ?
I realize the solution to this is probably to write a delegate class for UIView's layer property and do the custom drawing in drawLayer, but I thought I would ask before I go re-working my code.
The answer seems to be no.
Furthermore, it appears that my idea for the workaround also doesn't work: I was thinking I could write a nice little class that implements the drawLayer method from CALayerDelegate and do the drawing in there, and then in each UIView or UIView subclass' init method do a self.layer.delegate = niceLittleCALayerDelegateClass.
My research, however, happened upon this: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/#//apple_ref/occ/instp/CALayer/delegate which contains the damning sentence: In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer.
So, double nope.
Against rmaddy's advice I'm going to just write a subclass for each of the UIView subclasses I want to implement this drawing behavior in. We'll see how that goes.
Update:
I can't believe I didn't think of this before, but the "right" way to do this (that is to say without subclassing UIView's subclasses and adding a custom drawRect method to each subclass's subclass), from everything I can find, seems to be to either create a subview or a sublayer with a transparent background that does whatever custom drawing you want.
Obviously this is going to draw on top of the UIView you're actually using, so this would get exceedingly complicated if you're trying to draw things that interact with the default elements of the UIView, but for my purposes (just a simple frame drawn with a UIBezierPath) it seems to work great.
At present I'm not sure if the subview or the sublayer approach is more efficient. If anyone can shed light on that, I'd appreciate it.

xcode 4 drawing rectangles

i'm very new to xcode. i've googled this and even serched here and i didn't find exactly what i was looking for. i really wanna get this. especially since it's the most basic thing there is.
so, i have the .h and .m files
i want to DRAG a uiview into the .xib file, i don't want it to be as big as the screen, so i resize it.
now i want to draw a bunch of rectangles INSIDE this view object.
how do i go about doing this?
your help would be greatly appreciated!
So you add a generic UIView then create a subclass of UIView and do your drawing inside the drawRect method.
Then change the class of the UIView to your subclass name in the inspector.
Be sure to #include your header in the app delegate.
That's the basic thing.
For more sophistication, you're going to want to learn to use UIViewController subclasses as well. These are used all over ios.

UIView or UIViewController subclass?

I'm trying to refactor my code in the best possible way and I'm wondering what the proper architecture for the given situation is.
What I'm Trying To Do
What I'm doing is pretty simple: I have some custom CALayer subclasses that represent an interactive UI element. They are broken up into multiple layers since some of the parts of the UI are static, so I didn't want to redraw those static elements needlessly. Right now, the layers are added as sublayers in the initialization part of a CustomView class that is a subclass of UIView.
There is currently no corresponding CustomViewController class that is a subclass of UIViewController because when I'm using the CustomView, it's contained within a UITableViewCell or a part of a generic UIViewController with other views in it, so I felt another UIViewController for each CustomView instance would be redundant.
Also of importance is the that the only operation that I'm doing inside of the UIView class is I'm responding to touch events and sending the touch information to the sublayers so that the UI can update its appearance accordingly. I'm not overriding the drawRect method or anything like that.
The Question
Basically, I'm trying to figure out whether I should either:
Option 1:
Get rid of the CustomView class, create a CustomViewController class that is a subclass of UIViewController, and simply add the CALayer objects as sublayers of the CustomViewController's built-in view property.
or
Option 2:
My thinking about the UIViewController subclass being redundant is correct, so I should leave it the way I have it and have a CustomView class with the CALayer objects inside of it.
I would highly appreciate any advice on this.
I think that in terms of MVC, the code you're describing (option #2) is well written and maintains a very clear boundary of responsibility. You're not writing any code that has nothing to do with the view layer itself in this class which is great. I think that in this case there's no need for a separate UIViewController subclass to manage these instances because as you said - they are handling their own touch events and visible layers (exactly their responsibility).
If for any reason there is a need for something more complex that requires data related logic or other such computation, I would definitely consider subclassing a UIViewController or maybe looking at the problem in an entirely different way.
Given the situation you've presented, I think that maintaining the CALayer instance within this UIView subclass ('CustomView') is the right way to go.

Can a subclass of B (which inherits from class A) inherit from a subclass of A instead of A itself?

I'm working on an accessibility project for an iOS application. Because accessibility does not act quite as advertised, I have to override accessibilityFrame, accessibilityActivationPoint and pointInside:withEvent in a subclass in order to expand the region recognized by VoiceOver (for both drawing and touch recognition) beyond the "natural" bounds of the control view. So, in order to change the VoiceOver bounds of a UIButton I have to subclass that class and then add these three methods. In order to do this for a UILabel I have to add another subclass with the code, and so on.
I can refactor the code in these methods to a central location, but I was wondering if this can be done more elegantly with inheritance. I'd like to put this code into a subclass of UIView (maybe called UIViewAccessible) and then create a subclass of UIButton called UIButtonAccessible which inherits from UIButton which would in turn inherit from UIViewAccessible instead of UIView. Is this possible, or can something like this be done with a category?
Edit: According to the docs, you can't really achieve this with a category:
If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.
Is there some other way to do this?
To answer your question, no, it can't, since your UIViewAccessible is a second degree sibling to UIButton in the inheritance chain (both inherit from UIView at some point). But I guess you already knew that. As for a solution, you could wrap around your UIView accessible classes a decorator and use protocols for strong typing. That way you'll keep the code in one place. I've described this technique here in more detail (although for a different purpose, it's the same situation).
For the views that would support accessibility you'll have to do this:
#property (nonatomic, strong) UIView<MyAccesibilityProtocol>* view;
//self.view can come from the nib or previously created in code
self.view = [[AccesibilityDecorator alloc] initWithDecoratedObject:self.view];
//you can then use self.view like any other UIView,
//and because it also implements an
//accessibility protocol, you can use the methods
//implemented in the wrapper as well.
//more than that, you can control which methods to override
//in the AccesibilityDecorator class
[self.view addSubview:otherView];//could be overridden or not
[self.view myAccesibilityMethod];//custom method declared in the protocol

UIView Responsabilities (Object-Oriented Programming)

I am just starting out with iOS app development and it's been a great experience so far. Apple documentation is great, but there are some questions I have that are not as technical and only someone with experience might be able to answer.
I have a bunch of UIViewController which handle the "dynamic skinning" of the custom UIViews that they control. This leads to a controller with big chunks of code which seems a bit unpractical to me.
So the question is: Following the MVC pattern, should I give the responsibility of setting a UIFont, UIColor, etc to the view itself? Or should I create "micro" controllers that handle this task using some kind of input?
Thanks for the response.
Creating UIView subclasses that handle the layout works. Override layoutSubviews in the UIView subclass to do the positioning layout (setting frames etc). I find the init method to be a good place to set fonts, colors etc.
Now the UIViewController has relatively little code related to the custom UIView. The viewController just needs to position an instance of the custom UIView and perhaps set a few properties (like a textLabel's text).

Resources