MOBILE

iPhone Application Development : Using Switches, Segmented Controls, and Web Views (part 3)

2/4/2011 4:41:46 PM

Finishing the Interface

The only functional piece that is missing from our interface is a button (UIButton) that we can use to manually trigger the getFlower method anytime we want. Without the button, we’d have to switch between colors using the segmented control if we wanted to see a new flower image. This button does nothing more than trigger an action (getFlower), something you’ve done repeatedly in the past few hours, so this should be a walk in the park for you by now.

Drag a button into the view, positioning it in the center of the screen above the web views. Edit the button title to read Get New Photo.

Finally, select the button and open the Connections Inspector (Command+2). Drag from the Touch Up Inside event to the File’s Owner icon in the Document window. When prompted choose the getFlower action, as shown in Figure 13.

Figure 13. Connect the Get New Photo button’s Touch Up Inside event to the getFlower action.

Did you Know?

Although your interface may be functionally complete, you may want to select the view itself and set a background color. Keep your interfaces clean and friendly!


The interface, shown in Figure 14, is complete! Switch back to Xcode and let’s get coding!

Figure 14. The finished interface of the FlowerWeb application.


Implementing the View Controller Logic

There are two pieces of functionality that our view controller needs to implement via two action methods. The first, toggleFlowerDetail, will show and hide the flowerDetailView web view depending on whether the switch has been flipped on (show) or off (hide). The second method, getFlower, will load a flower image into the flowerView web view and details on that photograph into the flowerDetailView web view. We’ll start with the easier of the two, toggleFlowerDetail.

Hiding and Showing the Detail Web View

A useful property of any object that inherits from UIView is that you can easily hide (or show) it within your iPhone application interfaces. Because almost everything you see onscreen inherits from this class, this means you can hide and show labels, buttons, fields, images, and yes, other views. To hide an object, all we need to do is set its Boolean property hidden to TRUE or YES (both have the same meaning). So, to hide the flowerDetailView, we write the following:

flowerDetailView.hidden=YES;

To show it again, we just reverse the process, setting the hidden property to FALSE or NO:

flowerDetailView.hidden=NO;

To implement the logic for the toggleFlowerDetail: method, we need to figure out what value the switch is currently set to. As mentioned earlier in the lesson, we can check the state of a toggle switch through the isOn method that returns a Boolean value of TRUE/YES if the switch is set to on or FALSE/NO if it is off.

Because we don’t have an outlet specifically set aside for the switch, we’ll use the sender variable to access it in our method. When the toggleFlowerDetail action method is called, this variable is set to reference the object that invoked the action (in other words, the switch). So, to check to see whether the switch is on, we can write the following:

If ([sender isOn]) { <switch is on> } else { <switch is off> }

Now, here’s where we can get clever (you’re feeling clever, right?). We want to hide and show the flowerDetailView using a Boolean value and we get a Boolean value from the switch’s isOn method. This maps to two conditions:

  • When [sender isOn] is YES, the view should not be hidden (flowerDetailView.hidden=NO)

  • When [sender isOn] is NO, the view should be hidden (flowerDetailView.hidden=YES)

In other words, the state of the switch is the exact opposite of what we need to assign to the hidden property of the view. In C (and therefore Objective-C), to get the opposite of a Boolean value, we just put an exclamation mark in front (!). So all we need to do to hide or show flowerDetailView is to set the hidden property to ![sender isOn]. That’s it! A single line of code!

Implement toggleFlowerDetail: in FlowerWeb right after the @synthesize directives. The full method should look a lot like this:

-(IBAction)toggleFlowerDetail:(id)sender{
flowerDetailView.hidden=![sender isOn];
}

Loading and Displaying the Flower Image and Details

To fetch our flower images, we’ll be making use of a feature provided by the Flora Photographs website for specifically this purpose. We’ll be following four steps to interact with the website:

1.
We’ll get the chosen color from the segmented control.

2.
We will generate a random number called a session ID so that floraphotographs.com can track our request.

3.
We will request the URL http://www.floraphotographs.com/showrandomiphone.php?color=<color>&session=<session ID>, where <color> is the chosen color and <session ID> is the random number. This URL will return a flower photo.

