Saturday, 26 April 2014

Create the Project [Coming Events]

Launch Xcode and choose File  New Project. Select the Single View iOS app template. In the nexsheet, name the app EightBall, set the class prefix to EB, and choose iPhone for the device, as showin Figure 4-6.


Figure 4-6. Creating the EightBall project

Choose a location to save the new project and create it. In the project navigator, select the project, select the EightBall target from the pop-up menu (if needed), select the General tab, and then turn off the two landscapeorientations in the supported interface orientation section, so only the portrait orientation is enabled.
  
Create the Interface

Select the Main.storyboard Interface Builder file and select the single view object. Using the attributes inspector set the background color to Black, as shown in Figure 4-7.


Figure 4-7. Setting main view background color


From the library, drag a new image view object into the interface. Using the size inspector to set the height and width to 320 pixels. Drag the image object so it snaps to the vertical and horizontal centering guides, as shownin Figure 4-8.


Figure 4-8. Centering the image view

Set the first constraint by control+clicking/right-clicking in the image view and dragging down a little. Release the mouse and choose the Height constraint. This will fix the height of the image view. From the Resolve AutoLayout Issues control, choose the Add Missing Constraints in View Controller. Xcode will add sufficient constraints to make them complete. Because the view was centered in the screen, Xcode will add constraints to keep itcentered.

Just as you did in Chapter 2, you’re going to add some resource image files to your project. In the project navigator, select the Images.xcassets assets catalog. In the Finder, locate the Learn  iOS Development  Projects folder youdownloaded in Chapter 1. Inside the Ch 4 folder you’ll find the EightBall (Resources) folder, which contains five image files. Select the files eight-ball.png and eight-ball@2x.png. With these files and your workspace window visible, drag the two image files into the assets catalog, as shown in Figure 4-9.


Figure 4-9. Adding eight-ball images to the asset catalog


Returning to your project, select Main.storyboard, and select the image view object. Using the attributes inspector set the image property to eight-ball, as shown in Figure 4-10.


Figure 4-10. Setting the image



Now you need to add a text view to display the magic message. From the object library, drag in a new text view (not a text field) object, placing it over the “window”  in the middle of the eight ball Use the size inspector to set thewidth of the text view to 160 pixels and the height to 112. Center the text view using the centering guides, as shown in Figure 4-11.


Figure 4-11. Centering text view

Using the control+click/right-click gesture again, add the following constraints:

Drag up (or down), inside the text viewrelease, and choose a Height constraint.

Drag right (or left), inside the text viewrelease, and choose a Width constraint.

Drag from text view up (or down) to the image view. Choose the Center Y constraint.

Drag right (or left), from the text view to the image view. Choose the Center X
constraint.

The text view now has a fixed size and will always be centered over the image view.

Select the text view. Using the attributes inspector set the following properties:

Set text to SHAKE  FOR  ANSWER, on three lines (see Figure 4-12). Hold down the Option key when pressing the Return key to insert a literal return” character into the text property field.

Make the text view color white.

Click the up arrow in the font property until it reads System  24.0.

Choose the centered (middle) alignment.

Uncheck the Editable behavior property.

Further down, find the background property and set it to default (no background).

Your interface design is finished, and should look like the one in Figure 4-12. Now its time to move on to the code.


Figure 4-12. Finished EightBall interface

Writing the Code

Your EBViewController object will need a connection to the text view object. Select your
EBViewController.h file and add the following property:

@property  (weak,nonatomic) IBOutlet  UITextView *answerView;

Now its time to write the code that displays the messages. Switch to your implementation file (EBViewController.m). Just above the @implementation  line, add this code:

static NSString*   gAnswers[] = {
@"\rYES",
@"\rNO",
@"\rMAYBE",
@"I\rDON'T\rKNOW",
@"TRY\rAGAIN\rSOON",
@"READ\rTHE\rMANUAL"
};
#define kNumberOfAnswers (sizeof(gAnswers)/sizeof(NSString*))

@interface  EBViewController ()
-  (void)fadeFortune;
-  (void)newFortune;
@end

