zoukankan      html  css  js  c++  java
  • WorkTimer

    随着工作压力的增大,工作和休息不能平衡,导致效率下降.这个小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和代码约束布局的相关知识.

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

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

  • 相关阅读:
    OAF 开发,给组件添加javascript事件
    SQL SERVER占用CPU过高优化
    Winform嵌入CEF(非正常用法)
    多线程——i++的坑
    20150819(i++与++i的思考)
    listView中,checkBox的显示和隐藏
    装箱和拆箱
    虚方法
    [转]关于struct的一些解释与class对比
    提取行政区边界经纬度坐标(高德+百度)
  • 原文地址:https://www.cnblogs.com/xwjack1554239786/p/5515620.html
Copyright © 2011-2022 走看看