Swift.日期选择器

作者: 王四猫 | 来源:发表于2018-08-30 10:16 被阅读10次
    效果图

    实现效果:

    controller弹出时:半透明背景渐变展示.时间选择器从下方弹出.选择器日期滚动到当前日期.

    点击确认进行将数据回调到上一控制器,点击页面空白区域退出controller.

    controller消失时:背景渐变消失,时间选择器向下退出.

    实现方式:

    1.首先写一个ViewController,将DatePicker加入.

    2.实现DatePicker的展示效果与功能.

    3.修改viewController的背景色,使其半透明.

    4.实现我们需要的转场视图动画.

    5.修改ViewController的transitioningDelegate,使其使用我们重写的转场视图动画.


    1.首先写一个ViewController,将DatePicker加入.

            let cancel = UIButton(frame: CGRect(x: 0, y: 10, width: 70, height: 20))
            let sure = UIButton(frame: CGRect(x: ScreenInfo.Width - 80, y: 10, width: 70, height: 20))
            cancel.setTitle("取消", for: .normal)
            sure.setTitle("确认", for: .normal)
            cancel.setTitleColor(UIColor.colorWithRGBA(r: 255, g: 51, b: 102, a: 1), for: .normal)
            sure.setTitleColor(UIColor.colorWithRGBA(r: 255, g: 51, b: 102, a: 1), for: .normal)
            cancel.addTarget(self, action: #selector(self.onClickCancel), for: .touchUpInside)
            sure.addTarget(self, action: #selector(self.onClickSure), for: .touchUpInside)
            picker = UIPickerView(frame: CGRect(x: 0, y: 24, width: ScreenInfo.Width, height: 216))
            picker.delegate = self
            picker.dataSource = self
            picker.backgroundColor = UIColor.clear
            picker.clipsToBounds = true//如果子视图的范围超出了父视图的边界,那么超出的部分就会被裁剪掉。
            //创建日期选择器
            self.containV.addSubview(cancel)
            self.containV.addSubview(sure)
            self.containV.addSubview(picker)
            self.view.addSubview(self.containV)
    

    2.实现DatePicker的展示效果与功能.

      //MARK: - PickerViewDelegate
    extension EWDatePickerViewController:UIPickerViewDelegate,UIPickerViewDataSource {
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 3
        }
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            if component == 0 {
                return 10
            }else if component == 1 {
                return 12
            }else {
                let year: Int = pickerView.selectedRow(inComponent: 0) + currentDateCom.year!
                let month: Int = pickerView.selectedRow(inComponent: 1) + 1
                let days: Int = howManyDays(inThisYear: year, withMonth: month)
                return days
            }
        }
        private func howManyDays(inThisYear year: Int, withMonth month: Int) -> Int {
            if (month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12) {
                return 31
            }
            if (month == 4) || (month == 6) || (month == 9) || (month == 11) {
                return 30
            }
            if (year % 4 == 1) || (year % 4 == 2) || (year % 4 == 3) {
                return 28
            }
            if year % 400 == 0 {
                return 29
            }
            if year % 100 == 0 {
                return 28
            }
            return 29
        }
        func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
            return ScreenInfo.Width / 3
        }
        func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
            return 40
        }
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            if component == 0 {
                return "\((currentDateCom.year!) + row)\("年")"
            }else if component == 1 {
                return "\(row + 1)\("月")"
            }else {
                return "\(row + 1)\("日")"
            }
        }
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            if component == 1 {
                pickerView.reloadComponent(2)
            }
        }
    }
    

    3.修改viewController的背景色,使其半透明.

            var backgroundView:UIView = {
                let view = UIView()
                view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
                return view
            }()
            self.view.backgroundColor = UIColor.clear
            self.view.insertSubview(self.backgroundView, at: 0)
            self.modalPresentationStyle = .custom//viewcontroller弹出后之前控制器页面不隐藏 .custom代表自定义
    

    4.实现我们需要的转场视图动画.

       //EWDatePickerViewController的推出和取消动画
    class EWDatePickerPresentAnimated: NSObject,UIViewControllerAnimatedTransitioning {
    
        var type: EWDatePickerPresentAnimateType = .present
    
        init(type: EWDatePickerPresentAnimateType) {
            self.type = type
        }
        /// 动画时间
        func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
            return 0.3
        }
        /// 动画效果
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    
            switch type {
            case .present:
                let toVC : EWDatePickerViewController = transitionContext.viewController(forKey: .to) as! EWDatePickerViewController
                let toView = toVC.view
    
                let containerView = transitionContext.containerView
                containerView.addSubview(toView!)
    
                toVC.containV.transform = CGAffineTransform(translationX: 0, y: (toVC.containV.frame.height))
    
                UIView.animate(withDuration: 0.25, animations: {
                    /// 背景变色
                    toVC.backgroundView.alpha = 1.0
                    /// datepicker向上推出
                    toVC.containV.transform =  CGAffineTransform(translationX: 0, y: -10)
                }) { (finished) in
                    UIView.animate(withDuration: 0.2, animations: {
                        /// transform初始化
                        toVC.containV.transform = CGAffineTransform.identity
                    }, completion: { (finished) in
                        transitionContext.completeTransition(true)
                    })
                }
            case .dismiss:
                let toVC : EWDatePickerViewController = transitionContext.viewController(forKey: .from) as! EWDatePickerViewController
    
                UIView.animate(withDuration: 0.25, animations: {
                    toVC.backgroundView.alpha = 0.0
                    /// datepicker向下推回
                    toVC.containV.transform =  CGAffineTransform(translationX: 0, y: (toVC.containV.frame.height))
                }) { (finished) in
                    transitionContext.completeTransition(true)
                }
            }
        }
    }
    

    5.修改ViewController的transitioningDelegate,使其使用我们重写的转场视图动画.

    //MARK: - 转场动画delegate
    extension EWDatePickerViewController:UIViewControllerTransitioningDelegate{
        func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            let animated = EWDatePickerPresentAnimated(type: .present)
            return animated
        }
        func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            let animated = EWDatePickerPresentAnimated(type: .dismiss)
            return animated
        }
    }
    

    demo地址:https://github.com/WangLiquan/EWDatePicker.求star

    有问题欢迎探讨.

    相关文章

      网友评论

        本文标题:Swift.日期选择器

        本文链接:https://www.haomeiwen.com/subject/mubfwftx.html