Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 调用视图后调用drawRect_Ios_Iphone_Swift_Cocoa Touch_Uiview - Fatal编程技术网

Ios 调用视图后调用drawRect

Ios 调用视图后调用drawRect,ios,iphone,swift,cocoa-touch,uiview,Ios,Iphone,Swift,Cocoa Touch,Uiview,我有一个视图正在使用drawRect绘制一个圆形计时器 在它的superview中有一个按钮,可以将另一个VC推到屏幕上 问题是,当用户单击后退按钮时,计时器(使用drawRect绘制)会自动从fromValue的toValue值instad开始。我希望它完全按照我第一次启动视图时绘制的方式重新绘制 有人知道我怎样才能做到吗 谢谢大家! 代码: class CountDownTimer: UIView { public var backgroundStrokeColor: CGColo

我有一个视图正在使用
drawRect
绘制一个圆形计时器

在它的superview中有一个按钮,可以将另一个VC推到屏幕上

问题是,当用户单击
后退
按钮时,计时器(使用
drawRect
绘制)会自动从
fromValue
toValue
值instad开始。我希望它完全按照我第一次启动视图时绘制的方式重新绘制

有人知道我怎样才能做到吗

谢谢大家!

代码:

class CountDownTimer: UIView {

    public var backgroundStrokeColor: CGColor = UIColor.white.cgColor
    public var backgroundFillColor: CGColor = UIColor.clear.cgColor
    public var backgroundLineWidth: CGFloat = 15
    public var timeLeftSrtokeColor: CGColor = UIColor.red.cgColor
    public var timeLeftFillColor: CGColor = UIColor.clear.cgColor
    public var timeLeftLineWidth: CGFloat = 10
    public var textColor: UIColor = UIColor.white
    public var textFont: UIFont = UIFont.balooRegular(10.0)

    fileprivate var timeLeft: TimeInterval = 0
    fileprivate var endDate: Date?
    fileprivate var timeLeftShapeLayer: CAShapeLayer?
    fileprivate var bgShapeLayer: CAShapeLayer?
    fileprivate var timeLabel:  UILabel?
    fileprivate var timer = Timer()
    fileprivate let strokeIt = CABasicAnimation(keyPath: "strokeEnd")

    //MARK: - UIView
    override func draw(_ rect: CGRect) {    
        drawBgShape()
        drawTimeLeftShape()
        addTimeLabel()

        strokeIt.toValue = 1 //"fromValue" is set in "startTimer(duration, timerProgress)
        strokeIt.duration = self.timeLeft
        // add the animation to your timeLeftShapeLayer
        timeLeftShapeLayer?.add(strokeIt, forKey: nil)
        // define the future end time by adding the timeLeft to now Date()

    }

    //MARK: - Public
    public func startTimer(duration: TimeInterval, timerProgress: Double) {
        self.timeLeft = duration
        endDate = Date().addingTimeInterval(timeLeft)
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
        strokeIt.fromValue = timerProgress
    }

    //MARK: - Private
    fileprivate func drawBgShape() {
        //we initialize and add the layer only if there is not initialized
        if(bgShapeLayer == nil){
            bgShapeLayer = CAShapeLayer()
            self.layer.addSublayer(bgShapeLayer!)
        }

        bgShapeLayer?.path = UIBezierPath(arcCenter: CGPoint(x: self.frame.midX , y: self.frame.midY), radius:
            min((frame.width - self.timeLeftLineWidth)/2, (frame.height - self.timeLeftLineWidth)/2), startAngle: -90.degreesToRadians, endAngle: 270.degreesToRadians, clockwise: true).cgPath
        bgShapeLayer?.strokeColor = self.backgroundStrokeColor
        bgShapeLayer?.fillColor = self.backgroundFillColor
        bgShapeLayer?.lineWidth = self.backgroundLineWidth
    }

    fileprivate func drawTimeLeftShape() {
        //we initialize and add the layer only if there is not initialized
        if(timeLeftShapeLayer == nil){
            timeLeftShapeLayer = CAShapeLayer()
            self.layer.addSublayer(timeLeftShapeLayer!)
        }
        timeLeftShapeLayer?.path = UIBezierPath(arcCenter: CGPoint(x: self.frame.midX , y: self.frame.midY), radius:
            min((frame.width - self.timeLeftLineWidth)/2, (frame.height - self.timeLeftLineWidth)/2), startAngle: -90.degreesToRadians, endAngle: 270.degreesToRadians, clockwise: true).cgPath
        timeLeftShapeLayer?.strokeColor = self.timeLeftSrtokeColor
        timeLeftShapeLayer?.fillColor = self.timeLeftFillColor
        timeLeftShapeLayer?.lineWidth = self.timeLeftLineWidth
    }

    fileprivate func addTimeLabel() {
        //we initialize and add the UILabel only if there is not initialized
        if(timeLabel == nil){
            timeLabel = UILabel()
            self.addSubview(timeLabel!)
        }

        timeLabel?.frame = CGRect(x: self.frame.midX-50 ,y: self.frame.midY-25, width: 100, height: 50)
        timeLabel?.adjustsFontSizeToFitWidth = true
        timeLabel?.textAlignment = .center
        timeLabel?.text = self.timeLeft.stringTime
        timeLabel?.textColor = self.textColor
        timeLabel?.font = self.textFont
    }

    //MARK: - Actions
    @objc fileprivate func updateTime() {
        if timeLeft > 0 {
            timeLeft = endDate?.timeIntervalSinceNow ?? 0
            timeLabel?.text = self.timeLeft.stringTime
        } else {
            timeLabel?.text = self.timeLeft.stringTime
            timer.invalidate()
        }
    }
}

给我们看一些代码。您所说的
fromValue
toValue
变量是什么?@vacawama您好,谢谢您的回答。我已将计时器视图的代码添加到问题中。谢谢您在哪里调用
startTimer
?@vacawama它是:UICollectionView单元格中的countDownTimer容器(UIView)中的countDownTimer。所以我称之为“内部”collectionViewCell@vacawama你知道吗?