Creating a Custom View - IPHONE APPS

The UIView class provides the underlying support for displaying content on the screen and for handling touch events, but its instances draw nothing but a background color using an alpha value and its subviews. If your application needs to display custom content or handle touch events in a specific manner, you must create a custom subclass of UIView.

The following sections describe some of the key methods and behaviors you might implement in your custom view objects. For additional subclassing information, see UIView Class Reference.

Initializing Your Custom View

Every new view object you define should include a custom init With Frame: initializer method. This method is responsible for initializing the class at creation time and putting your view object into a known state. You use this method when creating instances of your view programmatically in your code.

Listing shows a skeletal implementation of a standard init With Frame: method. This method calls the inherited implementation of the method first and then initializes the instance variables and state information of the class before returning the initialized object. Calling the inherited implementation is traditionally performed first so that if there is a problem, you can simply abort your own initialization code and return nil.

Initializing a view subclass

If you plan to load instances of your custom view class from a nib file, you should be aware that in iPhone OS, the nib-loading code does not use the initWithFrame: method to instantiate new view objects. Instead, it uses the initWithCoder: method that is defined as part of the NSCoding protocol.

Even if your view adopts the NSCoding protocol, Interface Builder does not know about your view’s custom properties and therefore does not encode those properties into the nib file. As a result, your own init With Coder: method does not have the information it needs to properly initialize the class when it is loaded from a nib file. To solve this problem, you can implement the awake From Nib method in your class and use it to initialize your class specifically when it is loaded from a nib file.

Drawing Your View’s Content

As you make changes to your view’s content, you notify the system that parts of that view need to be redrawn using the set Needs Display or set Needs Display InRect: methods. When the application returns to its run loop, it coalesces any drawing requests and computes the specific parts of your interface that need to be updated. It then begins traversing your view hierarchy and sending drawRect: messages to the views that require updates. The traversal starts with the root view of your hierarchy and proceeds down through the subviews, processing them from back to front. Views that display custom content inside their visible bounds must implement the drawRect: method to render that content.

Before calling your view’s drawRect: method, UIKit configures the drawing environment for your view. It creates a graphics context and adjusts its coordinate system and clipping region to match the coordinate system and bounds of your view. Thus, by the time your drawRect: method is called, you can simply begin drawing using UIKit classes and functions, Quartz functions, or a combination of them all. If you need to access the current graphics context, you can get a pointer to it using the UI Graphics Get Current Context function.

Listing shows a simple implementation of a drawRect: method that draws a 10-pixel-wide red border around the view. Because UIKit drawing operations use Quartz for their underlying implementations, you can mix drawing calls as shown here and still get the results you expect.

A drawing method

If you know that your view’s drawing code always covers the entire surface of the view with opaque content, you can improve the overall efficiency of your drawing code by setting the opaque property of your view to YES. When you mark a view as opaque, UIKit avoids drawing content that is located immediately behind your view. This not only reduces the amount of time spent drawing but also minimizes the work that must be done to composite that content together. You should set this property to YES only if you know your view provides opaque content. If your view cannot guarantee that its contents are always opaque, you should set the property to NO.

Another way to improve drawing performance, especially during scrolling, is to set the clears Context Before Drawing property of your view to NO. When this property is set to YES, UIKIt automatically fills the area to be updated by your drawRect: method with transparent black before calling your method. Setting this property to NO eliminates the overhead for that fill operation but puts the burden on your application to completely redraw the portions of your view inside the update rectangle passed to your drawRect: method. Such an optimization is usually a good tradeoff during scrolling, however.

Responding to Events

The UI View class is a subclass of UI Responder and is therefore capable of receiving touch events corresponding to user interactions with the view’s contents. Touch events start at the view in which the touch occurred and are passed up the responder chain until they are handled. Because views are themselves responders, they participate in the responder chain and therefore can receive touch events dispatched to them from any of their associated subviews.

Views that handle touch events typically implement all of the following methods, which are described in more detail in “Event Handling”.

Remember that, by default, views respond to only one touch at a time. If the user puts a second finger down, the system ignores the touch event and does not report it to your view. If you plan to track multifinger gestures from your view’s event-handler methods, you need to reenable multi-touch events by setting the multiple Touch Enabled property of your view to YES.

Some views, such as labels and images, disable event handling altogether initially. You can control whether a view handles events at all by changing the value of the view’s user Interaction Enabled property. You might temporarily set this property to NO to prevent the user from manipulating the contents of your view while a long operation is pending. To prevent events from reaching any of your views, you can also use the begin Ignoring Interaction Events and end Ignoring Interaction Events methods of the UI Application object. These methods affect the delivery of events for the entire application, not just for a single view.

As it handles touch events, UIKit uses the hitTest:withEvent: and point Inside: with Event: methods of UI View to determine whether a touch event occurred in a given view. Although you rarely need to overrides these methods, you could do so to implement custom touch behaviors for your view. For example, you could override these methods to prevent subviews from handling touch events.

Cleaning Up After Your View

If your view class allocates any memory, stores references to any custom objects, or holds resources that must be released when the view is released, you must implement a dealloc method. The system calls the dealloc method when your view’s retain count reaches zero and your view is about to be deallocated itself.

Your implementation of this method should release the objects and resources it holds and then call the inherited implementation, as shown in Listing.

Implementing the dealloc method

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd Protection Status