12. Slideshow App

Photos and iPod Library Access

image

12.1 Introduction

The Slideshow app allows the user to create and manage slideshows using pictures and music from the iPhone photo album and iPod library. Each slideshow’s title and first image are displayed in a table (Fig. 12.1). This app does not save slideshows when the app is closed—we add this capability in the next chapter’s Enhanced Slideshow app. Touching the “PlayButton next to a slideshow plays that slideshow (Fig. 12.2(a)). Rotating the iPhone horizontally while the slideshow is playing displays its images in landscape orientation (Fig. 12.2(b)). Each of the images displays for five seconds, while a user-chosen song from the iPod library plays in the background. The images transition either by fading or by sliding to the left, as specified by the user when creating the slideshow. Touching the “EditButton in the top-left corner of the app displays Deletion Control Buttons (image) next to each of the slideshows (Fig. 12.3 (a)). Touching one of these displays a “DeleteButton next to the selected slideshow (Fig. 12.3 (b)) that allows the user to remove that slideshow. The user touches the “NewButton to create a new slideshow.

Fig. 12.1 | List of saved slideshows.

image

Fig. 12.2 | Slideshow playing in portrait and landcape orientations.

image

Fig. 12.3 | Editing the list of slideshows.

image

Touching the “NewButton in the top-right corner of the app displays a Text Field requesting a name for the new slideshow (Fig. 12.4 (a)). The Edit Slideshow screen (Fig. 12.4 (b)) allows the user to add pictures, music and effects to the slideshow. Touching the “Add PictureButton in the bottom-left corner of the app displays the iPhone’s photo library (Fig. 12.5).

Fig. 12.4 | Creating a new slideshow.

image

Fig. 12.5 | Photo library.

image

Touching any of the albums displays the pictures in the album (Fig. 12.6 (a)). The user touches a picture to see a larger version of it. Touching the “ChooseButton adds that photo to the slideshow (Fig. 12.6 (b)).

Fig. 12.6 | Picking a photo.

image

12.2 Test-Driving the Slideshow App

Opening the Completed App

Open the directory containing the Slideshow app project. Double click Slideshow.xcodeproj to open the project in Xcode.

Adding a New Slideshow

Touch the “NewButton at the top of the app to view the Edit Slideshow screen. Touch the “Add PictureButton to view the iPhone’s (or simulator’s) photo library. If you’re using the simulator, touch Saved Photos; otherwise, touch one of your personal photo folders. Touch any one of the photos to see a larger view of that photo and touch the “ChooseButton to add the picture to the slideshow and return to the Edit Slideshow screen. Touching the “CancelButton here returns you to the previous screen without adding the photo. Add two more images to this slideshow. Touch the reordering control (image) next to the top picture and drag that picture to the bottom of the list so it’s the last image displayed in this slideshow. Now touch the Deletion Control Button (image) next to the top picture then touch the “DeleteButton to remove that picture from this slideshow.

Touch the “Add EffectButton and choose Slide. This will cause the slideshow to transition between images by sliding them to the left. If you’re using an actual iPhone to test this app, touch the “Add MusicButton to view your iPod music library—this feature is not supported by the simulator. Select one or more of your songs to add them to the slideshow as background music. If your slideshow contains enough pictures, the slideshow will play the list of songs in the order you selected them; otherwise, the slideshow will likely end before the first song completes. Touch the “BackButton in the top-left corner of the app to return to the list of slideshows.

Playing a Slideshow

Touch the “PlayButton next to your slideshow to play it. The images you added are displayed on the screen, sliding to the left when each new image transitions into view. Your chosen songs play in the background. Rotate the iPhone horizontally to view the slideshow in portrait mode. You can do this in the simulator by selecting Hardware > Rotate Left or Hardware > Rotate Right in the iPhone simulator.

Editing and Deleting a Slideshow

Touch the “ModifyButton next to your slideshow to return to the Edit Slideshow screen. Touch the “Add EffectButton and choose Fade. You can add or delete photos as you did previously. If you choose different songs, the original song list is replaced. Return to the list of slideshows and play your slideshow again. The images now transition by fading from view instead of sliding off the screen.