4.
We will request the URL http://www.floraphotographs.com/detailiphone.php?session=<session ID>, where <session ID> is the same random number. This URL will return the details for the previously requested flower photo.

Let’s go ahead and see what this looks like in code, and then discuss details behind the implementation. Add the getFlower code block, shown in Listing 2, following the toggleFlowerDetail method that you implemented.

Listing 2.
 1: -(IBAction)getFlower:(id)sender {
2: NSURL *imageURL;
3: NSURL *detailURL;
4: NSString *imageURLString;
5: NSString *detailURLString;
6: NSString *color;
7: int sessionID;
8:
9: color=[colorChoice titleForSegmentAtIndex:
10: colorChoice.selectedSegmentIndex];
11: sessionID=random()%10000;
12:
13: imageURLString=[[NSString alloc] initWithFormat:
14: @"http://www.floraphotographs.com/showrandomiphone.php?color=%@&session=%d"
15: ,color,sessionID];
16: detailURLString=[[NSString alloc] initWithFormat:
17: @"http://www.floraphotographs.com/detailiphone.php?session=%d"
18: ,sessionID];
19:
20: imageURL=[[NSURL alloc] initWithString:imageURLString];
21: detailURL=[[NSURL alloc] initWithString:detailURLString];
22:
23: [flowerView loadRequest:[NSURLRequest requestWithURL:imageURL]];
24: [flowerDetailView loadRequest:[NSURLRequest requestWithURL:detailURL]];
25:
26: flowerDetailView.backgroundColor=[UIColor clearColor];
27:
28: [imageURLString release];
29: [detailURLString release];
30: [imageURL release];
31: [detailURL release];
32: }


This is the most complicated code that you’ve written so far, but it’s broken down into the individual pieces, so it’s not difficult to understand:

Lines 2–7 declare the variables that we need to prepare our requests to the website. The first variables, imageURL and detailURL, are instances of NSURL that will contain the URLs that will be loaded into the flowerView and flowerDetailView web views. To create the NSURL objects, we need two strings, imageURLStringdetailURLString, and which we’ll format with the special URLs that we presented earlier, including the color and sessionID values.

In lines 9–10, we retrieve the title of the selected segment in our instance of the segmented control: colorChoice. To do this, we use the object’s instance method titleForSegmentAtIndex along with the object’s selectedSegmentIndex property. The result, [colorChoice titleForSegmentAtIndex: colorChoice.selected SegmentIndex], is stored in the string color and is ready to be used in the web request.

Line 11 generates a random number between 0 and 9999 and stores it in the integer sessionID.

Lines 13–18 prepare imageURLString and detailURLString with the URLs that we will be requesting. The strings are allocated, and then the initWithFormat method is used to store the website address along with the color and session ID. The color and session ID are substituted into the string using the formatting placeholders %@%d for strings and integers, respectively. and

Lines 20–21 allocate and create the imageURL and detailURL NSURL objects using the initWithString class method and the two strings imageURLString and detailURLString.

Lines 23–24 use the loadRequest method of the flowerView and flowerDetailView web views to load the NSURLs imageURL and detailURL, respectively. When these lines are executed, the display updates the contents of the two views.

By the Way

Although we mentioned this earlier, remember that UIWebView’s loadRequest method doesn’t handle NSURL objects directly; it expects an NSURLRequest object instead. To work around this, we create and return NSURLRequest objects using the NSURLRequest class method requestWithURL and the imageURL and detailURL objects as parameters.


Line 26 is an extra nicety that we’ve thrown in. This sets the background of the flowerDetailView web view to a special color called clearColor. This, combined with the alpha channel value that you set earlier, will give the appearance of a nice translucent overlay of the details over the main image. You can comment out or remove this line to see the difference it creates.

Did you Know?

To create web views that blend with the rest of your interface, you’ll want to keep clearColor in mind. By setting this color, you can make the background of your web pages translucent, meaning that the content displayed on the page will overlay any other content that you’ve added to your iPhone view.


Finally, Lines 28–31 release all the objects that we’ve allocated in the method. Because getFlower will potentially be called over and over, it’s important that we release any memory that we might be using!

Fixing Up the Interface When the App Loads

Now that the getFlower method is implemented, you can run the application and everything should work—except that when the application starts, the two web views will be empty and the detail view will be visible, even though the toggle switch is set to off.

