Swift之时间选择器

先看效果:

屏幕快照 2017-04-07 上午11.57.23.png

首先,把控件的尺寸和间距写成宏,方便后续修改

import UIKit
fileprivate let kGaoJianLongScreenWidth: CGFloat = UIScreen.main.bounds.size.width
fileprivate let kGaoJianLongScreenHeight: CGFloat = UIScreen.main.bounds.size.height

fileprivate let kGaoJianLongWidthScale: CGFloat = 375.0
fileprivate let kGaoJianLongHeightScale: CGFloat = 667.0

//弹窗距离左右边距
fileprivate let kGaoJianLongSpaceLeftOrRight: CGFloat = 35
//弹窗距离上边距
fileprivate let kGaoJianLongSpaceTop: CGFloat = 114
//弹窗宽度
fileprivate let kGaoJianLongPopView_Width: CGFloat = kGaoJianLongScreenWidth - (kGaoJianLongSpaceLeftOrRight * 2)
//弹窗高度
fileprivate let kGaoJianLongPopView_Height: CGFloat = 220
//时间选择器的高度
fileprivate let kGaoJianLongDatePicker_Height: CGFloat = 200

声明属性(类似视图类的属性用懒加载的方式较好些)

    // 代理属性
    var delegate : JLBTimePopViewDelegate?
    
    // MARK: 属性
    fileprivate lazy var coverView : UIView = {
        let v = UIView()
        v.frame = CGRect.init(x: 0, y: 0, width: kGaoJianLongScreenWidth, height: kGaoJianLongScreenHeight)
        v.backgroundColor = UIColor.black
        v.alpha = 0
        
        return v
    }()
    
    fileprivate lazy var popView : UIView = {
        let v = UIView()
        v.frame = CGRect.init(x: kGaoJianLongSpaceLeftOrRight, y: kGaoJianLongSpaceTop, width: kGaoJianLongPopView_Width, height: kGaoJianLongPopView_Height)
        v.backgroundColor = UIColor.white
        v.layer.masksToBounds = true;
        v.layer.cornerRadius = 10;
        v.alpha = 0
        
        return v
    }()
    
    fileprivate lazy var startBtn: UIButton = {
        let btn = UIButton.init(type: .custom)
        btn.setTitleColor(JLBTimePopView.kRgbColor(r: 51, g: 51, b: 51), for: .normal)
        btn.setTitleColor(JLBTimePopView.kRgbColor(r: 15, g: 156, b: 254), for: .selected)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 17);
        btn.titleLabel?.textAlignment = .right;
        btn.addTarget(self, action: #selector(startBtnAction(btn:)), for: .touchUpInside)
        
        let date = self.datePicker.date
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        let titleString = dateFormatter.string(from: date)
        btn.setTitle(titleString, for: .normal)
        
        btn.isSelected = true
        return btn
    }()
 
    fileprivate lazy var endBtn: UIButton = {
        let btn = UIButton.init(type: .custom)
        btn.setTitleColor(JLBTimePopView.kRgbColor(r: 51, g: 51, b: 51), for: .normal)
        btn.setTitleColor(JLBTimePopView.kRgbColor(r: 15, g: 156, b: 254), for: .selected)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 17)
        btn.titleLabel?.textAlignment = .left
        btn.addTarget(self, action: #selector(endBtnAction(btn:)), for: .touchUpInside)
        
        btn.setTitle("2016-09-30", for: .normal)
        return btn
    }()
    
    fileprivate lazy var cancelBtn: UIButton = {
        let btn = UIButton.init(type: .custom)
        btn.frame = CGRect.init(x: 0, y: self.popView.frame.height - 49, width: (self.popView.frame.width - 1) / 2.0, height: 49)
        btn.setTitle("取消", for: .normal)
        btn.setTitleColor(JLBTimePopView.kRgbColor(r: 51, g: 51, b: 51), for: .normal)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
        btn.addTarget(self, action: #selector(cancelBtnAction), for: .touchUpInside)

        return btn
    }()
    
    fileprivate lazy var confirmBtn: UIButton = {
        let btn = UIButton.init(type: .custom)
        let x: CGFloat = self.popView.frame.width - self.cancelBtn.frame.width - 1
        let y: CGFloat = self.popView.frame.height - 49
        let w: CGFloat = (self.popView.frame.width - 1) / 2.0
        let h: CGFloat = 49
        btn.frame = CGRect.init(x: x, y: y, width: w, height: h)
        btn.setTitle("确定", for: .normal)
        btn.setTitleColor(JLBTimePopView.kRgbColor(r: 51, g: 51, b: 51), for: .normal)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
        btn.addTarget(self, action: #selector(confirmBtnAction), for: .touchUpInside)
        
        return btn
    }()
    
    fileprivate var datePicker: UIDatePicker = UIDatePicker()

初始化

class JLBTimePopView: UIView {
       
    override init(frame: CGRect)
    {
        super.init(frame: frame)
        
        UIApplication.shared.keyWindow?.addSubview(self)
        self.frame = self.superview?.bounds ?? UIScreen.main.bounds
        
        self.addSubview(coverView)
        self.addSubview(datePicker)
        self.addSubview(popView)
        
        setDatePickerStyle()
        setPopView()
    }

    required init?(coder aDecoder: NSCoder)
    {
        fatalError("init(coder:) has not been implemented")
    }

    class func shareTimePopView() -> JLBTimePopView
    {
        return JLBTimePopView.init(frame: UIScreen.main.bounds)
    }
     
    class func showPopView(delegate:JLBTimePopViewDelegate) -> JLBTimePopView
    {
        let popView = JLBTimePopView.shareTimePopView()
        popView.delegate = delegate
        popView.show()
        
        return popView
    }
 
    class func showPopView(delegate: JLBTimePopViewDelegate, startDate: String, endDate: String) -> JLBTimePopView
    {
        let popView = JLBTimePopView.shareTimePopView()
        popView.delegate = delegate
        
        let formatter = DateFormatter()
        formatter.setLocalizedDateFormatFromTemplate("yyyy-MM-dd")
        let date = formatter.date(from: startDate)
        
        popView.datePicker.setDate(date ?? popView.datePicker.date, animated: false)
        popView.startBtn.setTitle(startDate, for: .normal)
        popView.endBtn.setTitle(endDate, for: .normal)
        
        popView.show()
        return popView
    }
    
    fileprivate func show()
    {
        UIView.animate(withDuration: 0.25, animations: { [weak self] in
            self?.coverView.alpha = 0.5;
            self?.popView.alpha = 1;
            self?.datePicker.alpha = 1;
        }) { (finished) in
            
        }
    }
    
    fileprivate func dismiss()
    {
        UIView.animate(withDuration: 0.25, animations: { [weak self] in
            self?.coverView.alpha = 0;
            self?.popView.alpha = 0;
            self?.datePicker.alpha = 0;
        }) { (finished) in
            self.removeFromSuperview()
        }
    }
}

swift中类方法的声明,在func标识符之前加一个class即可

//类方法
    class func shareTimePopView() -> JLBTimePopView
    {
        return JLBTimePopView.init(frame: UIScreen.main.bounds)
    }

对象方法的声明,直接用func标识即可

//实例方法
    func startBtnAction(btn: UIButton)
    {
        btn.isSelected = true
        endBtn.isSelected = false
        
        rollCurrentDate(btn: btn)
    }

苹果官方建议,把数据源代理方法单独写到一个扩展中,以便提高代码的可读性
在这里,我把自定义的一些私有方法写在了扩展中,同样是为了提高代码可读性
格式如下:

extension + 类名 { 
}

extension JLBTimePopView {

}

extension JLBTimePopView {
    
    fileprivate class func kRgbColor(r: CGFloat, g: CGFloat, b: CGFloat) -> UIColor
    {
        return UIColor.init(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1)
    }
    
    fileprivate func rollCurrentDate(btn: UIButton)
    {
        let dateStr: String? = btn.currentTitle
        let formatter: DateFormatter = DateFormatter()
        formatter.setLocalizedDateFormatFromTemplate("yyyy-MM-dd")
        
        let date: Date = formatter.date(from: dateStr ?? "2017-06-06")!
        datePicker.setDate(date, animated: true)
    }
    
    /// 设置日期选择器相关属性
    fileprivate func setDatePickerStyle()
    {
        datePicker.alpha = 0
        datePicker.frame = CGRect.init(x: 0, y: kGaoJianLongScreenHeight - kGaoJianLongDatePicker_Height + 20, width: kGaoJianLongScreenWidth, height: kGaoJianLongDatePicker_Height)
        datePicker.backgroundColor = UIColor.white
        datePicker.datePickerMode = .date;
        
        let minDate: Date = Date.init(timeIntervalSince1970: 60 * 60)
        let maxDate: Date = Date.init(timeIntervalSinceNow: 60 * 60)
        
        datePicker.minimumDate = minDate
        datePicker.maximumDate = maxDate
        
        datePicker.addTarget(self, action: #selector(datePicekerValueChanged(picker:)), for: .valueChanged)
    }
    
    /// 设置popView上的子控件
    fileprivate func setPopView()
    {
        //第一部分
        let titleLabel = UILabel()
        titleLabel.frame = CGRect.init(x: 0, y: 0, width: popView.frame.width, height: 50)
        titleLabel.text = "请选择统计时间"
        titleLabel.font = UIFont.systemFont(ofSize: 14)
        titleLabel.textColor = JLBTimePopView.kRgbColor(r: 153, g: 153, b: 153)
        titleLabel.textAlignment = .center;
        popView.addSubview(titleLabel)

        let topLineView = UIView()
        topLineView.frame = CGRect.init(x: 0, y: 50, width: popView.frame.width, height: 1)
        topLineView.backgroundColor = JLBTimePopView.kRgbColor(r: 242, g: 242, b: 242)
        popView.addSubview(topLineView)
        
        //第二部分
        popView.addSubview(self.startBtn)
        self.startBtn.frame = CGRect.init(x: 20, y: topLineView.frame.maxY + 20, width: (popView.frame.width - 60) / 2.0, height: popView.frame.height - 100 - 40)

        let tempLabel = UILabel()
        tempLabel.frame = CGRect.init(x: self.startBtn.frame.maxX, y: self.startBtn.frame.minY, width: 20, height: self.startBtn.frame.height)
        tempLabel.textAlignment = .center
        tempLabel.text = "至"
        tempLabel.font = UIFont.systemFont(ofSize: 14)
        tempLabel.textColor = JLBTimePopView.kRgbColor(r: 153, g: 153, b: 153)
        popView.addSubview(tempLabel)
        
        popView.addSubview(self.endBtn)
        self.endBtn.frame = CGRect.init(x: tempLabel.frame.maxX, y: self.startBtn.frame.minY, width: self.startBtn.frame.width, height: self.startBtn.frame.height)
        
        let bottomLineView = UIView()
        bottomLineView.frame = CGRect.init(x: 0, y: kGaoJianLongPopView_Height - 50, width: popView.frame.width, height: 1)
        bottomLineView.backgroundColor = JLBTimePopView.kRgbColor(r: 242, g: 242, b: 242)
        popView.addSubview(bottomLineView)
        
        //第三部分
        popView.addSubview(self.cancelBtn)
        
        let verticalLineView: UIView = UIView()
        verticalLineView.frame = CGRect.init(x: self.cancelBtn.frame.width, y: self.cancelBtn.frame.minY, width: 1, height: self.cancelBtn.frame.height)
        verticalLineView.backgroundColor = JLBTimePopView.kRgbColor(r: 242, g: 242, b: 242)
        popView.addSubview(verticalLineView)
        
        popView.addSubview(self.confirmBtn)
    }
}

使用的时候把JLBTimePopView.swift这个类拷贝到项目中,调用方式如下:

    func showNewOrder(btn: UIButton)
    {
        print("\("新订单")")
        
        _ = JLBTimePopView.showPopView(delegate: self as JLBTimePopViewDelegate)        
    }

实现代理方法,获取选中的日期时间:

extension ViewController: JLBTimePopViewDelegate 
{    
    func getStartDate(startDate: String, endDate: String)
    {
        print("开始时间:\(startDate)" + "结束时间:\(endDate)")
    }
}

项目地址:https://github.com/Fei627/SwiftDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容