IOS中UITabBar、UIDatePicker、Picker View控件练习(一)
目标:
我们将创建一个类似iphone“时钟”的小程序,当然会比时钟简单的多^_^
我们的程序会有5个界面,实现5个不同的功能,分别是时间选择器、单滚轮选择器、多滚轮选择器、包含依赖的多滚轮选择器、包含图像的自定义选择器。
思路:
ios程序其实很简单(至少我目前看的教程是这样),有一个主视图负责显示不同的子视图,每个子视图只需要考虑自己的功能既可。
设计步骤:
添加5个类,作为子类的控制器。
新建一个storyboard,拖一个Tab Bar Controller,你会发现,出现了3个scene,而且其中一个关联了另外两个,不要惊讶,这应该是xcode帮我做的,因为如果你打算用tab bar controller肯定就有1个以上的 scene啊,xcode知道这一点,所以干脆帮我们关联好了2个子视图。
现在我们有2个子视图,可是我们需要5个子视图,现在我们需要做的就是在往storyboard中拖3个view controller,然后把这3个视图作为子视图和主视图关联起来。
关联的方法是选中主视图的controller,按住control,拖向子视图,然后松开鼠标,在弹出的菜单中relationship segue中的view controllers。

当我们完成这一步的时候,你应该能发现子视图的底部出现了一个和屏幕一样宽的按钮,名字一般是item,选中这个item(可以通过编辑区左下角的show document outline打开导航器选择),打开属性面板,在bar item设置组中设置title和图标。
选择子视图的controller,在身份面板,选择对应的控制器。
按照这样的步骤,添加5个子视图,并分别设置好。
程序框架设计已经完成,可以运行了,不过此时因为5个子视图的都没有内容,所以我们只能看到屏幕底部的Tab bar在变化。
时间选择器:
选中其中一个子视图,从控件库拖一个date picker放在视图的最上方,然后在视图中间位置添加一个button。
把date picker拖到对应的controller.m文件中,添加输出接口,
把button拖到对应的controller.m文件中,添加方法,在button实现方法中获取date picker的值,然后用uialert view显示。
因为这个很简单,所以不讲解代码了。
程序优化:
1、在viewDidLoad方法中可以把date picker的值设置为当前时间,提升用户体验或者为了学习date picker的设置时间的方法。
2、界面优化,适配屏幕旋转和不同尺寸的屏幕,我们可以通过约束来实现。
选择view中的uidatepicker,然后通过菜单栏editor-pin-top space to superview,使uidatepicker始终靠在试图顶部
然后选择storyboard右下角的add new constraints,把左右边距设为0,这样uidatepicker就能始终与屏幕同宽。
3、日期格式默认显示的GMT(格林威治时间),这个地方我们还可以优化为指定格式的

具体代码:
1 // 2 // DatePickerViewController.m 3 // Pickers 4 // 5 // Created by 张光发 on 15/10/13. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "DatePickerViewController.h" 10 11 @interface DatePickerViewController () 12 @property (weak, nonatomic) IBOutlet UIDatePicker* datePicker; 13 14 @end 15 16 @implementation DatePickerViewController 17 18 - (void)viewDidLoad 19 { 20 [super viewDidLoad]; 21 // Do any additional setup after loading the view. 22 NSDate* now = [NSDate date]; 23 [self.datePicker setDate:now]; 24 } 25 26 - (IBAction)buttonPressed:(UIButton*)sender 27 { 28 NSDate* selected = [self.datePicker date]; 29 NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init]; 30 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 31 NSString* date = [dateFormatter stringFromDate:selected]; 32 33 NSString* message = [[NSString alloc] initWithFormat:@"你选择的日期是%@", date]; 34 UIAlertView* alert = [[UIAlertView alloc] 35 initWithTitle:@"Date and Time Selected" 36 message:message 37 delegate:nil 38 cancelButtonTitle:@"That's so true" 39 otherButtonTitles:nil, nil]; 40 [alert show]; 41 } 42 43 @end
单滚轮选择器:
选择一个子视图,从控件库拖一个picker view放在视图的最顶端,在视图中间放一个button。
把picker拖到对应的controller.m文件中,添加输出接口,
把button拖到对应的controller.m文件中,添加方法,在button实现方法中获取picker的值,然后用uialert view显示。
NOTE:
和时间选择器不同,单滚轮选择器需要指定数据源和委托,因为picker view本身只是一个view,他并不会保存数据。
选择picker之后在关联检查器中Outlets设置组中可以看到datasource和delegate,现在他们还没有任何关联。
按住后面的空心圆指向scene中的controller,两个都是这样做。
这样就把控制器作为数据源和委托了。
代码讲解:
我们使用控制器作为picker view的数据源和委托,因此控制器必须实现两个协议,
UIPickerViewDelegate和UIPickerViewDataSource,在.h文件中添加
SingleComponentPickerViewController : UIViewController <UIPickerViewDelegate,UIPickerViewDataSource>
数据源我们使用NSArray就可以,所以先添加一个nsarray,并在界面加载后就给数据源赋值
获取picker的思路是:获取picker选取的行数,然后找数据源中对应索引的数据。
NSInteger row = [self.singlePicker selectedRowInComponent:0]; NSString* selected = self.characterNames[row];
有了数据就可以使用uialertview显示啦、Y^o^Y
有了这些还不够,还需要实现一些方法,来设置picker
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
方法是告诉picker应该有几个滚轮、
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
是告诉picker某个滚轮有几行。
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
是一个委托方法,这个方法可以返回某个滚轮上某一行的数据。
.m文件完整代码:
1 // 2 // SingleComponentPickerViewController.m 3 // Pickers 4 // 5 // Created by 张光发 on 15/10/13. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "SingleComponentPickerViewController.h" 10 11 @interface SingleComponentPickerViewController () 12 @property (weak, nonatomic) IBOutlet UIPickerView* singlePicker; 13 @property (strong, nonatomic) NSArray* characterNames; 14 15 @end 16 17 @implementation SingleComponentPickerViewController 18 19 - (void)viewDidLoad 20 { 21 [super viewDidLoad]; 22 // Do any additional setup after loading the view. 23 self.characterNames = @[ @"qew", @"23", @"wqe 2", @"😈", @"09uqwe", @"扫ij", @"啊思安奥斯丁我" ]; 24 } 25 26 27 - (IBAction)buttonPressed:(id)sender 28 { 29 NSInteger row = [self.singlePicker selectedRowInComponent:0]; 30 NSString* selected = self.characterNames[row]; 31 NSString* title = [[NSString alloc] initWithFormat:@"你选择的是%@", selected]; 32 UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title 33 message:@"thank you for you choosing" 34 delegate:nil 35 cancelButtonTitle:@"you are welcome" 36 otherButtonTitles:nil, nil]; 37 [alert show]; 38 } 39 40 #pragma 41 #pragma picker date source methods 42 -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 43 { 44 return 1; 45 } 46 47 -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 48 { 49 return [self.characterNames count]; 50 } 51 52 #pragma picker date delegate methods 53 -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 54 { 55 return self.characterNames[row]; 56 } 57 @end
效果图:

