WorkTimer - Swift

随着工作压力的增大,工作和休息不能平衡,导致效率下降.这个小Demo模仿了Tomate的核心理念和动画.

在这个基础上优化了核心代码,减少了反复重绘图片和计算,降低了CPU的使用率,使得扩展性增加,更好的适配不同的机型不同的系统.

虽然界面设计的很简单,没有给设置时间等,但是最合理的模式其实还是默认模式,也就是25(工作)+5(休息)模式的反复进行,把效率提高到最大.

原项目:Tomate

本项目:WorkTimer

下面给出设计的布局

iPhone5下的布局:

模拟器下的布局:

其中最主要的还是对核心动画进行优化:

import UIKit
import QuartzCore

/**
*  Update Timer UI
*/
public protocol TimerViewProtocol {
    func updateTimer(durationInSeconds: CGFloat)
}

extension CGFloat {
    func numberTimerFormate() -> String {
        return String(format: "%02d", Int(self))
    }
}

class TimerView: UIView, TimerViewProtocol {

    var totalTimeInSeconds: CGFloat {
        get{
            return totalTime
        }
        set{
            totalTime = newValue
            initTimerState()
        }
    }
    private var totalTime: CGFloat = 0.0

    private var radius: CGFloat = 0.0
    private var timerCenter: CGPoint = CGPoint(x: 0.0, y: 0.0)
    private let startAngle: CGFloat = -CGFloat(M_PI) / 2
    private let endAngle: CGFloat = 3 * CGFloat(M_PI) / 2

    private var minutesRingPath: UIBezierPath!
    private var secondsRingPath: UIBezierPath!
    private var fullRingPath: UIBezierPath!

    private var numberTimeLabel = UILabel()
    private let minutesShapeLayer: CAShapeLayer = CAShapeLayer()
    private let secondsShapeLayer: CAShapeLayer = CAShapeLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)

        layer.addSublayer(minutesShapeLayer)
        layer.addSublayer(secondsShapeLayer)
        addSubview(numberTimeLabel)

        addConstraints(settingNumberTimeLabelConstraint())

        backgroundColor = UIColor.clearColor()
        //backgroundColor = UIColor.redColor()///////////////////////////////////////////////////////////////////////////////////////////
        print("init TimerView complete")
    }

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

    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.

    override func drawRect(rect: CGRect) {

        timerCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect))
        radius = rect.width / 2 - 10

        settingMinuteStyle()
        settingSecondStyle()
        settingTimeLabelStyle()
        drawRing()

        initTimerState()

        print("Timer View drawRect:\(rect)-timerCenter:\(timerCenter)-radius:\(radius)")
    }

    func updateTimer(durationInSeconds: CGFloat) {
        minutesShapeLayer.strokeEnd = durationInSeconds / totalTime
        secondsShapeLayer.strokeEnd = durationInSeconds % 60 / 60

        numberTimeLabel.text = (durationInSeconds / 60).numberTimerFormate() + ":" + (durationInSeconds % 60).numberTimerFormate()
    }

    private func initTimerState() {
        minutesShapeLayer.strokeEnd = 0.0
        secondsShapeLayer.strokeEnd = 0.0
        numberTimeLabel.text = CGFloat(0).numberTimerFormate() + ":" + CGFloat(0).numberTimerFormate()

        let dashLength = 2 * radius * CGFloat(M_PI) / (totalTime / 60.0);
        minutesShapeLayer.lineDashPattern = [dashLength - 2, 2]

        print("init Time State complete")
    }

    private func settingMinuteStyle() {
        minutesRingPath = UIBezierPath(arcCenter: timerCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        minutesShapeLayer.path = minutesRingPath.CGPath

        minutesShapeLayer.fillColor = UIColor.clearColor().CGColor
        minutesShapeLayer.strokeColor = TimerStyleKit.timerColor.CGColor
        minutesShapeLayer.lineWidth = 4.0

        print("setting Minute Style")
    }

    private func settingSecondStyle() {
        secondsRingPath = UIBezierPath(arcCenter: timerCenter, radius: radius - 4, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        secondsShapeLayer.path = secondsRingPath.CGPath

        secondsShapeLayer.fillColor = UIColor.clearColor().CGColor
        secondsShapeLayer.strokeColor = TimerStyleKit.timerColor.CGColor
        secondsShapeLayer.lineWidth = 1.0

        print("setting Second Style")
    }

    private func settingTimeLabelStyle() {
        numberTimeLabel.textAlignment = .Center
        numberTimeLabel.textColor = TimerStyleKit.timerColor

        numberTimeLabel.font = UIFont(name: "HelveticaNeue-Thin", size: radius / 2 + 10)
        //numberTimeLabel.font = UIFont(name: "HelveticaNeue-Thin", size: 80)
        numberTimeLabel.adjustsFontSizeToFitWidth = true
        numberTimeLabel.center = timerCenter
        //numberTimeLabel.backgroundColor = UIColor.greenColor()///////////////////////////////////////////////////////////////////////////////////////////
        print("setting TimeLabel Style")

    }

    private func drawRing() {
        TimerStyleKit.timerColor.set()

        fullRingPath = UIBezierPath(arcCenter: timerCenter, radius: radius + 4, startAngle: startAngle, endAngle: endAngle, clockwise: true)

        fullRingPath.lineWidth = 1.0
        fullRingPath.stroke()
    }

    private func settingNumberTimeLabelConstraint() -> [NSLayoutConstraint] {
        numberTimeLabel.translatesAutoresizingMaskIntoConstraints = false

        var constraints = [NSLayoutConstraint]()

        if #available(iOS 9.0, *) {
            constraints.append(numberTimeLabel.centerXAnchor.constraintEqualToAnchor(centerXAnchor))
            constraints.append(numberTimeLabel.centerYAnchor.constraintEqualToAnchor(centerYAnchor))
        } else {
            // Fallback on earlier versions
            let views = ["numberTimeLabel": numberTimeLabel]
            constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-40-[numberTimeLabel]-40-|", options: [], metrics: [:], views: views)
            //constraints += NSLayoutConstraint.constraintsWithVisualFormat("V:|-40-[numberTimeLabel]-40-|", options: [], metrics: [:], views: views)
        }
        return constraints
    }

}

