Every application may keep some images in its resources, such as textures or icons. In this recipe, we'll study how one can add an image to resources, load it into the UIImage
object, and then display it on the screen. We will use the UIImageView
component for that purpose, and get familiar with the important Model-View-Controller (MVC) design pattern.
Source code for this recipe is available in the Recipe02_DisplayingImage
folder in the code bundle that accompanies this book. You can also take your own image with the preferred 320 x 480 resolution. Or, you can use the provided lena.png
image, based on the famous picture among computer vision engineers (http://lenna.org). You can use iOS Simulator to work on this recipe.
The following are the steps required to display an image:
Add an image to the project's resources.
Add
UIImageView
component to the View.Add image loading code.
Display an image on the screen.
Let's implement the described steps:
For this example, you can use the Xcode project created in the previous recipe. We'll start by adding an image to the project. For that purpose, you should use the Add files to ... context menu from the Project Navigator Area. In the opened window, you should select the image and click on the Add button. The filename should appear in the Supporting Files group of the Project Navigator Area.
Next, we'll add the
UIImageView
component to our View. For that purpose, you have to open the storyboard file corresponding to your device in the Project Navigator Area. Initially it looks like a blank panel. You should find the Image View component in the Objects list located in the bottom-right corner of the Xcode window and drag it to the View. In the following screenshot, you can see the Objects list in storyboard editor:We now have the View for displaying images, but it doesn't have any code-behind. In order to add some logic, we should first add a special variable to our Controller class. In order to do that, change the interface of the
ViewController
class in theViewController.h
file as follows:@interface ViewController : UIViewController { UIImage* image; } @property (nonatomic, weak) IBOutlet UIImageView* imageView; @end
Then we should connect the newly created property and the visual component on our View. Open storyboard again and turn on the Assistant Editor mode by navigating to View | Assistant Editor | Show Assistant Editor. After that, the main Xcode window will be split into two parts. On one side you can find the
ViewController.h
file, and the storyboard will be shown on the other side. Connect theimageView
property with theUIImageView
component, as shown in the following screenshot:Now it's time to add some code to the Controller's implementation file. If you use your own image, please change the filename accordingly, as shown in the following code snippet:
#import "ViewController.h" @interface ViewController () @end @implementation ViewController @synthesize imageView; - (void)viewDidLoad { [super viewDidLoad]; // Read the image image = [UIImage imageNamed:@"lena.png"]; if (image != nil) imageView.image = image; // Displaying the image }
That's all; you can now run your application by clicking on the Run button.
In this recipe we have implemented our first GUI on iOS. We'll now discuss some basic concepts related to GUI development. The most important idea is using Model-View-Controller design pattern, which separates visual representation, user interaction logic, and the core logic of the application. There are three parts in this pattern:
Model: This contains business logic, such as data and algorithms for data processing. It does not know how this information should be presented to the user.
View: This is responsible for visualization. It can be imagined as some GUI form with visual components on it (for example, buttons, labels, and so on).
Controller: This provides communication between the user and the system core. It monitors the user's input and uses Model and a View to implement the necessary response.
Usually, applications have several Views with some rules to switch between them. Also, simple programs usually contain only two parts of the pattern: View and Controller, because logic is very simple, and developers do not create a separate entity for the Model.
A View is created as a storyboard element. The file with the *.storyboard
extension allows you to describe an interface of your application with all internal elements. Xcode contains a special graphical tool to add visual controls and change their parameters. So, all that you need is to fill your View with the needed GUI components using drag-and-drop.
Note
All our examples are based on the storyboards mechanism that was introduced in iOS 5. It is a great intuitive way to describe all interactions between visual components of your application. If you want to support devices with the iOS version older than 5, you should use .xib
files to describe the application interface.
When you create a new project, Xcode adds two storyboards for different device families (MainStoryboard_iPhone.storyboard
and MainStoryboard_iPad.storyboard
). Of course, you can use a single storyboard for all devices. For this purpose, you should change value of the Main Storyboard property in Deployment Settings of the project. But tablets and smartphones differ much in screen resolutions, so it is highly recommended to create separate Views with different layouts for both families.
For each View, you should normally have a Controller. For every new project, Xcode creates a ViewController
class by default (ViewController.h
and ViewController.m
files). In our example, we first add the IBOutlet
property to the interface declaration of our View. IBOutlet
is a special macro to denote a variable that can be attached to some visual component on the View. IBOutlet
resolves to nothing, but it makes clear to Xcode that such variables can be linked with UI elements.
In our implementation, we use the @property
keyword. By default, if we add some variable to the Controller's interface (as well as to any other interface), it will be private, so we can't access it out of the class. If we want to do it, we can use the @property
keyword. It is somewhat added as an instance variable, but it requires you to implement getter and setter methods. In our example, we do it by calling another special @synthesize
keyword. It automatically generates getter and setter methods for your variable.
In this recipe, we add some code to the viewDidLoad
method of the ViewController
class. This method is a good place to show our image, because it is called after the ViewController
has been loaded. You may have noticed that this method already had the following line:
[super viewDidLoad];
It is just a call of the viewDidLoad
method implemented in the superclass. Here we use UIImage
object to load an image from the file. UIImage
is a high-level class to store and display image data. It is similar to cv::Mat
class as an image container, but can't be used for mathematical computations.
To display the image on the View, we just need to assign the variable with the loaded image to the imageView.image
property.
You have the possibility to implement getters and setters manually:
-(UIImageView*)imageView { return imageView1; } -(void)setImageView:(UIImageView*)newImageView { if (newImageView != imageView1) { imageView1 = newImageView; } }
In this recipe, we get familiar with one of the most important Cocoa design patterns—Model-View-Controller. But there are other important patterns that you should know to design your applications properly. We encourage you to study the Cocoa Fundamentals Guide (http://bit.ly/3848_CocoaFundamentalsGuide) and the Cocoa Design Patterns article in particular (http://bit.ly/3848_CocoaDesignPatterns).