多滚轮选择器:
和单滚轮选择器相似,所以一些简单的布局、关联等操作就略过了,可以参考单滚轮选择器
注意:因为是多滚轮选择器,所以在获取数据和设置行数的时候注意判断具体是那个滚轮就好。
具体代码:
1 // 2 // DoubleComponentPickerViewController.m 3 // Pickers 4 // 5 // Created by 张光发 on 15/10/13. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "DoubleComponentPickerViewController.h" 10 #define kFillingComponent 0 11 #define kBreadComponent 1 12 13 @interface DoubleComponentPickerViewController () 14 @property (weak, nonatomic) IBOutlet UIPickerView* doublePicker; 15 @property (strong, nonatomic) NSArray* fillingTypes; 16 @property (strong, nonatomic) NSArray* breadTypes; 17 @end 18 19 @implementation DoubleComponentPickerViewController 20 21 - (void)viewDidLoad 22 { 23 [super viewDidLoad]; 24 // Do any additional setup after loading the view. 25 26 self.fillingTypes = @[ @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8" ]; 27 self.breadTypes = @[ @"A", @"B", @"C", @"D", @"E", @"F", @"G" ]; 28 } 29 30 - (IBAction)buttonPressed:(id)sender 31 { 32 NSInteger fillingRow = [self.doublePicker selectedRowInComponent:kFillingComponent]; 33 NSInteger breadeRow = [self.doublePicker selectedRowInComponent:kBreadComponent]; 34 NSString* filling = self.fillingTypes[fillingRow]; 35 NSString* bread = self.breadTypes[breadeRow]; 36 37 NSString* message = [[NSString alloc] initWithFormat:@"你选择的组合是%@%@", filling, bread]; 38 UIAlertView* alert = [[UIAlertView alloc] 39 initWithTitle:@"你做出了选择" 40 message:message 41 delegate:nil 42 cancelButtonTitle:@"中大奖,┏ (゜ω゜)=☞" 43 otherButtonTitles:nil, nil]; 44 [alert show]; 45 } 46 47 //TODO: 返回滚轮个数 48 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView 49 { 50 return 2; 51 } 52 //TODO: 返回每个滚轮行数 53 - (NSInteger)pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component 54 { 55 if (component == kFillingComponent) { 56 return [self.fillingTypes count]; 57 } 58 else { 59 return [self.breadTypes count]; 60 } 61 } 62 63 //TODO: 返回指定滚轮指定行数的数据 64 - (NSString*)pickerView:(UIPickerView*)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 65 { 66 if (component == kFillingComponent) { 67 return self.fillingTypes[row]; 68 } 69 else { 70 return self.breadTypes[row]; 71 } 72 } 73 74 @end
界面优化:
因为我们的界面设计非常简单,只有一个按钮和一个pickerview,所以屏幕适配和支持屏幕旋转其实so easy
给pickerview添加3个约束,分别是top space to:superview(0),trailing space to:superview(0),leading space to:superview(0),这三个约束的意思分别是:上边距为0,右边距为0,左边距为0.
给button添加2个约束,align center X to:superview(0),top space to:pickerview equal 100,这两个约束的意思是:在X轴的中间位置,顶部距离pcikerview 100点。
align center X(Y) to:superview(value),这个约束的value值如果为正值就会向X(Y)轴负方向偏离,此处要注意。
添加好这两个控件的约束,就能适配不同尺寸的屏幕和支持屏幕旋转了。
效果图:


浙公网安备 33010602011771号