首页 > 代码库 > ios成长之每日一遍(day 7)

ios成长之每日一遍(day 7)

今天到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 = http://www.mamicode.com/random() % [self.images count];
        
        if (newValue =http://www.mamicode.com/= 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));
}

#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