Once the slideshow finishes, touch the “EditButton in the top-left corner of the app. Touch the Deletion Control Button (image) next to your slideshow then touch the “DeleteButton to erase your slideshow from the app.

12.3 Technologies Overview

The app’s list of slideshows is displayed in a UITableView containing custom UITableViewCells in which we add "Play" and "Modify" Buttons. The Edit Slideshow screen uses a UITableView with standard UITableViewCells to display the images in a selected slideshow. We’ll use a UINavigationController with a UIToolbar to allow the user to navigate between the app’s screens. UIBarButtonItems are used to switch between views and to delete images and slideshows.

The Photo API contains image pickers that provide a user interface for choosing photos from the iPhone’s photo library. We create a UIImagePickerController to allow the user to add photos from the photo library to the slideshow. We use MPMediaPickerController to control a similar built-in interface that allows the user to choose the slideshow’s background music from their iPod library. We store songs chosen from the iPod music library in an MPMediaItemCollection. An MPMusicPlayerController is used to play the selected song.

The user selects between different image transitions for a slideshow using a UIActionSheet. This displays a screen displaying several Buttons describing different image transitions. Each of these buttons corresponds to a member of the transitions enum which is used to define the different transition styles our app supports.

12.4 Building the App

The RootViewController controls the view displaying the list of created slideshows. Users can play, modify and delete existing slideshows from this view. The SlideshowViewController controls the view used to play slideshows. New slideshows are named using the view controlled by the NameViewController, which provides a Text Field in which the user can specify the slideshow name. The user can add images, effects and music to a slideshow in the view controlled by the SlideshowDataViewController.

12.4.1 Class RootViewController

Class RootViewController (Fig. 12.7) is a subclass of UITableViewController and implements the SlideshowCellDelegate (Fig. 12.15) and NameViewControllerDelegate (Fig. 12.24) protocols (lines 10–11). The NSMutableArray variable slideshows (line 13) will store the user’s slideshows. The addSlideshow method (line 16) displays the naming view, which allows the user to enter a title for a new slideshow. After being named, the slideshow is displayed in RootViewController’s list of slideshows.

Fig. 12.7 | RootViewController class controls the main list of slideshows.

image

Method viewDidLoad of Class RootViewController

The viewDidLoad method (Fig. 12.8) is called after the RootViewController’s view is initialized. Lines 10–11 call the superclass’s viewDidLoad method and initialize the slideshows NSMutableArray. Line 12 calls RootViewController’s navigationItem property’s setTitle method to display Slideshows at the top of the app.

Fig. 12.8 | Methods viewDidLoad of class RootViewController.

image

Lines 15–17 create a new UIBarButtonItem titled New, which calls the addSlideshow method when touched. This allows the user to create a new slideshow. Lines 20–22 create a UIBarButtonItem titled Back, which is added to the navigation bar when the user leaves the RootViewController, so the user can return to this view. We then add the “NewButton to the right side of the navigation bar (line 25). Line 26 adds RootViewController’s editButtonItem property to the left side of the navigation bar. This is the “EditButton used to delete slideshows. Line 29 passes backButton to UINavigationItem’s setBackBarButtonItem: method to specify that backButton should appear when the user navigates to a different view.

Methods viewWillAppear: and addSlideshow of Class RootViewController

The viewWillAppear: method (Fig. 12.9, lines 36–43) is called each time the app displays the RootViewController’s view. Line 38 calls the superclass’s viewWillAppear: method. We then get RootViewController’s UINavigationController and use its setNavigationBarHidden:animated: method to display the navigation bar (line 41). Line 42 calls UITableView’s reloadData method to update RootViewController’s table to any changes made in another view.

Fig. 12.9 | Method viewWillAppear: and addSlideshow of class RootViewController.

image

The addSlideshow method (lines 46–55) displays the NameViewController when the user touches the “NewButton. Lines 49–51 create a new NameViewController and set its delegate to self. We call UIViewController’s presentModalViewController:animated: method to display the NameViewController (line 54).

Methods nameViewController:didGetName: and tableView:numberOfRowsInSection: of Class RootViewController

