继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Swift——图层几何学(时钟)

慕神8447489
关注TA
已关注
手记 1134
粉丝 172
获赞 955

最近在看iOS核心动画高级技巧,OC语言与Swift转换有点令人头疼,某些类和Api改动相当大。所以遇到我很困扰的语法我都会记录一下,也方便日后回顾。

首先是关于时间的类NSCalendar

webp

时钟.gif

这是iOS核心动画高级技巧——3.图层几何学——3.2锚点里的原文

- (void)tick
{    //convert time to hours, minutes and seconds
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];    NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];    CGFloat hoursAngle = (components.hour / 12.0) * M_PI * 2.0;    //calculate hour hand angle //calculate minute hand angle
    CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0;    //calculate second hand angle
    CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0;    //rotate hands
    self.hourHand.transform = CGAffineTransformMakeRotation(hoursAngle);    self.minuteHand.transform = CGAffineTransformMakeRotation(minsAngle);    self.secondHand.transform = CGAffineTransformMakeRotation(secsAngle);
}

在我前前后后的各种查找语法糖的情况下,摸索出三种写法。

第一种

因为这句代码NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit 中或的写法,是在是不知道怎么转,所以就暂时没管它

    @objc func tick(){
        
        let calendar = NSCalendar.init(identifier: NSCalendar.Identifier.gregorian)
        
        let hoursAngle = (getComponents(calendar!, unit: .hour) / 12.0) * CGFloat.pi * 2.0
        let minsAngle = (getComponents(calendar!, unit: .minute) / 60.0) * CGFloat.pi * 2.0
        let secsAngle = (getComponents(calendar!, unit: .second) / 60.0) * CGFloat.pi * 2.0
        
        self.hourHand.transform = CGAffineTransform.init(rotationAngle: hoursAngle)       self.minuteHand.transform = CGAffineTransform.init(rotationAngle: minsAngle)        self.secondHand.transform = CGAffineTransform.init(rotationAngle: secsAngle)

    }
    
    func getComponents(_ cal:NSCalendar, unit:NSCalendar.Unit) -> CGFloat{        
        return CGFloat(cal.component(unit, from: Date()))
    }

第二种

后来总是想着,OC可以Swift肯定也行的,然后发现是这样写的

    @objc func tick2(){
        
        let calendar = NSCalendar.init(identifier: NSCalendar.Identifier.gregorian)
        
        let units:NSCalendar.Unit = [.hour, .minute, .second]
        
        let comp = calendar!.components(units, from: Date())
        
        setDigit(digit: comp.hour! / 10, forView: self.digitViews[0])
        setDigit(digit: comp.hour! % 10, forView: self.digitViews[1])
        
        setDigit(digit: comp.minute! / 10, forView: self.digitViews[2])
        setDigit(digit: comp.minute! % 10, forView: self.digitViews[3])
        
        setDigit(digit: comp.second! / 10, forView: self.digitViews[4])
        setDigit(digit: comp.second! % 10, forView: self.digitViews[5])
        
    }

第三种

NS开头的,Swift肯定是会重写成自己的类的,试试?

    @objc func tick3(){
        
        let calendar = Calendar.init(identifier: .gregorian)
        let ccc:Set<Calendar.Component> = [Calendar.Component.hour, Calendar.Component.minute, Calendar.Component.second]
        let comp = calendar.dateComponents(ccc, from: Date())
        
        setDigit(digit: comp.hour! / 10, forView: self.digitViews[0])
        setDigit(digit: comp.hour! % 10, forView: self.digitViews[1])
        
        setDigit(digit: comp.minute! / 10, forView: self.digitViews[2])
        setDigit(digit: comp.minute! % 10, forView: self.digitViews[3])
        
        setDigit(digit: comp.second! / 10, forView: self.digitViews[4])
        setDigit(digit: comp.second! % 10, forView: self.digitViews[5])
        
    }

这些代码只是语法的转换,不是完整代码。而且代码量很小,我也不想上传github,所以直接贴出来,但是没包括Interface Builder中的布局,所以我截了张XIB的图出来。还有不要给约束。


webp

XIB截图

代码

class ClockController: UIViewController {

    @IBOutlet weak var hourHand: UIImageView!
    
