当前位置: 首页 > news >正文

swift 自定义DatePacker

请添加图片描述

import Foundationenum AppDatePickerStyle {case KDatePickerDate    //年月日case KDatePickerTime    //年月日时分case kDatePickerMonth // 年月case KDatePickerSecond  //秒}class AppDatePicker: UIView {private let jk_rootView = UIApplication.shared.keyWindow!private var jk_backgroundView: UIView!private var confirmHandler: (( _ year: Int, _ month: Int,_ day: Int) -> Void)?//选择的回调var cancelHandler: (() -> Void)?//取消的回调/// 选择器类型fileprivate var datePickerStyle: AppDatePickerStyle!/// 时间数据fileprivate var unitFlags:Set<Calendar.Component>!var pickerView = UIPickerView()//数据相关fileprivate var yearRange = 30 + 1000//年的范围fileprivate var dayRange = 0 //fileprivate var startYear = 0// 当前选中日期fileprivate var selectedYear = 0;fileprivate var selectedMonth = 0;fileprivate var selectedDay = 0;fileprivate var selectedHour = 0;fileprivate var selectedMinute = 0;fileprivate var selectedSecond = 0;override init(frame: CGRect) {super.init(frame: frame)}convenience init(title: String = "选择日期", type: AppDatePickerStyle, confirmHandler: @escaping (_ year:Int,_ month:Int,_ day:Int) -> Void) {self.init(frame: .zero)configUI()self.confirmHandler = confirmHandlerjk_titleLabel.text = titleinitDatePickerWithType(type: type)}convenience init(title: String = "选择日期", year: Int, month: Int, day: Int, confirmHandler: @escaping (_ year:Int,_ month:Int,_ day:Int) -> Void) {self.init(frame: .zero)configUI()self.confirmHandler = confirmHandlerjk_titleLabel.text = titleinitDatePickerWithType(type: .kDatePickerMonth, date: year == -1 ? nil:Date.dateFor("\(year)-\(month)-\(day)"))}private func getHeight() -> CGFloat {return CGFloat(56 + 4 * 50 + 56)}// MARK: - UIButtonAction@objc private func confimBtnAction() {if let holder = confirmHandler {holder(selectedYear, selectedMonth, selectedDay)}hide()}// MARK: - configUIfunc configUI() {// 防止多个 AlertView 重复显示if jk_rootView.subviews.filter({ $0.isKind(of: AppDatePicker.self) }).count > 0 { return }jk_backgroundView = UIView()jk_backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0)jk_rootView.addSubview(jk_backgroundView)jk_rootView.addSubview(self)addSubview(jk_backView)jk_backView.addSubview(cornerBackView)cornerBackView.addSubview(jk_titleLabel)cornerBackView.addSubview(pickerView)cornerBackView.addSubview(jk_cancelBtn)cornerBackView.addSubview(conformBtn)cornerBackView.addSubview(verticalLineView)jk_backgroundView.snp.makeConstraints { (make) inmake.edges.equalTo(jk_rootView)}let height = getHeight()snp.makeConstraints { make inmake.left.right.equalToSuperview()make.height.equalTo(height + Size.safeAreaBottomGap)make.bottom.equalTo(height + Size.safeAreaBottomGap)}jk_backView.snp.makeConstraints { make inmake.edges.equalToSuperview()}cornerBackView.snp.makeConstraints { make inmake.left.top.right.equalToSuperview()make.height.equalTo(height)}jk_titleLabel.snp.makeConstraints { make inmake.height.equalTo(40)make.top.equalTo(16)make.left.right.equalToSuperview()}pickerView.snp.makeConstraints { make inmake.top.equalTo(jk_titleLabel.snp.bottom)make.left.right.equalToSuperview()make.height.equalTo(50 * 4)}jk_cancelBtn.snp.makeConstraints { make inmake.height.equalTo(56)make.top.equalTo(pickerView.snp.bottom)make.left.equalToSuperview()make.width.equalToSuperview().multipliedBy(0.5)}conformBtn.snp.makeConstraints { make inmake.right.equalToSuperview()make.centerY.height.width.equalTo(jk_cancelBtn)}verticalLineView.snp.makeConstraints { make inmake.height.equalTo(20)make.width.equalTo(1)make.centerY.equalTo(jk_cancelBtn)make.centerX.equalToSuperview()}self.jk_rootView.layoutIfNeeded()let tapGR = UITapGestureRecognizer.init(target: self, action: #selector(hideAction))jk_backgroundView.addGestureRecognizer(tapGR)jk_cancelBtn.addTarget(self, action: #selector(hideAction), for: .touchUpInside)conformBtn.addTarget(self, action: #selector(confimBtnAction), for: .touchUpInside)pickerView.delegate = selfpickerView.dataSource = self}private lazy var jk_backView: UIView = {let jk_backView = UIView()jk_backView.backgroundColor = .whitereturn jk_backView}()private lazy var cornerBackView: UIView = {let cornerBackView = UIView()cornerBackView.backgroundColor = .whitereturn cornerBackView}()private lazy var jk_titleLabel: UILabel = {let jk_titleLabel = UILabel()jk_titleLabel.textAlignment = .centerjk_titleLabel.font = kSetPingFangMedium(18)return jk_titleLabel}()private lazy var jk_cancelBtn: UIButton = {let jk_cancelBtn = UIButton()jk_cancelBtn.setTitle("取消", for: .normal)jk_cancelBtn.setTitleColor( .black, for: .normal)return jk_cancelBtn}()private lazy var verticalLineView: UIView = {let verticalLineView = UIView()verticalLineView.backgroundColor = .jky_viewBackgroundColorreturn verticalLineView}()private lazy var conformBtn: UIButton = {let conformBtn = UIButton()conformBtn.setTitle("确定", for: .normal)conformBtn.setTitleColor( .black, for: .normal)return conformBtn}()required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)fatalError("init(coder:) has not been implemented")}
}//MARK:初始化数据
extension AppDatePicker {fileprivate func initDatePickerWithType(type: AppDatePickerStyle, date: Date? = nil)  {datePickerStyle = typelet  calendar0 = Calendar.init(identifier: .gregorian)//公历var comps = DateComponents()//一个封装了具体年月日、时秒分、周、季度等的类unitFlags = [.year , .month , .day]switch  datePickerStyle {case .KDatePickerDate:breakcase .KDatePickerTime:unitFlags = [.year , .month , .day , .hour , .minute ]case .kDatePickerMonth:unitFlags = [.year , .month]case .KDatePickerSecond:unitFlags = [.year , .month , .day , .hour , .minute ,.second]default:break}//        comps = calendar0.dateComponents(unitFlags, from: date != nil ? date! : Date())comps = calendar0.dateComponents(unitFlags, from: date != nil ? date!:Date())startYear = comps.year! - 100dayRange = self.isAllDay(year: startYear, month: 1)yearRange = 30 + 1000;selectedYear = comps.year!;selectedMonth = comps.month!;self.pickerView.selectRow(selectedYear - startYear, inComponent: 0, animated: true)self.pickerView.selectRow(selectedMonth - 1, inComponent: 1, animated: true)if datePickerStyle != .kDatePickerMonth {selectedDay = comps.day!;self.pickerView.selectRow(selectedDay - 1, inComponent: 2, animated: true)}switch  datePickerStyle {case .KDatePickerDate:breakcase .KDatePickerTime:selectedHour = comps.hour!;selectedMinute = comps.minute!;self.pickerView.selectRow(selectedHour , inComponent: 3, animated: true)self.pickerView.selectRow(selectedMinute , inComponent: 4, animated: true)case .KDatePickerSecond:selectedHour = comps.hour!;selectedMinute = comps.minute!;selectedSecond = comps.second!;self.pickerView.selectRow(selectedHour , inComponent: 3, animated: true)self.pickerView.selectRow(selectedMinute , inComponent: 4, animated: true)self.pickerView.selectRow(selectedSecond, inComponent: 5, animated: true)default:break}self.pickerView.reloadAllComponents()}//MARK:计算每个月有多少天fileprivate func isAllDay(year:Int, month:Int) -> Int {var   day:Int = 0switch(month){case 1,3,5,7,8,10,12:day = 31case 4,6,9,11:day = 30case 2:if(((year%4==0)&&(year%100==0))||(year%400==0)){day=29}else{day=28;}default:break;}return day;}}extension AppDatePicker : UIPickerViewDelegate,UIPickerViewDataSource {//返回UIPickerView当前的列数func numberOfComponents(in pickerView: UIPickerView) -> Int {return unitFlags == nil ? 0 : unitFlags.count}//确定每一列返回的东西func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {switch component {case 0:return yearRangecase 1:return 12case 2:return dayRangecase 3:return 24case 4:return 60case 5:return 60default:return 0}}func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {return 45}//返回一个视图,用来设置pickerView的每行显示的内容。func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {let label  = UILabel(frame: CGRect(x: screenWidth * CGFloat(component) / 6 , y: 0, width: screenWidth/6, height: 50))label.font = UIFont.boldSystemFont(ofSize: CGFloat(16))label.tag = component*100+rowlabel.textAlignment = .centerswitch component {case 0:label.frame=CGRect(x:5, y:0,width:screenWidth/4.0, height:50);label.text="\(self.startYear + row)年";case 1:label.frame=CGRect(x:screenWidth/4.0, y:0,width:screenWidth/8.0, height:50);label.text="\(row + 1)月";case 2:label.frame=CGRect(x:screenWidth*3/8, y:0,width:screenWidth/8.0, height:50);label.text="\(row + 1)日";case 3:label.textAlignment = .rightlabel.text="\(row )时";case 4:label.textAlignment = .rightlabel.text="\(row )分";case 5:label.textAlignment = .rightlabel.frame=CGRect(x:screenWidth/6, y:0,width:screenWidth/6.0 - 5, height:50);label.text="\(row )秒";default:label.text="\(row )秒";}return label}//当点击UIPickerView的某一列中某一行的时候,就会调用这个方法func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {switch component {case 0:self.selectedYear = self.startYear + rowself.dayRange = self.isAllDay(year: self.startYear, month: self.selectedMonth)if datePickerStyle != .kDatePickerMonth {self.pickerView.reloadComponent(2)}case 1:self.selectedMonth =  row + 1self.dayRange = self.isAllDay(year: self.startYear, month: self.selectedMonth)if datePickerStyle != .kDatePickerMonth {self.pickerView.reloadComponent(2)}case 2:selectedDay = row + 1case 3:selectedHour = rowcase 4:selectedMinute = rowcase 5:selectedSecond = rowdefault:selectedSecond = row}}}extension AppDatePicker: UIGestureRecognizerDelegate {func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {if let view = touch.view, view.isDescendant(of: pickerView) {return false}return true}func show() {self.jk_backView.layerCornerRadius(16, [.topLeft,.topRight])UIView.animate(withDuration: 0.2, animations: {self.jk_backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.5)self.snp.updateConstraints { make inmake.bottom.equalTo(0)}self.jk_rootView.layoutIfNeeded()})}@objc private func hideAction() {if let holder = cancelHandler {holder()}hide()}private func hide(completion: (() -> Void)? = nil) {UIView.animate(withDuration: 0.2, animations: {self.jk_backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0)self.snp.updateConstraints { make inmake.bottom.equalTo(self.getHeight() + Size.safeAreaBottomGap)}self.jk_rootView.layoutIfNeeded()}) { finished inguard finished else { return }self.removeFromSuperview()self.jk_backgroundView.removeFromSuperview()}}}

相关文章:

swift 自定义DatePacker

import Foundationenum AppDatePickerStyle {case KDatePickerDate //年月日case KDatePickerTime //年月日时分case kDatePickerMonth // 年月case KDatePickerSecond //秒}class AppDatePicker: UIView {private let jk_rootView UIApplication.shared.keyWindow!pri…...

MySQL事务,锁,MVCC总结

mysql中最重要的就是事务&#xff0c;其四大特性让我们维持了数据的平衡&#xff0c;一致。那么事务究竟是什么&#xff0c;与什么相关&#xff0c;他的使用步骤&#xff0c;以及使用过程中我们会遇到什么问题呢&#xff1f;下面我们一起学习交流! 1.MySQL的存储引擎&#xff…...

24/8/7 算法笔记 支持向量机回归问题天猫双十一

import numpy as np from sklearn.svm import SVR import matplotlib.pyplot as plt X np.linspace(0,2*np.pi,50).reshape(-1,1) y np.sin(X) plt.scatter(X,y) 建模 线性核函数 svr SVR(kernel linear) svr.fit(X,y.ravel())#变成一维y_ svr.predict(X) plt.scatter(…...

win7系统利用定时启动+脚本实现MySQL文件自动备份

前言 最近接到项目&#xff0c;数据量不大但对运行数据的安全性要求极高&#xff0c;为避免因不可抗拒因素导致的数据丢失&#xff0c;选择机械硬盘作为数据存储盘&#xff0c;并使用脚本方式对文件进行备份 一、脚本 下面为自动备份文件的 脚本&#xff0c;可根据自身情况进…...

基于Java多线程处理数据

基于Java多线程处理数据 背景代码实现 背景 在日常工作中&#xff0c;有一个同步企微客户-学员关系接口的定时任务在执行中随着数据量的不断增长&#xff0c;定时任务的执行结束时间也出现了当天执行不完的情况&#xff0c;影响到了正常业务的运行。基于这种情况&#xff0c;在…...

日常知识点之遇到问题结构体按位构造协议时和期望不一致,研究记录一下

遇到一个问题&#xff0c;在做业务的时候&#xff0c;涉及到协议相关&#xff0c;按位进行设计&#xff0c;用结构体来模拟协议时&#xff0c;发现内存存储和实际目的不一致&#xff0c;知道是大小端以及计算机底层存储逻辑相关&#xff0c;所以研究了一下。 1&#xff1a;简单…...

spring mvc 文件下载

在web中下载的方式大多基于servlet&#xff0c;在web.xml中配置下载路径&#xff0c;这里再介绍json(转成base64字符串)和blob的使用方式 servlet WEB-INF/web.xml <!--url映射--> <servlet-mapping><servlet-name>DowloadServlet</servlet-name>&l…...

Qt WebEngine基于WebEngineScript注入js脚本

在之前的文章中&#xff0c;我们介绍了Qt WebEngine注入js的用法&#xff0c;及runJavaScript()的用法&#xff0c;该方法主要是用在页面加载完成后&#xff0c;为了和网页做一些交互时使用。有时候需要监听网页加载完成的一些状态或信息&#xff0c;则需要网页加载前注入js来实…...

案例分享-国外UI设计界面赏析

国外UI设计倾向于简洁的布局和清晰的排版&#xff0c;减少视觉干扰&#xff0c;提升用户体验。通过合理的色彩搭配和图标设计&#xff0c;营造舒适愉悦的使用氛围。 设计师不拘泥于传统框架&#xff0c;勇于尝试新元素和理念&#xff0c;使界面独特有趣。同时&#xff0c;强调以…...

用PyTorch 从零开始构建 BitNet 1.58bit

我们手动实现BitNet的编写&#xff0c;并进行的一系列小实验证实&#xff0c;看看1.58bit 模型是否与全精度的大型语言模型相媲美&#xff01; 什么是量化以及为什么需要它&#xff1f; 量化是用更少的比特数表示浮点数的过程。当两个数字使用不同的比特数进行量化时&#xf…...

信创安全 | 新一代内网安全方案—零信任沙盒

在当今数字化时代&#xff0c;访问安全和数据安全成为企业面临的重要挑战。传统的边界防御已经无法满足日益复杂的内网办公环境&#xff0c;层出不穷的攻击手段已经让市场单一的防御手段黔驴技穷。当企业面临越来越复杂的网络威胁和数据泄密风险时&#xff0c;更需要一种综合的…...

Redis的回收策略(淘汰策略)

volatile-lru &#xff1a;从已设置过期时间的数据集&#xff08; server.db[i].expires &#xff09;中挑选最近最少使用的数据淘汰 volatile-ttl &#xff1a; 从已设置过期时间的数据集&#xff08; server.db[i].expires &#xff09; 中挑选将要过期的数据淘汰 volatile…...

Electron-builder 打包

项目比较简单&#xff0c;仅使用了 Electron 原生js 安装 electron-builder npm install electron-builder --dev配置 package.json 中的打包命令 {"script":{// ..."dev": "electron .","pack": "electron-builder"} }添…...

笔试练习day3

目录 BC149 简写单词题目解析代码 dd爱框框题目解析解析代码方法一暴力解法方法二同向双指针(滑动窗口) 除2!题目解析解法模拟贪心堆 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1…...

企业想要将大模型技术应用到企业管理中需具备什么条件?

#企业 #企业管理 #大模型 企业想要将大模型技术应用到企业管理中&#xff0c;需要考虑以下几个关键条件&#xff1a; 1.明确的需求定位&#xff1a;企业应首先诊断自身的业务场景、数据、算法、基础设施预算以及战略等能力&#xff0c;明确大模型能够为企业带来的具体赋…...

go 事件机制(观察者设计模式)

背景&#xff1a; 公司目前有个业务&#xff0c;收到数据后&#xff0c;要分发给所有的客户端或者是业务模块&#xff0c;类似消息通知这样的需求&#xff0c;自然而然就想到了事件&#xff0c;观察者比较简单就自己实现以下&#xff0c;确保最小功能使用支持即可&#xff0c;其…...

RISC-V竞赛|第二届 RISC-V 软件移植及优化锦标赛报名正式开始!

目录 赛事背景 赛道方向 适配夺旗赛 优化竞速赛 比赛赛题&#xff08;总奖金池8万元&#xff01;&#xff09; &#x1f525;竞速赛 - OceanBase 移植与优化 比赛赛程&#xff08;暂定&#xff09; 赛事说明 「赛事背景」 为了推动 RISC-V 软件生态更快地发展&#xff0…...

【VTK】ubuntu手动编译VTK9.3 Generating qmltypes file 失败

环境 硬件&#xff1a;Jetson Xavier NX 套件 系统&#xff1a;Ubuntu 20.04 软件 &#xff1a;QT5.15.6 解决 0、问题 最近在Jetson Xavier NX 套件上编译VTK库&#xff0c;因为想要配合QQuick使用&#xff0c;所以cmake配置时勾选了VTK_MODULE_ENABLE_VTK_GUISupportQtQu…...

学习java的日子 Day64 学生管理系统 web2.0 web版本

MVC设计模式 概念 - 代码的分层 MVC&#xff1a;项目分层的思想 字母表示层理解MModle模型层业务的具体实现VView视图层展示数据CController控制器层控制业务流程&#xff08;跳转&#xff09; 1.细化理解层数 Controller&#xff1a;控制器层&#xff0c;用于存放Servlet&…...

【第14章】Spring Cloud之Gateway路由断言(IP黑名单)

文章目录 前言一、内置路由断言1. 案例&#xff08;Weight&#xff09;2. 更多断言 二、自定义路由断言1. 黑名单断言2. 全局异常处理3. 应用配置4. 单元测试 总结 前言 Spring Cloud Gateway可以让我们根据请求内容精确匹配到对应路由服务,官方已经内置了很多路由断言,我们也…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

基于Uniapp的HarmonyOS 5.0体育应用开发攻略

一、技术架构设计 1.混合开发框架选型 &#xff08;1&#xff09;使用Uniapp 3.8版本支持ArkTS编译 &#xff08;2&#xff09;通过uni-harmony插件调用原生能力 &#xff08;3&#xff09;分层架构设计&#xff1a; graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...