The nameViewController:didGetName: method (Fig. 12.10, lines 58–73) is declared in the NameViewDelegate protocol (Fig. 12.24) and is called when the user finishes entering a name for a new slideshow. UIViewController’s dismissModalViewControllerAnimated: method hides the NameViewController’s view (line 62). Lines 65–67 create a new SlideshowDataViewController and add it to slideshows using NSMutableArray’s addObject: method. We then set the new slideshow’s title property to the given name. Line 71 calls UINavigationController’s pushViewController:animated: method to show the SlideshowDataView for the new slideshow. The tableView:numberOfRowsInSection: method (lines 76–80) specifies that RootViewController’s UITableView’s only section has as many rows as there are slideshows.

Fig. 12.10 | RootViewController methods nameViewController:didGetName:, and tableView:numberOfRowsInSection:.

image

Method tableView:cellForRowAtIndexPath: of Class RootViewController

The tableView:cellForRowAtIndexPath: method (Fig. 12.11) retrieves the UITableViewCell specified by the given NSIndexPath. Lines 87–100 attempt to reuse a UITableViewCell from the given tableView using UITableView’s dequeReusableCellWithIdentifier: method. We set the new SlideshowCell’s delegate to this RootViewController (line 103). Line 105 sets the UITableViewCell’s selectionStyle property to UITableViewCallSelectionStyleNone to indicated that no action is taken when the UITableViewCell is touched. Lines 108–109 get the SlideshowDataViewController corresponding to the touched UITableViewCell. Line 112 calls the SlideshowDataViewController’s firstImage method to get a UIImage representing the first picture in the selected slideshow. Lines 113–114 set the SlideshowCell’s thumbnail to that UIImage and title to the SlideshowDataViewController’s title.

Fig. 12.11 | Method tableView:cellForRowAtIndexPath: of class RootViewController.

image

Methods slideshowCellDidSelectEditButton: and slideshowCellDidSelectPlayButton: of Class RootViewController

The slideshowCellDidSelectEditButton: method (Fig. 12.12, lines 120–126) is declared by the SlideshowCellDelegate protocol and displays the SlideshowDataViewController’s view for the touched slideshow. This allows the user to edit the selected slideshow.

Fig. 12.12 | Methods slideshowCellDidSelectEditButton: and slideshowCellDidSelectPlayButton: of class RootViewController.

image

The slideshowCellDidSelectPlayButton: method (lines 129–150) plays a slideshow when the user touches its “PlayButton. Lines 132–136 get the SlideshowDataViewController at the UITableViewCell selected by the given NSIndexPath. We then create a new SlideshowViewController to play the selected slideshow (lines 139–140). Lines 141–143 set the SlideshowViewController’s pictures, effect and music to those of the selected slideshow. We hide the navigation bar then call UINavigationController’s pushViewController:animated: method to display the slideshow (lines 146–149).

MethodtableView:commitEditingStyle:forRowAtIndexPath: of Class RootViewController

Method tableView:commitEditingStyle:forRowAtIndexPath: (Fig. 12.13) specifies that RootViewController’s UITableViewCells support editing. This allows the user to delete slideshows.

Fig. 12.13 | Method tableView:commitEditingStyle:forRowAtIndexPath: of class RootViewController.

image

Methods tableView:moveRowAtIndexPath:toIndexPath: and tableView:canMoveRowAtIndexPath: of Class RootViewController

The tableView:moveAtIndexPath:toIndexPath: method (Fig. 12.14, lines 170–183) is called when the user moves a row in RootViewController’s UITableView by dragging a UITableViewCell’s reordering control (image). Lines 174–178 get the SlideshowDataViewController for the row being dragged and remove it from slideshows using NSMutableArray’s removeObjectAtIndex: method. The fromIndexPath NSIndexPath specifies the UITableViewCell being dragged. Line 181 inserts the SlideshowDataViewController back in slideshows at the index to which the UITableViewCell was dragged. The toIndexPath NSIndexPath specifies the end location of the dragged UITableViewCell. Method tableView:canMoveRowAtIndexPath: (lines 186–190) always returns YES in this example to indicate that the user can move all of the UITableViewCells.