    @IBOutlet weak var minuteHand: UIImageView!
    
    @IBOutlet weak var secondHand: UIImageView!
    
    var timer:Timer!
    
    var timer2:Timer!
    
    @IBOutlet var digitViews:[UIView]!
    
    override func viewDidLoad() {        super.viewDidLoad()        self.secondHand.layer.anchorPoint = CGPoint.init(x: 0.5, y: 0.9)        self.minuteHand.layer.anchorPoint = CGPoint.init(x: 0.5, y: 0.9)        self.hourHand.layer.anchorPoint = CGPoint.init(x: 0.5, y: 0.9)
        
        timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(tick), userInfo: nil, repeats: true)
        // Do any additional setup after loading the view.
        tick()
        
        setupTick2()
        
    }

    @objc func tick(){
        
        let calendar = NSCalendar.init(identifier: NSCalendar.Identifier.gregorian)
        
        let hoursAngle = (getComponents(calendar!, unit: .hour) / 12.0) * CGFloat.pi * 2.0
        let minsAngle = (getComponents(calendar!, unit: .minute) / 60.0) * CGFloat.pi * 2.0
        let secsAngle = (getComponents(calendar!, unit: .second) / 60.0) * CGFloat.pi * 2.0
        
        self.hourHand.transform = CGAffineTransform.init(rotationAngle: hoursAngle)       self.minuteHand.transform = CGAffineTransform.init(rotationAngle: minsAngle)        self.secondHand.transform = CGAffineTransform.init(rotationAngle: secsAngle)

    }
    
    func getComponents(_ cal:NSCalendar, unit:NSCalendar.Unit) -> CGFloat{        
        return CGFloat(cal.component(unit, from: Date()))
    }

    func setupTick2(){
        
        let digits = UIImage.init(named: "Digits")        
        for vi in self.digitViews {

            vi.layer.contents = digits?.cgImage
            vi.layer.contentsRect = CGRect.init(x: 0, y: 0, width: 0.1, height: 1.0)
            vi.layer.contentsGravity = kCAGravityResizeAspect
            vi.layer.magnificationFilter = kCAFilterNearest
            
        }
        
        timer2 = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(tick2), userInfo: nil, repeats: true)
        self.tick2()
    }
    
    @objc func tick2(){
        
        let calendar = NSCalendar.init(identifier: NSCalendar.Identifier.gregorian)
        
        let units:NSCalendar.Unit = [.hour, .minute, .second]
        
        let comp = calendar!.components(units, from: Date())
        
        setDigit(digit: comp.hour! / 10, forView: self.digitViews[0])
        setDigit(digit: comp.hour! % 10, forView: self.digitViews[1])
        
        setDigit(digit: comp.minute! / 10, forView: self.digitViews[2])
        setDigit(digit: comp.minute! % 10, forView: self.digitViews[3])
        
        setDigit(digit: comp.second! / 10, forView: self.digitViews[4])
        setDigit(digit: comp.second! % 10, forView: self.digitViews[5])
        
    }
    
    @objc func tick3(){
        
        let calendar = Calendar.init(identifier: .gregorian)
        let ccc:Set<Calendar.Component> = [Calendar.Component.hour, Calendar.Component.minute, Calendar.Component.second]
        let comp = calendar.dateComponents(ccc, from: Date())
        
        setDigit(digit: comp.hour! / 10, forView: self.digitViews[0])
        setDigit(digit: comp.hour! % 10, forView: self.digitViews[1])
        
        setDigit(digit: comp.minute! / 10, forView: self.digitViews[2])
        setDigit(digit: comp.minute! % 10, forView: self.digitViews[3])
        
        setDigit(digit: comp.second! / 10, forView: self.digitViews[4])
        setDigit(digit: comp.second! % 10, forView: self.digitViews[5])
        
    }
    
    func setDigit(digit:Int, forView view:UIView){
        
        let num = Double(digit)
        view.layer.contentsRect = CGRect.init(x: num * 0.1, y: 0, width: 0.1, height: 1.0)
    }
    
    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.
    }
    
}



作者:Bart_Simpson
链接:https://www.jianshu.com/p/d3765cccb471


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP