暑期项目开发实训 Day24
来源:互联网 发布:ubuntu的浏览器字体 编辑:程序博客网 时间:2024/06/03 12:59
周三:
今天终于算是大功告成了?上午吃包子的时间突然灵机一动,解决了很多问题。(历史遗留问题)
吃包子前解决的controller问题,已经写在上午9点的博客里了。下面说说问题。
toggle问题:
去掉willSelectRowAt
// 不需要实现 // func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { // }
推送问题:
1. done时要调用 scheduleNotification
@IBAction func done() { // 创建 item let item = ChecklistItem() item.text = textField.text! item.checked = false// item.shouldRemind = true item.dueDate = dueDate item.scheduleNotification() //推送通知
/** 设置提醒 **/ func shouldRemindToggled(_ reminder: Bool) { if reminder { let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .sound]) { granted, error in } } }
下午是我心心念的商业逻辑问题:
1. 用户一周内上线
2. 用户隔一周上线
3. 用户长久未上线
解决方案如下:
这里涉及到了Swift语言的值拷贝和引用拷贝 (深拷贝和浅拷贝的问题)还是比较有意思的。
/** 时间变更判断策略 用户下一次进入时 根据现实世界的时间变化 推算出list是否需要更新 **/ func judgeTime() { let jweek = (lists[0].weekID == Main.Variables.weekID_this) //判断周相同 let jnext = (lists[1].weekID == Main.Variables.weekID_this) //判断是否恰好隔了一周 let jmonth = (lists[0].monthID == Main.Variables.monthID_this) //判断月相同 let jyear = (lists[0].yearID == Main.Variables.yearID_this) //判断年相同 //策略A: 下周变这周,下周清空 if jnext && jmonth && jyear { lists[0] = lists[1] //copy 可变集合中的对象是浅拷贝,集合本身是深拷贝 lists[1] = Variables.nextweeklist // lists[1]改变指针,不影响lists[0] } //策略B: 两周都清空 if (!jweek && !jnext) || !jmonth || !jyear {// lists.removeAll() // 值拷贝,深拷贝 lists[0] = Variables.thisweeklist lists[1] = Variables.nextweeklist } }
然后考虑了日期显示的问题:
第一是 缩写问题。 我们希望周一写成MO而不是MON,周六写成SA而不是SAT。
这里涉及到Swift的字符串处理问题(不得不说,Swift的字符处理是真的麻烦!)
/** 更新DueDate **/ func updateDueDate() { let formatter = DateFormatter() formatter.dateFormat = "E HH:mm" //时间格式 let s = formatter.string(from: dueDate) let t = s.uppercased() let week = "Week \(thisweeklist.weekID) " let day = t.substring(to: t.characters.index(t.startIndex, offsetBy: 2)) let time = t.substring(from: t.characters.index(t.startIndex, offsetBy: 3)) let result = week + " " + day + " " + time dueDateNavigationItem.title = result //时间格式为 Week 5 TH 15:00 }
第二是 日期范围问题。 我们既然用了ThisWeek的List,总不希望选定时间时能选到超出本周范围的时间吧?
可是如果想要让DatePicker里只显示7行的日期,单单用PickerView里的方法是无法实现的。第三方库也没有很完美的解决方案。
因此我想到了曲线救国的方法:这样Date Picker中,超出范围的时间是不可选的。会Roll back
/** 日期范围限制 **/ func DateLimit() { let dateformatter = DateFormatter() dateformatter.dateFormat = "yyyy-MM-dd" let minDate = dateformatter.date(from: thisweeklist.stTime) let maxDate = dateformatter.date(from: thisweeklist.edTime) datePicker.minimumDate = minDate datePicker.maximumDate = maxDate }
最后,我还做了一些优化:
之前我默认item的Cell上的时间戳是Label,总是设置提醒为true。
后来我仔细研究了设计图,发现时间戳应该是个Button。点击时变红色表示设置提醒,灰色表示关闭提醒。
那么如何在Cell上加Button呢?又开始研究了:
// 通过关联函数来“扩展”button的属性 (失败了)
// objc_setAssociatedObject(button, "firstObject", item, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// let item = objc_getAssociatedObject(button, "firstObject")
// print(sender.title(for: UIControlState.highlighted))
在 datasource 协议中:
let button = cell.viewWithTag(2000) as! UIButton
// 给button添加点击事件 click button.addTarget(self, action: #selector(click(_:)), for: UIControlEvents.touchUpInside)
然后就说Cell上的Button点击事件了,可以获取Button的Cell和IndexPath,从而找到正确的item。。。。
/** Cell上 button 点击事件 **/ func click(_ sender: Any) { // 获取button的cell和indexPath, 从而找到正确的item let btn = sender as! UIButton let cell = btn.superView(of: UITableViewCell.self)! let indexPath = tableView.indexPath(for: cell) let row = indexPath?.row let item = thisweeklist.items[row!] // 提醒改变 item.shouldRemind = !item.shouldRemind if item.shouldRemind { btn.setImage(UIImage(named: "reminder_on"), for: UIControlState.normal) btn.setImage(UIImage(named: "reminder_on"), for: UIControlState.highlighted) btn.setTitleColor(UIColor.red, for: UIControlState.normal) btn.setTitleColor(UIColor.red, for: UIControlState.highlighted) } else { btn.setImage(UIImage(named: "reminder_off"), for: UIControlState.normal) btn.setImage(UIImage(named: "reminder_off"), for: UIControlState.highlighted) btn.setTitleColor(UIColor.black, for: UIControlState.normal) btn.setTitleColor(UIColor.black, for: UIControlState.highlighted) } shouldRemindToggled(item.shouldRemind) //设置提醒 item.scheduleNotification() //推送 }
/** 实现Button点击事件传参 参考文献:《在单元格里的按钮点击事件中获取对应的cell以及indexPath》 http://www.hangge.com/blog/cache/detail_1500.html **/extension UIView { //返回该view所在的父view func superView<T: UIView>(of: T.Type) -> T? { for view in sequence(first: self.superview, next: { $0?.superview }) { if let father = view as? T { return father } } return nil }}
忙完发现已经凌晨四点钟了。。。。
- 暑期项目开发实训 Day24
- 暑期项目开发实训 Day1
- 暑期项目开发实训 Day2
- 暑期项目开发实训 Day3
- 暑期项目开发实训 Day4
- 暑期项目开发实训 Day4
- 暑期项目开发实训 Day5
- 暑期项目开发实训 Day6
- 暑期项目开发实训 Day7
- 暑期项目开发实训 Day8
- 暑期项目开发实训 Day9
- 暑期项目开发实训 Day9
- 暑期项目开发实训 Day10
- 暑期项目开发实训 Day11
- 暑期项目开发实训 Day12
- 暑期项目开发实训 Day13
- 暑期项目开发实训 Day14
- 暑期项目开发实训 Day15
- 2017年Java面试题
- java 每日练习-2
- QT静态编译
- Unity3D获取游戏对象详解
- 通过C++文件复制小程序来理解read、write函数
- 暑期项目开发实训 Day24
- 【Oracle 12c Flex Cluster专题】Leaf Node的故障迁移
- C++之new 和 delete
- Picasso
- JavaScript定义类的方法
- 转换到 COFF 期间失败: 文件无效或损坏和VS2010不能创建项目的解决办法
- StyleBank: An Explicit Representation for Neural Image Style Transfer 论文理解
- Java多态--- 如何匹配的呢?
- 关于php如何在页面之间传递参数的问题