Fig. 12.14 | Methods tableView:moveRowAtIndexPath:toIndexPath: and tableView:canMoveRowAtIndexPath: of class RootViewController.

image

SlideshowCell Interface Declaration

The SlideshowCell class (Fig. 12.15) extends UITableViewCell to display a slideshow title, and “Play” and “ModifyButtons. Lines 11–13 declare this class’s delegate and other instance variables. We declare each of SlideshowCell’s instance variables as properties (lines 17–19). The editSlideshow method (line 21) informs the delegate that the SlideshowCell’s “EditButton was touched. The playSlideshow method (line 22) informs the delegate that the SlideshowCell’s "Play" Button was touched. The SlideshowCellDelegate protocol (lines 26–33) defines two methods used to inform the delegate that SlideshowCell’s Buttons were touched.

Fig. 12.15 | UITableViewCell for previewing a slideshow.

image

Method initWithFrame:reuseIdentifier: of Class SlideshowCell

The initWithFrame:reuseIdentifier: method (Fig. 12.16) initializes the SlideshowCell. Lines 19–20 create a new UIImageView on the left side of the SlideshowCell. This is used to show a thumbnail of the first image of the slideshow. Line 23 expands the thumbnail to fit the height of the SlideshowCell. Lines 26–27 create a new Label which we user later to title the slideshow. Lines 30–55 create UIButtons editButton and playButton. Touching the editButton calls SlideshowCell’s editSlideshow method. Touching the playButton calls the playSlideshow method. We then call UIView’s addSubview method to add the thumbnail image, title and Buttons to this SlideshowCell’s contentView to display them on the UITableViewCell (lines 58–61).

Fig. 12.16 | SlideshowCell method initWithFrame:reuseIdentifier:.

image

image

Methods editSlideshow and playSlideShow of Class SlideshowCell

The editSlideshow method (Fig. 12.17, lines 68–72) calls the delegate’s slideshowCellDidSelectEditButton: method (line 71). This displays the selected slideshow’s SlideshowDataViewController so the user can edit that slideshow. The playSlideshow method (Fig. 12.17, lines 75–79) calls the delegate’s slideshowCellDidSelectPlayButton: method to play the selected slideshow.

Fig. 12.17 | Methods editSlideshow and playSlideShow of class SlideshowCell.

image

12.4.2 Class SlideshowViewController

The SlideshowViewController’s View plays a slideshow in full screen mode. The slideshow re-orients as the user rotates the iPhone.

SlideshowViewController Interface Declaration

The SlideshowViewController class (Fig. 12.18) controls a view that displays a usercreated slideshow. Lines 7–11 create an enum type containing a set of integer symbolic constants. Values in an enum start with 0 and increment by 1 by default, so the constant TransitionEffectFade has the value 0 and TransitionEffectSlide has the value 1. The identifiers in an enumeration must be unique, but the values may be duplicated. To provide a specific value for a constant, assign the value to the enum constant in the enum declaration. Line 16 declares a TransitionEffect variable effect. If the user chooses Fade as this slideshow’s effect, the effect variable is set to TransitionEffectFade. Choosing the Slide effect sets the variable effect to TransitionEffectSlide.

Fig. 12.18 | Controller for a View that shows a slideshow.

image

Line 17 declares an MPMediaItemCollection used to store the background music for this slideshow. We declare an MPMusicPlayerController to play music from the iPod library (line 18). Lines 19–21 declare SlideshowViewController’s remaining instance variables.

Lines 25–27 declare the NSMutableArray, TransitionEffect and MPMediaItemCollection as properties. The SlideshowViewController class declares three methods (lines 29–31):

nextImageView—returns the new UIImage displayed in the current slideshow

exitShow—returns the app to the RootView

timerFired:—changes the slideshow’s image every five seconds; if there are no slides left, this method calls exitShow

Lines 35–39 add the Scaling category to class UIImageView. The category’s expandToFill: method scales a UIImageView to fill the given CGRect.

Methods loadView and nextImageView of Class SlideshowViewController

The loadView method (Fig. 12.19, lines 12–18) initializes the SlideshowView (line 14). We set the UIView’s frame property makes the slideshowView fill the entire screen (line 17).

