IOS开发(十三):UIDatePicker、场景切换综合示例

一、创建项目

使用Single View Application创建一个项目,命名为Date。

1、添加DateChooserViewController类

    用于显示日期选择器并且在用户选择的时候作出响应,类似上个项目,添加一个新的类,Create完成。

2、添加Date Chooser场景并关联视图控制器

    在IB中打开MainStoryboard.storyboard,将一个视图控制器添加到IB的空白区域(或文档大纲区域)。为了将新增的视图控制器关联到新建的类,在文档大纲区域选择第二个场景的View Controller图标,打开属性,从Class下拉列表中选择DateChooserViewController。

二、设计界面

1、从对象库中拖动一个工具栏到第一个视图的底部,默认情况下工具栏只有一个item的按钮。双击该item,修改文字为:选择日期。接下来,从对象库中拖动2个灵活间距栏按钮项(Flexible Space Bar Button Item)到工具栏中,分别放在“选择日期”的两边,调整长短到合适即可。

2、然后在第一个视图中间添加一个Label,居中显示,设置默认文字为:“没有选择”。

3、设置第一个视图的背景色为Scroll View Texted Background Color。

4、选择第二个视图,添加一个日期选择器,一个Label,一个按钮。

三、创建切换

按住Control键,从初始视图拖动到第二个视图(直接在视图上面拉线我怎么老失败,在文档大纲区域,反而成功???),选择Modal。这时候初始场景中将增加一行,内容为Segue from UIViewController to DateChooserViewController,选择这行,打开属性,配置该切换:

给切换指定标示符:toDateChooser。由于将要手工切换,因此将标示符设置为该值很重要。

务必指定锚: 
对于在两个视图控制器之间创建的弹出切换,必须设置锚。如果不设置,程序也能运行,但是单击触发切换的按钮后,程序将崩溃。

四、创建并连接输出口和操作

1、添加输出口

    1)、选择第一个场景的输出标签,创建一个名为outputLabel的输出口,用于在第一个场景中显示日期计算结果;

2、添加操作

    1)、选择第一个场景,创建工具栏中间的“选择日期”按钮的操作showDateChooser,用于显示第二个场景;
    2)、选择第二个场景,创建日期选择器的操作setDateTime,并将触发其Value Changed事件;
    3)、选择第二个场景,创建完成按钮的操作dismissDateChooser,返回到第一个场景。

五、实现场景切换逻辑

1、导入接口文件

    在ViewController.h文件,添加如下代码:  

#import "DateChooserViewController.h"

    在新增的类的.h文件中,添加如下代码:

#import "ViewController.h"

2、创建并设置属性delegate

    除了让这两个类能互相知道对方提供的属性和方法之外,还需提供一个属性,让日期选择器视图控制器能够访问初始场景的视图控制器。

对于模态类型,可以使用DateChooserViewController的属性presentingViewController来获取初始场景的视图控制器,但是该属性不适用于ipad独有的弹出框。为了保持模态实现和弹出框的实现一致,在类DateChooserViewController.h中添加如下代码:

@property (strong, nonatomic) id delegate;

定义了一个类型为id的属性,可以指向任何对象。然后在其对应的.m文件,添加如下代码:

@synthesize delegate;

设置属性delegate:在ViewController.m中实现,当初始场景和日期选择场景之间的切换被触发时会调用这个方法。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    ((DateChooserViewController *)segue.destinationViewController).delegate = self;
}

通过上述代码,将参数segue的属性destinationViewController强制转换为一个DateChooserController,并将其delegate属性设置为self,即初始场景的ViewController类的当前实例。

属性delegate提供了一种交换信息的机制。


3、处理初始场景和日期选择场景之间的切换

    本项目中,切换是在两个视图之间,而不是前面的对象和视图控制器之间创建的。

 这称为手工切换,因为需要在方法中使用代码来触发。在触发时,首先检查是否显示了日期选择器,通过一个布尔值来判断。在ViewController.h和.m文件分别添加如下代码:

@property (nonatomic) Boolean dateChooserVisible;
@synthesize dateChooserVisible;

因为布尔型不是对象,因此不须要使用关键字strong,也不用在使用完后置为nil。

然后在ViewConyroller.m文件实现showDateChooser方法:

首先核实属性dateChooserVisible不为YES,再调用performSegueWithIdentifier:sender启动到日期选择场景的切换。然后设置布尔值为YES,以便了解当前显示了日期选择场景。

- (IBAction)showDateChooser:(id)sender {
    if(self.dateChooserVisible!=YES){
        [self performSegueWithIdentifier:@"toDateChooser"
                                  sender:sender];
        self.dateChooserVisible = YES;
    }
}

另外,在第二个场景点击确定按钮,回到第一个场景:

- (IBAction)dismissDateChooser:(id)sender {
    [self dismissViewControllerAnimated:YES
                             completion:nil];
}

六、实现日期计算逻辑

1、获取当前日期

    创建并初始化一个NSDateFormatter对象,然后使用该对象的setDateFormat方法和一个模式字符串创建一种自定义格式,最后调用NSDateFormatter的另一个方法stringFromDate将这种格式应用到日期。

2、计算两个日期相差多少天

    使用NSDate对象的实例方法timeIntervalSinceDate实现,返回两个日期相差多少秒。

3、实现日期计算和显示

    1)、在ViewController.h文件,添加如下代码:

-(void) calculateDateDifference:(NSDate *)chosenDate;

    2)、在ViewController.m文件实现:

//计算日期差值
-(void)calculateDateDifference:(NSDate *)chosenDate{
    
    NSDate *todaysDate;
    NSString *differenceOutput;
    NSString *todaysDateString;
    NSString *chosenDateString;
    NSDateFormatter *dateFormat;
    NSTimeInterval difference;
    
    //把当前日期时间存储到todaysDate
    todaysDate = [NSDate date];
    //计算时间差
    difference = [todaysDate timeIntervalSinceDate:chosenDate] / 86400;
    //创建一个新的日期格式器对象,用于格式化todaysDate和chosenDate
    dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"MMMM d, yyyy hh:mm:ssa"];
    //使用todaysDateString存储当前日期
    todaysDateString = [dateFormat stringFromDate:todaysDate];
    chosenDateString = [dateFormat stringFromDate:chosenDate];
    
    differenceOutput = [[NSString alloc] initWithFormat:
                        @"选择的日期(%@)和今天(%@)相差:%1.2f天",
                        chosenDateString,
                        todaysDateString,
                        fabs(difference)];
    self.outputLabel.text = differenceOutput;
}

4、输出更新

    在两个地方需要调用calculateDateDifference方法:用户选择日期、显示日期选择场景时。在第二种情况时,用户还没有选择日期,选择器显示的是当前日期。

    1)、对用户的操作响应:在方法setDateTime中调用,计算两个日期的差值,它在日期选择器的值发生变化时调用。在DateChooserViewController.m中实现:

- (IBAction)setDateTime:(id)sender {
    [(ViewController *)delegate calculateDateDifference:((UIDatePicker *)sender).date];
}

这样通过属性delegate来访问ViewController.m中的方法calculateDateDifference,并将日期选择器的date属性传递给这个方法。但是如果用户在没有显式地选择日期选择器的情况下返回,则不会进行日期计算。

在这种情况下,可假定用户选择的是当前日期。在DateChooserViewController.m中:

-(void)viewDidAppear:(BOOL)animated{
    [(ViewController *)self.delegate calculateDateDifference:[NSDate date]];
}

七、运行项目

原文地址:https://www.cnblogs.com/xsjayz/p/3012654.html