iOS UI PATTERNS

iOS UI PATTERNS

Introduction

Most established mobile platforms have a set of design patterns, written or unwritten guidelines of how things should look, feel, and function. Applying established design patterns improves the usability of our product, increases conversion, and provides a feeling of familiarity to users. Ignoring standards will confuse and frustrate users, hence every application design developers should try to avoid as much as possible.

In this article, we shall look at design patterns of iOS by showing a few sample design patterns and how existing applications apply these design patterns.

Types of design pattern

Singleton Pattern:

The Singleton design pattern ensures that only one instance exists for a given class and there’s a global access point to that instance. It usually uses lazy loading to create the single instance for the first time. In some situations it can be problematic to have two instances of a class running; this should be the only reason to use the singleton pattern.

It is a very common pattern, but developers have to be careful not to overuse it.

Decorator Design Pattern:

The Decorator pattern dynamically adds behaviors and responsibilities to an object without modifying its code. It’s an alternative to sub classing where we can modify a class’ behavior by wrapping it with another object.

In Objective-C there are two very common implementations of this pattern:

  • Category
  • Delegation

Category:

Category is an extremely powerful mechanism that allows us to add methods to existing classes without sub classing. The new methods are added at compile time and can be executed like normal methods of the extended class. It’s slightly different from the classic definition of a decorator, because a Category doesn’t hold an instance of the class it extends.

Delegation:

The other Decorator design pattern, Delegation, is a mechanism in which one object acts on behalf of, or in coordination with, another object.

Use Case

How to use singleton pattern:

singleton mobile

The above image shows a Logger class with a single property (which is a single instance), and two methods: sharedInstance and init.

When a client sends the shared Instance message for the first time, the property instance isn’t yet initialized, so we can create a new instance of the class and return a reference to it.
The next time when we call shared Instance, it is immediately returned without any initialization. This logic assures that only one instance exists at all times.

We’ll implement this pattern by creating a singleton class to manage all the album data.
We can notice a group called API in the project; this is where we’ll put all the classes that will provide services to our app. inside this group to create a new class with the iOS\Cocoa Touch\Objective-C class template. Name the class LibraryAPI, and make it a subclass of NSObject.

Open LibraryAPI.h and replace its contents with the following:

 Now go to LibraryAPI.m and insert this method right after the @implantation line:

 There’s a lot of process involved in this short method:

  • Declare a static variable to hold the instance of our class, ensuring it’s availability globally inside our class.
  • Declare the static variable dispatch_once_t, which ensures that the initialization code executes only once.
  • Use Grand Central Dispatch (GCD) to execute a block which initializes an instance of LibraryAPI. This is the essence of the Singleton design pattern: the initialize is never called again once the class has been instantiated.
  • The next time you call sharedInstance, the code inside the dispatch_once block won’t be executed (since it’s already executed once) and you receive a reference to the previously created instance of LibraryAPI.
  • Solution:

We now have a Singleton object as the entry point to manage the albums. Take it a step further and create a class to handle the persistence of your library data.

  • Step 1: Create a new class with the iOS\Cocoa Touch\Objective-C class template inside the API group. Name the classPersistencyManager, and make it a subclass of NSObject.
  • Step 2: Open PersistencyManager.h. and add the following import to the top of the file:
  • Step 3: Next, add the following code to PersistencyManager.h after the @interface line:
    The above are prototypes for the three methods we need, to handle the album data.
  •  Step 4: Open PersistencyManager.m and add the following code right above the @implementation line:
    The above adds a class extension, which is another way to add private methods and variables to a class so that external classes will not know about them. Here, we can declare an NSMutableArray to hold the album data. The array’s mutable so that we can easily add and delete albums.
  • Step 5: Now add the following code implementation to PersistencyManager.m after the @implementation line:
  • Step 6: Now add the following three methods to PersistencyManager.m
    These methods allow us to get, add, and delete albums. Build project just to make sure everything still compiles correctly. At this point, we might wonder where the PersistencyManager class comes in since it’s not a Singleton. We will further explore the relationship between LibraryAPI and PersistencyManager in the next section.

How to use Categories pattern:

Imagine a situation in which you have an Album object that you want to present inside a table view:

artist sabari

Where does the album titles come from? Album is a Model object, so we’ll need some external code to add this functionality to the Album class, but without modifying the class directly.
So, we will create a category that is an extension of Album; it will define a new method that returns a data structure which can be used easily with UITableViews.

To add a Category to Album, navigate to File\New\File… and select the Objective-C category template — don’t select the Objective-C class out of habit! Enter Table Representation in the Category field and Album in theCategory on field.

Go to Album+TableRepresentation.h and add the following method prototype:

Please notice there’s a tr_ at the beginning of the method name, as an abbreviation of category name: Table Representation. Again, conventions like this will help prevent collisions with other methods!

Go to Album+TableRepresentation.m and add the following method:

Consider for a moment how powerful this pattern can be:

  • We are using properties directly from Album.
  • We have added to the Album class but we haven’t subclassed it. If we need to sub-class Album, we can do it.
  • This simple addition lets us return a UITableView-ish representation of an Album, without modifying Album‘s code.

Apple uses a lot of Categories in the Foundation classes. To observe the process, open NSString.h. Find @interface NSString, and we’ll see the definition of the class together with three categories: NSStringExtensionMethods, NSExtendedStringPropertyListParsing and NSStringDeprecated. These categories help to keep the methods organized and separated into sections.

How to use Delegation pattern:

When we use a UITableView, one of the methods we must implement is tableView: numberOfRowsInSection.
As UITableView  is application-specific, we have to specify how many rows we want to have in each section. Therefore, the task of calculating the amount of rows in each section is passed on to the UITableViewdelegate. This allows the UITableView class to be independent of the data it displays.

Here’s a pseudo-explanation of what’s going on when we create a new UITableView:

  • Step 1: Go to ViewController.m and add the following imports to the top of the file:
  • Step 2: Add these private variables to the class extension so that the class extension looks like this:
  • Step 3: Replace the @interface line in the class extension with this one:
  • Step 4: Replace viewDidLoad: with this code:
  • Step 5: Change the background color to a nice navy blue color.
  • Step 6: Get a list of all the albums via the API. We should not use PersistencyManager directly.
  • Step 7: This is where we create the UITableView. We have to declare that the view controller is the UITableView delegate/data source; therefore, all the information required by UITableView will be provided by the view controller.
  • Step 8: Add the following method to ViewController.m:
  • Step 9: Add the following line to the end of viewDidLoad
  • This loads the current album at app launch. Since currentAlbumIndex was previously set to 0, this shows the first album in the collection.Build and run the project; we’ll experience a crash with the following exception displayed in the debug console:

Exception

  • Step 10: Add the following code to ViewController.m anywhere between the @implementation and @end lines:
  • Step 11: Build and run the project. The app should start and present us with the following screen:

carrier

Conclusion

This has been a dense concept. However, from the discussion of the iOS design patterns we should understand that this delegation of event handling and of populating data into the UI from the view to a controller class makes sense inside the confines of the pattern. The availability of these features in Objective-C is one of the reasons why the MVC pattern has been widely adopted.

Reference

3451 Views 1 Views Today