Fig. 12.19 | Methods loadView and nextImageView of class SlideshowViewController.

image

image

Method nextImageView (lines 21–46) returns a UIImageView displaying the slideshow’s next image. We retrieve the next UIImage from pictures (line 24), then increment pictureIndex (line 25). Line 28 creates a new UIImageView using the retrieved UIImage. We access SlideshowViewController’s UIView’s bounds property to get a CGRect representing the screen’s bounds (line 30). We pass this CGRect to imageView’s expandToFill: method to resize our Image View to fill the entire screen. This method expands the image as much as possible without distorting it. Line 36 centers the UIImageView in the screen.

SlideshowViewController’s autoresizingMask property (inherited from UIView) defines how the UIView resizes its subviews when the UIView’s bounds change. This occurs in this app when the user rotates the iPhone while a slideshow is playing. The autoresizingMask property is an integer containing bit flags so we set it by combining all desired options using the bitwise OR operator (|). Lines 40–43 specify that SlideshowViewController’s UIImageView remains centered as the iPhone rotates.

Methods exitShow and timerFired of Class SlideshowViewController

The exitShow method (Fig. 12.20, lines 49–58) stops the background music by calling AVAudioPlayer’s stop method (line 51). We call UIApplication’s sharedApplication method to get the singleton UIApplication for this app (line 54). UIApplication’s setStatusBarHidden method is called to redisplay the status bar, which we hid when the slideshow began playing. The status bar normally appears at the top of the app and displays the iPhone’s remaining battery life, service provider (e.g. AT&T) and current time among other things. Line 57 calls UINavigationController’s popViewControllerAnimated: method to return to the previous view.

Fig. 12.20 | Methods exitShow and timerFired of class SlideshowViewController.

image

image

The timerFired: method (lines 61–119) displays the next slideshow image every five seconds. If there are no more images in the slideshow (line 64), we call the exitShow method to end the current slideshow (line 66). Otherwise, we call the nextImageView method to get a UIImageView representing the next picture in this slideshow (line 71). UIView’s addSubview: method is used to display the image (line 72).

The image is added to the screen using Core Animation according to the user’s chosen effect. If the effect is TransitionEffectFade, the UIImageView’s alpha property to set to 0.0, making the image transparent (lines 78–79). This allows us to fade in the image as the old image is faded out. If the effect is TransitionEffectSlide, we position the UIImageView to the right of the screen (lines 81–86). This allows us to slide the image in from the right edge of the screen. Lines 91–93 begin a Core Animation block defining an animation lasting two seconds. Lines 96–97 specify that the transitionFinished:finished:context: method is called when the animation ends.

We then set the final state of the image according to the chosen effect. If the effect is TransitionEffectFade the new UIImageView will have full opacity and the old UIImageView will be transparent (lines 101–102). If the effect is TransitionEffectSlide, we place the new UIImageView in the center of the screen (lines 106–109) and move the old UIImageView off the left side of the screen (lines 112–113). Line 117 calls UIView’s commitAnimations method to animate the UIImageView’s to their final state.

Methods transitionFinished:finished:context:, viewWillAppear and viewDidDisappear of Class SlideshowViewController

The transitionFinished:finished:context: method (Fig. 12.21, lines 122–128) is called when the image transition animation completes. Line 125 calls UIImageView’s removeFromSuperview method to remove the old image. We release the previous UIImageView’s memory and set currentImageView to the new image (lines 126–127).

Fig. 12.21 | Methods transitionFinished:finished:context:, viewWillAppear and viewDidDisappear of class SlideshowViewController.

image

image

The viewWillAppear method (lines 131–158) is called when the app transitions to the SlideshowViewController’s view. Lines 136–137 use UIView’s addSubview: method to display the first image in the slideshow. UIApplication’s setStatusBarHidden: method is used to hide the iPhone status bar so the slideshow fills the entire screen. Lines 143–144 initialize our NSTimer to call the timerFired: method every five seconds.