To fix this, we can start loading an image as soon as the app is up and running and set flowerDetailView.hidden to YES. Uncomment the viewDidLoad method and implement it as follows:

- (void)viewDidLoad {
flowerDetailView.hidden=YES;
[self getFlower:nil];
[super viewDidLoad];
}

As expected, flowerDetailView.hidden=YES will hide the detail view. Using [self getFlower:nil], we can call the getFlower: method from within our instance of the view control (referenced as self) and start the process of loading a flower in the web view. The method getFlower: expects a parameter, so we pass it nil. (This value is never used in getFlower:, however, so there is no problem with providing nil.)

Releasing the Objects

As always, we need to finish things up by releasing the objects that we’ve kept around. Edit the dealloc method to release the segmented control and two web views now:

- (void)dealloc {
[colorChoice release];
[flowerDetailView release];
[flowerView release];
[super dealloc];
}

Building the Application

Test out the final version of the FlowerWeb application by clicking Build and Run in Xcode.

Notice that you can zoom in and out of the web view, and use your fingers to scroll around. These are all features that you get without any implementation cost when using the UIWebView class.

Congratulations! Another app under your belt!

Other  
  •  iPhone Application Development : Using Advanced Interface Objects and Views - User Input and Output
  •  Windows Phone 7 Development : Wiring Up Events to an Application Bar ( part 2)
  •  Windows Phone 7 Development : Wiring Up Events to an Application Bar ( part 1) - Reacting to Add Button Events
  •  Adding an Application Bar to a Windows Phone 7 Application (part 3) - Adding an Application Bar Using Managed Code
  •  Adding an Application Bar to a Windows Phone 7 Application (part 2) - Adding a Local Application Bar Using XAML & Adding Menu Items
  •  Adding an Application Bar to a Windows Phone 7 Application (part 1) - Adding Images for Use with Application Bar Buttons & Adding a Global Application Bar Using XAML
  •  iPhone Application Development : Creating and Managing Image Animations and Sliders (part 3) - Finishing the Interface
  •  iPhone Application Development : Creating and Managing Image Animations and Sliders (part 2) - Adding an Image View
  •  iPhone Application Development : Creating and Managing Image Animations and Sliders (part 1)
  •  iPhone Application Development : User Input and Output
  •  Windows Phone 7 : Using Accelerometer Data to Move a Ball
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 4) - Device Libraries
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 3) - Transcoders
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 2) - Detecting the Context
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 1) - HTTP
  •  Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 2)
  •  Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 1)
  •  Using Windows Phone 7 Technologies : Understanding Orientation and Movement
  •  Programming the Mobile Web : HTML 5 (part 4) - Client Storage
  •  Programming the Mobile Web : HTML 5 (part 3) - Offline Operation
  •  
    Most View
    Galaxy S IV - Sketching A Portrait Of A Giant (Part 1)
    Linux vs Windows 8 (Part 4)
    Blackberry 10 OS (Part 2)
    Dell PowerEdge T320 - A Top Choice For SMBs
    Improve Your Mac (Part 10) - Add Video To Pages Projects
    Nokia Lumia 520 - Does Nokia Really Need Another Budget Windows Phone? (Part 1)
    Apple iPhone 5 vs. iPhone 4S
    New Products For May (Part 2)
    Create And Share Your First Photo Journal
    Samsung Galaxy Note 8.0 - Powerful Performance And Vivid Screen (Part 4)
    Top 10
    Watch Web TV Anywhere (Part 3)
    Watch Web TV Anywhere (Part 2)
    Watch Web TV Anywhere (Part 1)
    YouView brings The Most Extraordinary Way To Watch TV (Part 2)
    YouView brings The Most Extraordinary Way To Watch TV (Part 1)
    Samsung Glaxy Note 8.0 - An 8-Inch Android Tablet
    SQL Server 2008 : Policy-based management - Advanced policy-based management
    SQL Server 2008 : Policy-based management - Enterprise policy management
    Windows 8 : Managing Application Virtualization and Run Levels (part 2) - Setting Run Levels, Optimizing Virtualization and Installation Prompting for Elevation
    Windows 8 : Managing Application Virtualization and Run Levels (part 1) - Application Access Tokens and Location Virtualization, Application Integrity and Run Levels