今天到UITabBarController 结合 UIPickView, 这里一共有5个实现, 由浅到易。
其实在IB上面使用UITabBarController很简单, 就像平常拖控件一样拖到界面上面, 然后把Tab Bar Item拉到UITabBarController就可以增加底下的tab, 再分别指定底下tab就可以关联到对应的ViewController。
BIDAppDelegate.h
#import <UIKit/UIKit.h> @interface BIDAppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) IBOutlet UITabBarController *rootController; @end
BIDAppDelegate.m
#import "BIDAppDelegate.h" @implementation BIDAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. [[NSBundle mainBundle] loadNibNamed:@"TabBarController" owner:self options:nil]; // 因为与IB做了IBOutlet的关联, 所以以这种方式加载xib到对应的controller self.window.rootViewController = self.rootController; // 与IB做了IBOutlet的关联 self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } @end
=============================================================
BIDDatePickerViewController第一个Tab所对应的视图控制器:
BIDDatePickerViewController.h
#import <UIKit/UIKit.h> @interface BIDDatePickerViewController : UIViewController @property (strong, nonatomic) IBOutlet UIDatePicker *datePicker; - (IBAction)buttonPressed; @end
BIDDatePickerViewController.m
#import "BIDDatePickerViewController.h" @implementation BIDDatePickerViewController - (IBAction)buttonPressed { NSDate *selected = [self.datePicker date]; // 返回datapicker的时间 NSString *message = [[NSString alloc] initWithFormat: @"The date and time you selected is: %@", selected]; // 弹出UIAlertView UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Date and Time Selected" message:message delegate:nil cancelButtonTitle:@"Yes, I did." otherButtonTitles:nil]; [alert show]; } - (void)viewDidLoad { [super viewDidLoad]; NSDate *now = [NSDate date]; // 获取当前的时间 [self.datePicker setDate:now animated:NO]; // 在视图加载完后, 让datapicker显示当前的时间 } @end
=============================================================
BIDSingleComponentPickerViewController.h 第二个Tab所有对应的视图控制器:
#import <UIKit/UIKit.h> @interface BIDSingleComponentPickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> // datapicker的所需要委托还有数据源 @property (strong, nonatomic) IBOutlet UIPickerView *singlePicker; @property (strong, nonatomic) NSArray *characterNames; // datapicker的数据 - (IBAction)buttonPressed; @end
BIDSingleComponentPickerViewController.m
#import "BIDSingleComponentPickerViewController.h" @implementation BIDSingleComponentPickerViewController - (IBAction)buttonPressed { // 获取picker选择的哪一行, 0是表示第一列 NSInteger row = [self.singlePicker selectedRowInComponent:0]; NSString *selected = self.characterNames[row]; // 根据行数得到Array的对应索引的内容 NSString *title = [[NSString alloc] initWithFormat: @"You selected %@!", selected]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:@"Thank you for choosing." delegate:nil cancelButtonTitle:@"You're Welcome" otherButtonTitles:nil]; [alert show]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.characterNames = @[@"Luke", @"Leia", @"Han", @"Chewbacca", @"Artoo", @"Threepio", @"Lando"]; // 为Array赋数值 } #pragma mark - #pragma mark Picker Data Source Methods // UIPickerViewDataSource必须实现的方法, 指定picker有多少列 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } // 指定列有多少行 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [self.characterNames count]; } #pragma mark Picker Delegate Methods // UIPickerViewDelegate必须的方法, 指定picker每一行显示的内容 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return self.characterNames[row]; } @end
================================================================
BIDDoubleComponentPickerViewController.h 第三个tab所对应的视图控制器:
#import <UIKit/UIKit.h> #define kFillingComponent 0 #define kBreadComponent 1 @interface BIDDoubleComponentPickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> @property (strong, nonatomic) IBOutlet UIPickerView *doublePicker; @property (strong, nonatomic) NSArray *fillingTypes; @property (strong, nonatomic) NSArray *breadTypes; -(IBAction)buttonPressed; @end
BIDDoubleComponentPickerViewController.m
#import "BIDDoubleComponentPickerViewController.h" @implementation BIDDoubleComponentPickerViewController -(IBAction)buttonPressed { // kFillingComponent与kBreadComponent是定义的宏, 用来标记是第几列的 NSInteger fillingRow = [self.doublePicker selectedRowInComponent: kFillingComponent]; // 返回第kFillingComponent列被选中的行 NSInteger breadRow = [self.doublePicker selectedRowInComponent: kBreadComponent]; // 返回第kBreadComponent列被选中的行 NSString *filling = self.fillingTypes[fillingRow]; NSString *bread = self.breadTypes[breadRow]; NSString *message = [[NSString alloc] initWithFormat: @"Your %@ on %@ bread will be right up.", filling, bread]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"Thank you for your order" message:message delegate:nil cancelButtonTitle:@"Great!" otherButtonTitles:nil]; [alert show]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.fillingTypes = @[@"Ham", @"Turkey", @"Peanut Butter", @"Tuna Salad", @"Chicken Salad", @"Roast Beef", @"Vegemite"]; self.breadTypes = @[@"White", @"Whole Wheat", @"Rye", @"Sourdough", @"Seven Grain"]; } #pragma mark - #pragma mark Picker Data Source Methods // 表示这个picker有两列 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 2; } // 分别指定每一列所拥有的行数 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if (component == kBreadComponent) { return [self.breadTypes count]; } else { return [self.fillingTypes count]; } } #pragma mark Picker Delegate Methods // 为不同的列指定对应的内容 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { if (component == kBreadComponent) { return self.breadTypes[row]; } else { return self.fillingTypes[row]; } } @end
===============================================================
BIDDependentComponentPickerViewController.h 第四个tab所对应的视图控制器:
#import <UIKit/UIKit.h> #define kStateComponent 0 #define kZipComponent 1 @interface BIDDependentComponentPickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> @property (strong, nonatomic) IBOutlet UIPickerView *dependentPicker; @property (strong, nonatomic) NSDictionary *stateZips; @property (strong, nonatomic) NSArray *states; @property (strong, nonatomic) NSArray *zips; - (IBAction) buttonPressed; @end
BIDDependentComponentPickerViewController.m
#import "BIDDependentComponentPickerViewController.h" @implementation BIDDependentComponentPickerViewController - (IBAction)buttonPressed { NSInteger stateRow = [self.dependentPicker selectedRowInComponent:kStateComponent]; NSInteger zipRow = [self.dependentPicker selectedRowInComponent:kZipComponent]; NSString *state = self.states[stateRow]; NSString *zip = self.zips[zipRow]; NSString *title = [[NSString alloc] initWithFormat: @"You selected zip code %@.", zip]; NSString *message = [[NSString alloc] initWithFormat: @"%@ is in %@", zip, state]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. NSBundle *bundle = [NSBundle mainBundle]; // 获取NSBundle NSURL *plistURL = [bundle URLForResource:@"statedictionary" withExtension:@"plist"]; // 获取对应名字和后缀名的URL self.stateZips = [NSDictionary dictionaryWithContentsOfURL:plistURL]; // 根据URL获取对应的NSDictionary NSArray *allStates = [self.stateZips allKeys]; // 得到NSDictionary的所有key NSArray *sortedStates = [allStates sortedArrayUsingSelector: @selector(compare:)]; // 为Array排序 self.states = sortedStates; // 赋值 NSString *selectedState = self.states[0]; // 获取Array的第一个字符 self.zips = self.stateZips[selectedState]; // 因为是Dictionary, 所以根据Array的第一个字符获取对应的Array } #pragma mark - #pragma mark Picker Data Source Methods - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 2; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if (component == kStateComponent) { return [self.states count]; } else { return [self.zips count]; } } #pragma mark Picker Delegate Methods - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { if (component == kStateComponent) { return self.states[row]; } else { return self.zips[row]; } } // UIPickerViewDelegate的方法, 方法是点击后触发 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { // kStateComponent列 if (component == kStateComponent) { NSString *selectedState = self.states[row]; // 根据行数对应Array的元素 self.zips = self.stateZips[selectedState]; // Dictionary根据选中的元素也就是key获取对应的Array [self.dependentPicker reloadComponent:kZipComponent]; // picker重新加载指定列 [self.dependentPicker selectRow:0 inComponent:kZipComponent animated:YES]; // 选中指定列的某一行 } } // 为不同的列设置不同的宽度 - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { if (component == kZipComponent) { return 90; } else { return 200; } } @end
==================================================================
BIDCustomPickerViewController.h 第五个tab所对应的视图控制器:
#import <UIKit/UIKit.h> @interface BIDCustomPickerViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> @property (strong, nonatomic) IBOutlet UIPickerView *picker; @property (strong, nonatomic) IBOutlet UILabel *winLabel; @property (strong, nonatomic) NSArray *images; @property (strong, nonatomic) IBOutlet UIButton *button; - (IBAction)spin; @end
BIDCustomPickerViewController.m
#import "BIDCustomPickerViewController.h" #import <AudioToolbox/AudioToolbox.h> @implementation BIDCustomPickerViewController { SystemSoundID winSoundID; SystemSoundID crunchSoundID; } -(void)showButton { self.button.hidden = NO; } -(void)playWinSound { if (winSoundID == 0) { NSURL *soundURL = [[NSBundle mainBundle] URLForResource:@"win" withExtension:@"wav"]; // 获取指定音频文件得URL AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &winSoundID); // 创建系统声音对象 } AudioServicesPlaySystemSound(winSoundID); // 播放系统声音 self.winLabel.text = @"WINNING!"; [self performSelector:@selector(showButton) withObject:nil afterDelay:1.5]; // 执行方法 } - (IBAction)spin { BOOL win = NO; int numInRow = 1; int lastVal = -1; for (int i = 0; i < 5; i++) { int newValue = random() % [self.images count]; if (newValue == lastVal) { numInRow++; } else { numInRow = 1; } lastVal = newValue; [self.picker selectRow:newValue inComponent:i animated:YES]; [self.picker reloadComponent:i]; if (numInRow >= 3) { win = YES; } } if (crunchSoundID == 0) { NSString *path = [[NSBundle mainBundle] pathForResource:@"crunch" ofType:@"wav"]; NSURL *soundURL = [NSURL fileURLWithPath:path]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &crunchSoundID); } AudioServicesPlaySystemSound(crunchSoundID); if (win) { [self performSelector:@selector(playWinSound) withObject:nil afterDelay:.5]; } else { [self performSelector:@selector(showButton) withObject:nil afterDelay:.5]; } self.button.hidden = YES; self.winLabel.text = @""; if (win) { self.winLabel.text = @"WIN!"; } else { self.winLabel.text = @""; } } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.images = @[[UIImage imageNamed:@"seven"], [UIImage imageNamed:@"bar"], [UIImage imageNamed:@"crown"], [UIImage imageNamed:@"cherry"], [UIImage imageNamed:@"lemon"], [UIImage imageNamed:@"apple"]]; srandom(time(NULL)); // random()每次生成的随机数就是非固定的了 } #pragma mark - #pragma mark Picker Data Source Methods - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 5; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [self.images count]; } #pragma mark Picker Delegate Methods // 自定义的UIPickerView内容,给每列每行设置一个UIView - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { UIImage *image = self.images[row]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; return imageView; } @end