一、分页栏
创建一个新的项目,Subclass of的值选中UIViewController,然后在storyboard中删除根视图,在右下方拖出一个Tab Bar Controller
新增分页,只需从右下方拖出一个普通的View Controller,按住鼠标右键从分页栏控制器拖动到新视图控制器上释放,在弹出面板中的Relationship Segue标题下选中view controllers,使用这些分页要给他们创建Cocoa Touch Class 并关联。
设置分页栏底部的标题与图标,如图:
二、选取器
选取器分为Date Picker和Picker View,前者是日期选取器,后者为一般选取器,可以任意定制用途。
(一)下面实现一个功能:点击按钮,弹出一个警告视图显示当前在日期选取器中选定的日期和时间
1)往Date分页上拖出一个Date Picker和一个按钮,并设置约束
2)创建日期选取器的输出接口,选中Date Picker,按住右键拖动到实现文件,创建一个名为datePicker的输出接口,如图:
3)加载此视图时,选取器都会重置为当前的日期和时间的实现代码,在viewDidLoad方法中编写,如图:
4)实现功能的操作方法,选中按钮,按住右键拖动到实现文件下方,创建一个名为buttonPressed的操作方法,并编写代码,如图:
5)实现效果,显示的是格林威治标准时间
(二)自定义的选取器视图的实现,下面记录几个要点,与上面相同的步骤就不说了
1)将控制器实现为数据源和委托,关联dateSource和delegate,如图:
2)在.h文件中添加协议
3)创建一个数组,用于向选取器提供数据,并将其赋给characterNames属性,代码如下:
4)按钮的方法和数据源、委托的方法实现,结合上下图
5)实现效果
(三) 实现多滚轮选取器
1)添加委托与数据源协议,与上面相同。
<UIPickerViewDelegate,UIPickerViewDataSource>
2)定义两个选取器滚轮相应的索引值常量,以及相应的两个数组
3)其他方法的实现跟一个选取器差不多,这里只是多了一个判断使用哪个滚轮,代码如下:
@implementation DoubleComponentPickerViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 初始化滚轮的内容
self.fillingTypes = @[@"Ham",
@"Turkey",
@"Peanut Butter",
@"Tuna Salad",
@"Chicken Salad",
@"Roast Beef",
@"Vegemite"];
self.breadTypes = @[@"White",
@"Whole Wheat",
@"Rye",@"Sourdough",
@"Seven Grain"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonPressed:(id)sender {
NSInteger fillingRow = [self.doublePicker selectedRowInComponent:kFillingComponent];
NSInteger breadRow = [self.doublePicker selectedRowInComponent: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];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Thank you for your order" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"Great!" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark Picker Data Soure Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
// 滚轮数目2个
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
4)运行效果
(四)实现有依赖关系的选取器,即其中的内容变化会引起另一个中的内容变化
由于步骤大同小异,这里只po代码了。。。
//
// DependentComponentPickerViewController.m
// Pickers
//
// Created by Jierism on 16/7/19.
// Copyright © 2016年 Jierism. All rights reserved.
//
#import "DependentComponentPickerViewController.h"
#define kStateComponent 0
#define kZipComponent 1
@interface DependentComponentPickerViewController ()
@property (weak, nonatomic) IBOutlet UIPickerView *dependentPicker;
@property (strong,nonatomic) NSDictionary *stateZips;
@property (strong,nonatomic) NSArray *states;
@property (strong,nonatomic) NSArray *zips;
@end
@implementation DependentComponentPickerViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:@"statedictionary" withExtension:@"plist"];
self.stateZips = [NSDictionary dictionaryWithContentsOfURL:plistURL];
NSArray *allStates = [self.stateZips allKeys];
NSArray *sortedStates = [allStates sortedArrayUsingSelector:@selector(compare:)];
self.states = sortedStates;
NSString *selectedState = self.states[0];
self.zips = self.stateZips[selectedState];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonPressed:(id)sender {
NSInteger stateRow = [self.dependentPicker selectedRowInComponent:kStateComponent];
NSInteger zipRow = [self.dependentPicker selectedRowInComponent:kZipComponent];
NSString *state = self.states[stateRow];
NSString *zip = self.states[zipRow];
NSString *title = [[NSString alloc] initWithFormat:@"You selected zip code %@.",zip];
NSString *message = [[NSString alloc] initWithFormat:@"%@ is in %@",zip,state];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];
}
#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];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == kStateComponent) {
NSString *selectedState = self.states[row];
self.zips = self.stateZips[selectedState];
[self.dependentPicker reloadComponent:kZipComponent];
[self.dependentPicker selectRow:0 inComponent:kZipComponent animated:YES];
}
}
// 调整选取器占用的宽度
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
CGFloat pickerWidth = pickerView.bounds.size.width;
if (component == kZipComponent) {
return pickerWidth/3;
}else{
return 2*pickerWidth/3;
}
}
@end
注意这里加入了一个.plist文件,涉及到包的使用。什么是包?
包(bundle )是一种特定类型的文件夹,其中的内容遵循特定的结构。应用程序和框架都是包,这个调用返回的包对象表示我们的应用程序。
(五)用选取器实现的滚轮小游戏
相同的内容也不说了,详见代码
1)接口的声明,这里还添加了游戏声音
2)往选取器里面加载图片
3)实现点击按钮,选取器开始滚动,并在滚动过程中隐藏按钮
- (void)showButton {
self.button.hidden = NO;
}
- (IBAction)spin:(id)sender {
BOOL win = NO;
int numInRow = 1;
int lastVal = -1;
for (int i = 0; i < 5 ; i++) {
int newValue = arc4random_uniform((uint)[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:0.5];
}else{
[self performSelector:@selector(showButton) withObject:nil afterDelay:0.5];
}
// 隐藏按钮
self.button.hidden = YES;
self.winLabel.text = @" ";
}
4)播放声音的方法,点击按钮和获胜时会被调用,播放相应的音乐
5)数据源协议和委托的方法
6)运行效果