Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Beginning iOS5 Development.pdf
Скачиваний:
7
Добавлен:
09.05.2015
Размер:
15.6 Mб
Скачать

CHAPTER 7: Tab Bars and Pickers

205

Fonts Supported by iOS Devices

Be careful when using the fonts palette in Interface Builder for designing iOS interfaces. The attribute inspector’s font selector will let you assign from a wide range of fonts, but not all iOS devices have the same set of fonts available. At the time of this writing, for instance, there are several fonts that are available on the iPad, but not on the iPhone or iPod touch. You should limit your font selections to one of the font families found on the iOS device you are targeting. This post on Jeff LaMarche’s excellent iOS blog shows you how to grab this list programmatically: http://iphonedevelopment.blogspot.com/ 2010/08/fonts-and-font-families.html.

In a nutshell, create a view-based application and add this code to the method application:didFinishLaunchingWithOptions: in the application delegate:

for (NSString *family in [UIFont familyNames]) { NSLog(@"%@", family);

for (NSString *font in [UIFont fontNamesForFamilyName:family]) { NSLog(@"\t%@", font);

}

}

Run the project in the appropriate simulator, and your fonts will be displayed in the project’s console log.

Adding Image Resources

Now we need to add the images that we’ll be using in our game. We’ve included a set of six image files (seven.png, bar.png, crown.png, cherry.png, lemon.png, and apple.png) for you in the project archive under the 07 Pickers/Custom Picker Images folder. Add all of those files to your project by dragging the entire folder into the Pickers folder in Xcode, just as you did for the tab bar icons. It’s probably a good idea to copy them into the project folder when prompted to do so.

Implementing the Controller

We have a bunch of new stuff to cover in the implementation of this controller. Add the following code at the beginning of BIDCustomPickerViewController.m file:

#import "BIDCustomPickerViewController.h"

@implementation BIDCustomPickerViewController

@synthesize picker; @synthesize winLabel; @synthesize column1; @synthesize column2; @synthesize column3; @synthesize column4; @synthesize column5;

- (IBAction)spin { BOOL win = NO;

www.it-ebooks.info

206

CHAPTER 7: Tab Bars and Pickers

 

int numInRow

= 1;

 

int

lastVal = -1;

 

for

(int i =

0; i < 5; i++) {

int newValue = random() % [self.column1 count];

if (newValue == lastVal) numInRow++;

else

numInRow = 1;

lastVal = newValue;

[picker selectRow:newValue inComponent:i animated:YES]; [picker reloadComponent:i];

if (numInRow >= 3) win = YES;

}

if (win)

winLabel.text = @"WIN!";

else

winLabel.text = @"";

}

.

.

.

Then, insert the following code into the viewDidLoad method:

- (void)viewDidLoad { [super viewDidLoad];

// Do any additional setup after loading the view from its nib.

UIImage *seven = [UIImage imageNamed:@"seven.png"]; UIImage *bar = [UIImage imageNamed:@"bar.png"]; UIImage *crown = [UIImage imageNamed:@"crown.png"]; UIImage *cherry = [UIImage imageNamed:@"cherry.png"]; UIImage *lemon = [UIImage imageNamed:@"lemon.png"]; UIImage *apple = [UIImage imageNamed:@"apple.png"];

for (int i = 1; i <= 5; i++) {

UIImageView *sevenView = [[UIImageView alloc] initWithImage:seven]; UIImageView *barView = [[UIImageView alloc] initWithImage:bar]; UIImageView *crownView = [[UIImageView alloc] initWithImage:crown]; UIImageView *cherryView = [[UIImageView alloc]

initWithImage:cherry];

UIImageView *lemonView = [[UIImageView alloc] initWithImage:lemon]; UIImageView *appleView = [[UIImageView alloc] initWithImage:apple]; NSArray *imageViewArray = [[NSArray alloc] initWithObjects:

sevenView, barView, crownView, cherryView, lemonView, appleView, nil];

NSString *fieldName =

[[NSString alloc] initWithFormat:@"column%d", i]; [self setValue:imageViewArray forKey:fieldName];

}

srandom(time(NULL));

www.it-ebooks.info

CHAPTER 7: Tab Bars and Pickers

207

}

Next, insert the following new lines into the viewDidUnload method:

- (void)viewDidUnload { [super viewDidUnload];

//Release any retained subviews of the main view.

//e.g. self.myOutlet = nil;

self.picker = nil; self.winLabel = nil; self.column1 = nil; self.column2 = nil; self.column3 = nil; self.column4 = nil; self.column5 = nil;

}

Finally, add the following code to the end of the file:

.

.

.

#pragma mark -

#pragma mark Picker Data Source Methods

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 5;

}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [self.column1 count];

}

#pragma mark Picker Delegate Methods

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row

forComponent:(NSInteger)component reusingView:(UIView *)view { NSString *arrayName = [[NSString alloc] initWithFormat:@"column%d",

component+1];

NSArray *array = [self valueForKey:arrayName]; return [array objectAtIndex:row];

}

