• 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]];
    }

    七、运行项目

  • 相关阅读:
    详解threading模块:Condition类的使用
    concurrent.futures 模块使用说明
    细读Spring源码(四)什么是IOC?
    OAuth 2.0系列(六) OAuth令牌
    OAuth 2.0系列(七) OAuth 2.0可能存在的安全漏洞及预防方法
    细读Spring源码(一)refresh()方法概览
    HashMap源码解读() put方法的实现过程
    跟着字节码追踪JAVA中的基本运算
    细读Spring源码(六)Spring源码设计架构
    细读Spring源码(五)AOP从实战到源码
  • 原文地址:https://www.cnblogs.com/xsjayz/p/3012654.html
Copyright © 2020-2023  润新知