Photos and iPod Library Access
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 “Play” Button 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 “Edit” Button in the top-left corner of the app displays Deletion Control Buttons () next to each of the slideshows (Fig. 12.3 (a)). Touching one of these displays a “Delete” Button next to the selected slideshow (Fig. 12.3 (b)) that allows the user to remove that slideshow. The user touches the “New” Button to create a new slideshow.
Touching the “New” Button 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 Picture” Button in the bottom-left corner of the app displays the iPhone’s photo library (Fig. 12.5).
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 “Choose” Button adds that photo to the slideshow (Fig. 12.6 (b)).
Open the directory containing the Slideshow app project. Double click Slideshow.xcodeproj
to open the project in Xcode.
Touch the “New” Button at the top of the app to view the Edit Slideshow screen. Touch the “Add Picture” Button 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 “Choose” Button to add the picture to the slideshow and return to the Edit Slideshow screen. Touching the “Cancel” Button here returns you to the previous screen without adding the photo. Add two more images to this slideshow. Touch the reordering control () 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 () next to the top picture then touch the “Delete” Button to remove that picture from this slideshow.
Touch the “Add Effect” Button 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 Music” Button 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 “Back” Button in the top-left corner of the app to return to the list of slideshows.
Touch the “Play” Button 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.
Touch the “Modify” Button next to your slideshow to return to the Edit Slideshow screen. Touch the “Add Effect” Button 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 “Edit” Button in the top-left corner of the app. Touch the Deletion Control Button () next to your slideshow then touch the “Delete” Button to erase your slideshow from the app.
The app’s list of slideshows is displayed in a UITableView
containing custom UITableViewCell
s in which we add "
Play"
and "
Modify"
Buttons. The Edit Slideshow screen uses a UITableView
with standard UITableViewCell
s 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. UIBarButtonItem
s 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.
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
.
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.
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.
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 “New” Button 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 “Edit” Button 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.
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.
The addSlideshow
method (lines 46–55) displays the NameViewController
when the user touches the “New” Button. 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).
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.
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
.
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.
The slideshowCellDidSelectPlayButton:
method (lines 129–150) plays a slideshow when the user touches its “Play” Button. 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).
tableView:commitEditingStyle:forRowAtIndexPath:
of Class RootViewController
Method tableView:commitEditingStyle:forRowAtIndexPath:
(Fig. 12.13) specifies that RootViewController
’s UITableViewCell
s support editing. This allows the user to delete slideshows.
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 (). 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 UITableViewCell
s.
SlideshowCell
Interface DeclarationThe SlideshowCell
class (Fig. 12.15) extends UITableViewCell
to display a slideshow title, and “Play” and “Modify” Buttons. 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 “Edit” Button 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.
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 UIButton
s 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).
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.
SlideshowViewController
The SlideshowViewController
’s View plays a slideshow in full screen mode. The slideshow re-orients as the user rotates the iPhone.
SlideshowViewController
Interface DeclarationThe 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
.
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
.
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).
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.
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.
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.
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).
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.
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.
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.
NameViewController
The NameViewController
’s view is displayed when the user touches the “New” Button above the slideshow list. The user enters the name of the new slideshow into a Text Field.
NameViewController
Interface DeclarationThe 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
.
NameViewController
Class ImplementationMethod 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.
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.
Create a new UIViewController
subclass named SlideshowDataViewController
. Its class declaration is shown in SlideshowDataViewController.h
(Fig. 12.26).
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 BOOL
s (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
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 UIBarButtonItem
s 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).
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).
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 Picture” UIBarButtonItem
. 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).
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).
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).
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).
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).
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.
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).
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.
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.
3.144.116.159