If the user selected background music for this slideshow (line 147), we use an MPMusicPlayerController to play those files. Line 150 calls MPMusicPlayerController’s applicationMusicPlayer method to get the app’s singleton MPMusicPlayerController object. We prevent the MPMusicPlayerController from shuffling the selected songs by setting its shuffleMode property to MPMusicShuffleModeOff (line 151). We prevent the MPMusicPlayerController from repeating songs by setting its repeatMode property to MPMusicShuffleModeNone (line 152). Line 155 passes music to MPMusicPlayer’s setQueueWithItemCollection: method so the MPMusicPlayer plays each song in music when the MPMusicPlayer’s play method is called in line 156.

Method viewDidDisappear: (lines 161–169) is called when the app transitions from the SlideshowViewController’s view back to that of the RootViewController or the SlideshowDataViewController—this depends on where the user began playing the slideshow. We call the superclass’s viewDidDisappear method (line 163) then use NSTimer’s invalidate method to stop timer and release it (line 166). Line 168 calls UIImageView’s removeFromSuperView method to remove the current image; otherwise, the next time the user plays a slideshow, the previous slideshow’s last image will still be displayed.

Methods shouldAutorotateToInterfaceOrientation: and willRotateToInterfaceOrientation: of Class SlideshowViewController

The shouldAutorotateToInterfaceOrientation: method (Fig. 12.22, lines 172–176) returns YES indicating that the SlideshowViewController’s view can rotate to all possible iPhone orientations. Method willRotateToInterfaceOrientation:duration: (lines 179–189) is called when the user rotates the iPhone. Lines 184–185 create a new CGRect the same size as the screen. Line 188 calls imageView’s expandToFill: method to resize the slideshow image according to the screen’s new height and width.

Fig. 12.22 | Methods shouldAutorotateToInterfaceOrientation: and willRotateToInterfaceOrientation: of class SlideshowViewController.

image

Scaling Category of UIImageView

Method expandToFill: (Fig. 12.23, lines 202–237) expands a UIImageView to fill the given CGRect. Lines 204–205 get this UIImageView’s UIImage and frame. First, we check if the UIImage is bound by its height (lines 208–209). If it is, we expand its frame’s height to match the given CGRect’s height (line 212). We then calculate a new width to ensure the image is not distorted (lines 215–216). Lines 219–220 adjust the image’s origin so it remains centered. If the UIImage is bound by its width (line 222), we expand its frame’s height to match the given CGRect’s width (line 225). We then calculate a new height so the image is not distorted (lines 228–229). Lines 232–233 adjust the image’s origin so it remains centered.

Fig. 12.23 | Scaling category of UIImageView.

image

12.4.3 Class NameViewController

The NameViewController’s view is displayed when the user touches the “NewButton above the slideshow list. The user enters the name of the new slideshow into a Text Field.

NameViewController Interface Declaration

The NameViewController class (Fig. 12.24) extends UIViewController. Line 11 declares this class’s delegate and line 12 declares an outlet that responds to events from the Text Field used to name the slideshow. Lines 16–17 declare delegate and textField as properties. Method finishedNaming: is called when the user finishes naming a new slideshow. The NameViewControllerDelegate protocol declares the nameViewController:didGetName: method (lines 26–27), which passes the slideshow’s name to the delegate.

Fig. 12.24 | Controls a View for naming a slideshow.

image

NameViewController Class Implementation

Method ViewDidLoad (Fig. 12.25, lines 11–17) calls the superclass’s viewDidLoad method (line 13) then selects the Text Field by calling UITextField’s becomeFirstResponder method to display the keyboard. The finishedNaming: method (lines 20–24) passes the textField’s text property to the delegate’s nameViewController:didGetName: method. This gives the RootViewController the user-entered name for the new slideshow.

Fig. 12.25 | Implementation of NameViewController.

image

12.4.4 Class SlideshowDataViewController

The class SlideshowDataViewController controls the view where the user edits a slideshow. The view contains buttons for adding pictures, music and effects, and displays controls for deleting and reordering slides.

SlideshowDataViewController Interface Declaration

Create a new UIViewController subclass named SlideshowDataViewController. Its class declaration is shown in SlideshowDataViewController.h (Fig. 12.26).

