暑期项目开发实训 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()   //推送通知


2. shouldRemindToggled 使得允许推送
    /** 设置提醒     **/    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    }}


忙完发现已经凌晨四点钟了。。。。

原创粉丝点击