The first statement creates a static array of NSString  string objects. Each object is one possible answer to appear in the eight ball. The \r characters are called an escape sequence. They consist of a backslash (left leaningslash) character followed by a code that tells the compiler to 
replace the sequence with a special character. In this case, the \r is replaced with a literal “carriage return” 
character—something you cant type into your source without starting a new line.

The #define creates a constant, kNumberOfAnswers, that evaluates to the number of string objects in the gAnswers array. It does this by dividing the overall size of the array (sizeof(gAnswers)) by the size of a single element in thearray (sizeof(NSString*)). You do this so that you dont have to keep track of how many strings are in the gAnswers array. If you want to add more answers, just add new elements to the array. The kNumberOfAnswers macro willchange to reflect however many there are.

The @interface  EBViewController () statement declares the two methods used to update the message display: -fadeFortune and -newFortune. They are declared here, instead of in EBViewController.h, because these areprivate methods—not for use by objects other than EBViewController.

Create the two methods you just promised by adding the following code to your implementation (that is, between the @implementation  and @end statements):

-  (void)fadeFortune
{
[UIView animateWithDuration:0.75 animations:^{ self.answerView.alpha = 0.0;
}];
}

-  (void)newFortune
{
self.answerView.text = gAnswers[arc4random_uniform(kNumberOfAnswers)];

[UIView animateWithDuration:2.0 animations:^{ self.answerView.alpha = 1.0;
}];
}

The -fadeFortune method uses iOS animation to change the alpha property of the answerView
text view object to 0. The alpha property of a view is how opaque the view appears. A value of 1 is completely opaque, 0.5  makes it 50% transparent, and a value of 0 makes it completely invisible.
-fadeFortune makes the text view object fade away to nothing, over a period of ¾ of a second.
The -newFortune method is where all the fun is. The first statement does three things:

1.       The arc4random_uniform() function is called to pick a random numbebetween 0 and a number less than kNumberOfAnswers. So if kNumberOfAnswers is 6, the function will return a random number between 0and 5 (inclusive).

2.       The random number is used as an index into the gAnswers array to pick one of the constant NSString  objects.

3.       The random answer is used to set the text property of the text view object.
Once set, the text view object will display that text in your interface.

Finally, iOS animation is used again to change the alpha property slowly back to 1, going from invisible to opaque over a period of 2 seconds, causing the new message to gradually appear.

Theres one minor detail remaining: connecting the answerView outlet to the text view object in the interface. Switch to the Main.storyboard Interface Builder file. Select the view controller object, and use the connectionsinspector to connect the answerView outlet, as shown in
Figure 4-13.


Figure 4-13. Connecting the answerView outlet

Handling Shake Events

Your app now has everything it needs to work, except the event handling that will make it happen. In the Xcode documentation (Help  Documentation and API Reference), take a look at the documentation forUIResponder. In it, you’ll find documentation for three methods:

-  (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent  *)event
-  (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent  *)event
-  (void)motionCancelled:(UIEventSubtype)motion  withEvent:(UIEvent *)event

Each message is sent during a different phase of a motion event. Motion events are very simple—remember these are “high-level” events. Motion events begin and they end. If the motion is interrupted, or never finishes, your object receives a motion canceled message.

To handle motion events in your view controller, add these three event handler methods to your
EBViewController implementation:

-  (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent  *)event
{
if (motion==UIEventSubtypeMotionShake) [self  fadeFortune];
}



-  (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent  *)event
{
if (motion==UIEventSubtypeMotionShake) [self  newFortune];
}

-  (void)motionCancelled:(UIEventSubtype)motion  withEvent:(UIEvent *)event
{
if (motion==UIEventSubtypeMotionShake) [self  newFortune];
}

Each method begins by examining the motion parameter to see if the motion event received describes the one you’re interested in (the shake motion). If not, you ignore the event. This is important. Future versions of iOS may addnew motion events; your object should only pay attention to the ones its designed to work with.

The -motionBegan:withEvent: handler sends a -fadeFortune message. When the user starts to shake the device, the current message fades away.

The -motionEnded:withEvent: handler sends the -newFortune message. When the shaking stops, a new fortune appears.

Finally, the -motionCancelled:withEvent: handler makes sure a message is visible if the motion was interrupted or interpreted to be some other gesture.

No comments:

Post a Comment