Fig. 12.26 | Manages the pictures, sounds and effects of a slideshow.

image

Lines 10–12 declare the protocols that SlideshowDataViewController implements. We then declare a UIImagePickerController (line 14), which controls a view that prompts the user to choose a picture from the photo library. We also declare a MPMediaPickerController (line 15), which controls a view that prompts the user to pick music from the iPod music library. The music MPMediaItemCollection represents the songs the user chose using the MPMediaPickerController.

The SlideshowViewController (line 19) controls the view that displays the slideshow. Line 20 declares a UIActionSheet—a GUI component that prompts the user to choose between multiple options. We declare a UIToolbar (line 21), an NSMutableArray to hold the chosen pictures (line 22), a TransitionEffect to store the transition effect (line 23) and an NSString to store the slideshow’s title (line 24). We also declare two BOOLs (lines 25–26) that store whether this is the first time the view is appearing and whether the app is returning from picking an image. The SlideshowDataViewController interface declares five methods:

addPhoto—prompts the user to add a new photo to the slideshow

addMusic—prompts the user to choose music to play during the slideshow

addEffect—displays the choices for the slideshow’s transition effect

startSlideshow—begins playing the slideshow

firstImage—returns the first image in the slideshow

Method viewDidLoad of Class SlideshowDataViewController

SlideshowDataViewController’s class implementation can be found in SlideshowDataViewController.m (Fig. 12.27). Lines 7–10 synthesize the properties. We override the viewDidLoad method (lines 13–80) to set up our view. First, we set the navigationItem’s title (line 16) and initialize pictures (line 18). Then we create the four UIBarButtonItems for adding pictures, music, effects and playing the slideshow (lines 22–52). We add the UIBarButtonItem for playing the slideshow to the UINavigationItem (line 27) and add the other UIBarButtonItems to the bottom toolbar (lines 55–56). We also add a Flexible Space Bar Button Item (created at lines 50–52) to the bottom toolbar to center the other components. Lines 65–69 position the toolbar at the bottom of the main view. We then put the Table View in editing mode (line 73) and set the Table View’s row height (line 76).

Fig. 12.27 | Method viewDidLoad of class SlideshowDataViewController.

image

image

Method viewDidAppear: and viewDidDisappear: of Class SlideshowDataViewController

Methods viewDidAppear: and viewDidDisappear: (Fig. 12.28) adjust the GUI component’s sizes as necessary for hiding and showing the view. In viewDidAppear: (lines 83–114) we first check if this is the first time the view is appearing (line 88). If so, we adjust the size of the Table View to fit the toolbar (lines 92–96) otherwise, an animation displays the toolbar (lines 101–109). In viewWillDisappear: we hide the toolbar by moving it below the screen (lines 122–126).

Fig. 12.28 | Method viewDidAppear: and viewDidDisappear: of class SlideshowDataViewController.

image

image

Methods addPhoto and imagePickerController:didFinishPickingImage: of Class SlideshowDataViewController

The next two methods (Fig. 12.29) allow the user to choose an image from the photo library and add it to the slideshow. The addPhoto method (lines 130–148) is called when the user touches the “Add PictureUIBarButtonItem. First, we initialize the UIImagePickerController if it hasn’t been initialized yet (lines 132–142). We set the allowsImageEditing property to YES (line 136) to allow the user to edit the image before it is added to the slideshow. We also set the sourceType to UIImagePickerControllerSourceTypePhotoLibrary to specify that the image is to be picked from the user’s photo library. We then show the image picker (line 147).

Fig. 12.29 | Methods addPhoto and imagePickerController:didFinishPickingImage: of class SlideshowDataViewController.

image

The imagePickerController:didFinishPickingImage:editingInfo: method is called when the user finishes picking an image using a UIImagePickerController. The chosen image is passed as the img property. First, we add the chosen image to pictures (line 155). We then insert a new row in the table for the image (lines 159–161) and dismiss the UIImagePickerController (line 164).

Methods addMusic and mediaPicker:didPickMediaItems: of Class SlideshowDataViewController