@end

There’s a lot going on here, huh? Let’s take the new stuff method by method.

The spin Method

The spin method fires when the user touches the Spin button. In it, we first declare a few variables that will help us keep track of whether the user has won. We’ll use win to keep track of whether we’ve found three in a row by setting it to YES if we have. We’ll use numInRow to keep track of how many of the same value we have in a row so far, and we will keep track of the previous component’s value in lastVal so that we have a way

www.it-ebooks.info

208

CHAPTER 7: Tab Bars and Pickers

to compare the current value to the previous value. We initialize lastVal to -1 because we know that value won’t match any of the real values.

BOOL win = NO; int numInRow = 1; int lastVal = -1;

Next, we loop through all five components and set each one to a new, randomly generated row selection. We get the count from the column1 array to do that, which is a shortcut we can use because we know that all five columns have the same number of values.

for (int i = 0; i < 5; i++) {

int newValue = random() % [self.column1 count];

We compare the new value to the previous value and increment numInRow if it matches. If the value didn’t match, we reset numInRow back to 1. We then assign the new value to lastVal so we’ll have it to compare the next time through the loop.

if (newValue == lastVal) numInRow++;

else

numInRow = 1; lastVal = newValue;

After that, we set the corresponding component to the new value, telling it to animate the change, and we tell the picker to reload that component.

[picker selectRow:newValue inComponent:i animated:YES]; [picker reloadComponent:i];

The last thing we do each time through the loop is check whether we have three in a row, and set win to YES if we do.

if (numInRow >= 3) win = YES;

}

Once we’re finished with the loop, we set the label to say whether the spin was a win.

if (win)

winLabel.text = @"Win!";

else

winLabel.text = @"";

The viewDidLoad Method

The new version of viewDidLoad is somewhat scary looking, isn’t it? Don’t worry—once we break it down, it won’t seem quite so much like the monster in your closet.

The first thing we do is load six different images. We do this using a convenience method on the UIImage class called imageNamed:.

UIImage *seven = [UIImage imageNamed:@"seven.png"];

UIImage *bar = [UIImage imageNamed:@"bar.png"];

UIImage *crown = [UIImage imageNamed:@"crown.png"];

UIImage *cherry = [UIImage imageNamed:@"cherry.png"];

www.it-ebooks.info

CHAPTER 7: Tab Bars and Pickers

209

UIImage *lemon = [UIImage imageNamed:@"lemon.png"];

UIImage *apple = [UIImage imageNamed:@"apple.png"];

Once we have the six images loaded, we then need to create instances of UIImageView, one for each image, for each of the five picker components. We do that in a loop.

for (int i = 1;

i <= 5; i++)

{

UIImageView

*sevenView

=

[[UIImageView alloc] initWithImage:seven];

UIImageView

*barView =

[[UIImageView alloc] initWithImage:bar];

UIImageView

*crownView

=

[[UIImageView alloc] initWithImage:crown];

UIImageView

*cherryView = [[UIImageView alloc]

initWithImage:cherry];

UIImageView

*lemonView

= [[UIImageView alloc] initWithImage:lemon];

UIImageView

*appleView

=

[[UIImageView alloc] initWithImage:apple];

After we have the image views, we put them into an array. This array is the one that will be used to provide data to the picker for one of its five components.

NSArray *imageViewArray = [[NSArray alloc] initWithObjects: sevenView, barView, crownView, cherryView, lemonView, appleView, nil];

Now, we just need to assign this array to one of our five arrays. To do that, we create a string that matches the name of one of the arrays. The first time through the loop, this string will be column1, which is the name of the array we’ll use to feed the first component in the picker. The second time through, it will equal column2, and so on.

NSString *fieldName = [[NSString alloc] initWithFormat:@"column%d", i];

Once we have the name of one of the five arrays, we can assign this array to that property using a very handy method called setValue:forKey:. This method lets you set a property based on its name. So, if we call this with a value of "column1", it is exactly the same as calling the mutator method setColumn1:.

[self setValue:imageViewArray forKey:fieldName];

The last thing we do in this method is to seed the random number generator. If we don’t do that, the game will play the same way every time, which gets kind of boring.

srandom(time(NULL));

}

That wasn’t so bad, was it? But, um, what do we do with those five arrays now that we’ve filled them with image views? If you scroll down through the code you just typed, you’ll see that two data source methods look pretty much the same as before, but if you look down further into the delegate methods, you’ll see that we’re using a completely different delegate method to provide data to the picker. The one that we’ve used up to now returned an NSString *, but this one returns a UIView *.

Using this method instead, we can supply the picker with anything that can be drawn into a UIView. Of course, there are limitations on what will work here and look good at the same time, given the small size of the picker. But this method gives us a lot more freedom in what we display, although it is a bit more work.

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]