1.创建项目
创建初始场景,和日期选择场景(可以将其背景色设置为Scroll View Texted Background Color),选择一个日期选择器至该视图
2.创建切换
按住CONTROL从初始视图拉向日期设置视图,(注意与前一章的区别,这里因为是两个控制器相连,所以要手工触发切换因此将该切换命名以便代码实现)
3.实现逻辑
1.在实现中除了让两个控制器知道彼此的方法属性外,还要提供一个属性(让日期选择器能够访问初始控制器,他将通过该属性访问初始控制器,因为在IPAD中要禁止用户同时显示多个弹出框,若只是用模态切换则可以上一章一样用presentingViewController来获取初始场景视图控制器,但其不适用弹出框)
这里我暂且只关注IPHONE
2.手工切换的方法
由于手工切换,所以要在相应转换按钮按下的方法中编写代码
首先你要检查当前是否已经显示了日期选择器视图,通过设置一个布尔属性来进行判断,在初始控制器头文件中添加
@property(nonatomic) Boolean dateChooserVisible
布尔不是对象,所以声明属性时不用使用关键字Strong也不需要使用后将其设置为NIL,
-(IBACTION)show:id(sender){
if(self.dataChooserVisible != YES)
{
[self performSegueWithIdentifier:@"toDataChooser"sender:sender];//启动标识符为TODATACHOOSER的转换,sender为启动切换的对象
self.dataChooserVisble = Yes;
}
}
打开了日期选择界面后相应的只是bool变为了YES必须在该界面关闭时将其改回NO,
-(void)viewWillDisappear:(bool)animated{ //该方法在视图关闭时发生
((viewController *)self.delegate).datechooservisible = NO; //通过属性访问初始视图中的变量BOOL将其改回NO
}
关闭模态场景
-(IBACTION)dismiss自己定义的关闭按钮
{
[self dismissViewControllerAnimated:YES completetion:nil];
}
实现自定义选择视图
在相应的头文件中声明协议并设置属性
@interface AnimalChooserViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
@property (strong, nonatomic) NSArray *animalNames;
@property (strong, nonatomic) NSArray *animalSounds;
@property (strong, nonatomic) NSArray *animalImages;
.m文件中加载视图
- (void)viewDidLoad
{
self.animalNames=[[NSArray alloc]initWithObjects:
@"Mouse",@"Goose",@"Cat",@"Dog",@"Snake",@"Bear",@"Pig",nil];
self.animalSounds=[[NSArray alloc]initWithObjects:
@"Oink",@"Rawr",@"Ssss",@"Roof",@"Meow",@"Honk",@"Squeak",nil];
self.animalImages=[[NSArray alloc]initWithObjects:
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mouse.png"]],
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"goose.png"]],
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cat.png"]],
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"dog.png"]],
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snake.png"]],
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bear.png"]],
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pig.png"]],
nil
];
[super viewDidLoad];
}
记住要在DidUnLoad中清除
- (void)viewDidUnload
{
[self setDelegate:nil];
[self setAnimalNames:nil];
[self setAnimalImages:nil];
[self setAnimalSounds:nil];
[super viewDidUnload];
}
现在.m文件中声明
#define kComponentCount 2
#define kAnimalComponent 0
#define kSoundComponent 1
实现选择器视图数据源协议
返回组件数(.m文件)
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return kComponentCount;
}
返回每个组件包含的元素数
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
if (component==kAnimalComponent) {
return [self.animalNames count];
} else {
return [self.animalSounds count];
}
}
实现选择器视图委托协议
给每个选择器提供自定义视图
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row
forComponent:(NSInteger)component reusingView:(UIView *)view {
if (component==kAnimalComponent) { //检查是否动物组件,若是根据参数row返回数组animal images中相应的UImageView
return [self.animalImages objectAtIndex:row]; //若不是则使用animalSOunds数组中相应元素创建一个UILABle并返回
} else {
UILabel *soundLabel;
soundLabel=[[UILabel alloc] initWithFrame:CGRectMake(0,0,100,32)]; //shi使用initWUithFrame发放初始化UIlable,创建标签需定义其框架对应的矩形,CGrectMake定义起点0,0宽100高32的矩形
// [soundLabel autorelease];
soundLabel.backgroundColor=[UIColor clearColor]; //设置背景色透明
soundLabel.text=[self.animalSounds objectAtIndex:row];
return soundLabel;
}
}
选择器组件的宽度,行高,不设置显得拥挤
- (CGFloat)pickerView:(UIPickerView *)pickerView
rowHeightForComponent:(NSInteger)component {
return 55.0;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
if (component==kAnimalComponent) {
return 75.0;
} else {
return 150.0;
}
}
在用户做出选择时响应
我们用事件Value Changed来捕获用户修改选择器的操作,但自定义选择器的工作原理不是这样。
要获取用户自定义选择器中所做的选择必须实现委托方法pickerView:didSelectRow:inComponent
先在.H头文件中添加方法模型(源视图.h中)
- (void)displayAnimal:(NSString *)chosenAnimal withSound:(NSString *)chosenSound fromComponent:(NSString *)chosenComponent;
创建一个将用户的选择情况显示出来的方法(源视图.M中)
- (void)displayAnimal:(NSString *)chosenAnimal withSound:(NSString *)chosenSound fromComponent:(NSString *)chosenComponent {
NSString *animalSoundString;
animalSoundString=[[NSString alloc]
initWithFormat:@"You changed %@ (%@ and the sound %@)",
chosenComponent,chosenAnimal,chosenSound];
self.outputLabel.text=animalSoundString;
}
目的控制器。m文件中 实现方法
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {
ViewController *initialView;
initialView=(ViewController *)self.delegate;
if (component==kAnimalComponent) {
int chosenSound=[pickerView selectedRowInComponent:kSoundComponent]; //添加这行的原因是,- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row 方法只能指定最后用户选到的选项而不能收集到所有的状态
inComponent:(NSInteger)component {
[initialView displayAnimal:[self.animalNames objectAtIndex:row]
withSound:[self.animalSounds objectAtIndex:chosenSound]
fromComponent:@"the Animal"];
} else {
int chosenAnimal=[pickerView selectedRowInComponent:kAnimalComponent];
[initialView displayAnimal:[self.animalNames objectAtIndex:chosenAnimal]
withSound:[self.animalSounds objectAtIndex:row]
fromComponent:@"the Sound"];
}
}
指定默认情况(目的控制器.m)
-(void)viewDidAppear:(BOOL)animated {
ViewController *initialView;
initialView=(ViewController *)self.delegate;
[initialView displayAnimal:[self.animalNames objectAtIndex:0]
withSound:[self.animalSounds objectAtIndex:0]
fromComponent:@"nothing yet..."];
}