The addMusic and mediaPicker:didPickMediaItems: methods (Fig. 12.30) allow the user to choose music from the iPod similarly to how they chose images from the photo library. In the addMusic method (lines 168–179) we create a new MPMediaPickerController (lines 171–172). We specify MPMediaTypeMusic to only allow the media picker to pick music. We set the allowsPickingMultipleItems property to YES to allow the user to pick multiple songs. We then show the MPMediaPickerController (line 177).

Fig. 12.30 | Methods addMusic and mediaPicker:didPickMediaItems: of class SlideshowDataViewController.

image

The MPMediaPickerController calls method mediaPicker:didPickMediaItems: when the user finishes picking songs. We store the chosen music (line 185) and dismiss the MPMediaPickerContorller (line 188).

Methods addEffect, actionSheet:clickedButtonAtIndex:, startSlideshow and firstImage of Class SlideshowDataViewController

Figure 12.31 defines the addEffect, actionSheet:clickedButtonAtIndex: and startSlideshow methods. The addEffect method (lines 192–203) creates the UIActionSheet (from which the user chooses an effect) if it hasn’t been initialized yet (lines 194–200). We then show the UIActionSheet (line 202).

Fig. 12.31 | Methods addEffect and startSlideshow of class SlideshowDataViewController.

image

image

The actionSheet:clickedButtonAtIndex: method is called when the user touches one of the choices on the UIActionSheet. We update effect with the selected choice.

The startSlideshow method begins the slideshow. First, we create slideshowViewController if it hasn’t been created yet (lines 216–217). We then update slideshowViewController’s properties (lines 220–222) with the correct pictures, transition effect and music. We hide the navigation bar (line 225) and show the slideshowViewController (lines 228–229). The firstImage method (lines 233–240) returns the first UIImage in the pictures array, if one exists.

UITableViewDataSource methods of Class SlideshowDataViewController

The next methods in SlideshowDataViewController are declared in the UITableViewDataSource protocol. Method tableView:numberOfRowsInSection: (Fig. 12.32, lines 243–247) returns the number of pictures in the slideshow to indicate the number of rows.

Fig. 12.32 | Method tableView:cellForRowAtIndexPath: of class SlideshowDataViewController.

image

image

The tableView:cellForRowAtIndexPath: method (lines 250–290) first creates or reuses a UITableViewCell (lines 253–266). We then remove any views that may have been previously added to the cell (lines 269–270). Lines 273–276 create the UIImageView for this cell, which we then resize (lines 279–287). We add the configured UIImageView to the cell (line 288) and return the cell (line 290).

Additional UITableViewDataSource methods of Class SlideshowDataViewController

In tableView:commitEditingStyle:forRowAtIndexPath: (Fig. 12.33, lines 294–308) we handle the event generated when the user deletes a row. If the user deleted the row (line 299), we remove that entry from pictures (line 301) and remove the row from the table (lines 305–306). In the tableView:moveRowAtIndexPath:toIndexPath: method (lines 310–319) we move the object in pictures from the UItableviewcell specified by fromIndexPath to the UItableviewcell specified by toIndexPath. In tableView:canMoveRowAtIndexPath: we return YES because all the rows are reorderable.

Fig. 12.33 | Methods tableView:commitEditingStyle:forRowAtIndexPath:, tableView:moveRowAtIndexPath:toIndexPath: and tableView:canMoveRowAtIndexPath: of class SlideshowDataViewController.

image

image

12.5 Wrap-Up

The Slideshow app enables users to create slideshows using pictures and music stored on their iPhones. You saw how to use class UIImagePickerController to display a standard interface for choosing images, and class MPMediaPickerController for picking music from the iPod library. We used class MPMusicPlayerController to play the selected music. We also used the UIActionSheet component to present the user with a list of transition effect choices. Lastly, you learned how to enable an app to operate in portrait and landscape orientations by responding to orientation change events.

In Chapter 13, we’ll build the Enhanced Slideshow app, which enhances the Slideshow app with support for video and saving slideshows. You’ll see how to use the NSCoding protocol and the NSKeyedArchiver class to serialize an object to a file. You’ll also see how to use the UIImagePickerController class to allow the user to select videos, and how to use the MPMoviePlayerController class to play them.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.116.159