原项目中反复重绘和计算固定不变的一些属性,导致cpu占有率还是挺高的.

由于项目经验不足,只能造轮子了.

经过这个小Demo的制作,也了解了很多UIView和代码约束布局的相关知识.

其实我们做东西不仅仅只追求好看,而是应该合理的优化.

合理的设计模式和代码优化,包括好的扩展性,才是我们应该追求的.

时间: 2024-10-08 19:35:04

WorkTimer - Swift的相关文章

Apple Swift编程语言新手教程

Apple Swift编程语言新手教程 作者: 日期: gashero 2014-06-03 FROM:http://gashero.iteye.com/blog/2075324 文件夹 1   简单介绍 2   Swift入门 3   简单值 4   控制流 5   函数与闭包 6   对象与类 7   枚举与结构 1   简单介绍 今天凌晨Apple刚刚公布了Swift编程语言,本文从其公布的书籍<The Swift Programming Language>中摘录和提取而成.希望对各位的

swift 深入理解Swift的闭包

我们可用swift的闭包来定义变量的值. 先来一个简单的例子大家先感受感受. 定义一个字符串的变量的方法: 直接赋值 var str="JobDeer" 还可以用闭包的方式定义: var str:String={ return "JobDeer" }() 闭包还可以这么定义,省略了等号和括号: var str:String{ return "JobDeer" } 闭包中可以定义get方法. var str:String{ get{ return

在Swift结构体中如何实现写时复制?

结构体(Struct)在Swift语言中占有重要地位,在Swift标准库中,大约有90%的公开类型都是结构体,包括我们常用的Array.String.Dictionary.结构体相比类,一个最重要的特性就是它是值类型,而类似引用类型.值类型是通过复制值来赋值的,而不是引用同一个内存地址,这样就不存在数据共享的问题,能防止意外的数据改变,并且它是线程安全的. 举一个很简单的例子,在objc中,数组是类,是引用类型,在Swift中,数组是结构体,是值类型.因此下面的代码中: let array1 =

Swift学习之位移枚举的按位或运算

在OC里面我们经常遇到一些枚举值可以多选的,需要用或运算来把这些枚举值链接起来,这样的我们称为位移枚举,但是在swift语言里面却不能这么做,下面来讲解一下如何在swift里面使用 OC的位移枚举的区分 //位移枚举typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutores

Swift - 用UIScrollView实现视差动画效果

效果 源码 https://github.com/YouXianMing/Swift-Animations // // MoreInfoView.swift // Swift-Animations // // Created by YouXianMing on 16/8/18. // Copyright © 2016年 YouXianMing. All rights reserved. // import UIKit class MoreInfoView: UIView { var imageV

Swift 入门之简单语法(一)

定义 let 定义常量,一经赋值不允许再修改 var 定义变量,赋值之后仍然可以修改 //: # 常量 //: 定义常量并且直接设置数值 let x = 20 //: 常量数值一经设置,不能修改,以下代码会报错 // x = 30 //: 使用 `: 类型`,仅仅只定义类型,而没有设置数值 let x1: Int //: 常量有一次设置数值的机会,以下代码没有问题,因为 x1 还没有被设置数值 x1 = 30 //: 一旦设置了数值之后,则不能再次修改,以下代码会报错,因为 x1 已经被设置了数

Swift和Java关于字符串和字符的比较

1. 字符串字面量 Swift和Java关于字符串操作大同小异. Swift:字符串字面量(String Literals):我们可以在代码中包含一段预定义的字符串值作为字符串字面量. 字符串字面量是由双引号 ("") 包裹着的具有固定顺序的文本字符集.字符串字面量可以用于为常量和变量提供初始值. 代码如下: let someString = "Some string literal value" 字符串字面量可以包含以下特殊字符: 转义字符\0(空字符).\\(反

Swift Tour

设置常数使用let,设置变量使用var var myVariable = 42 myVariable = 50 let myConstant = 42 编译器可以自己推断出变量类型因此不用显式限定. 如果没有赋初值或信息不足以让编译器判断,则可以通过冒号显式声明: let implicitInteger = 70 let implicitDouble = 70.0 let explicitDouble: Double = 70 任何变量类型都不可以隐式转换,所有变量之间的转换都为显式: let

Swift备忘录

Swift 备忘录 2015-4 一.简介 1.Swift 语言由苹果公司在2010年7月开始设计,在 2014 年6月推出,在 2015 年 12 月 3 日开源 2.特点(官方): (1)苹果宣称 Swift 的特点是:快速.现代.安全.互动,而且明显优于 Objective-C 语言 (2)可以使用现有的 Cocoa 和 Cocoa Touch 框架 (3)Swift 取消了 Objective-C 的指针及其他不安全访问的使用 (4)舍弃 Objective-C 早期应用 Smallta