用IPhone6s的3D Touch来称重,比较2个物体的重量

这是一款开源应用,它利用 iPhone 6s 的 3D Touch 屏幕来测量出物体和手机的可能最大力值的相对比。用户还可以选择让 3D Touch 来测量其他物体的相对重量,只要它不超过 iPhone 6s 屏幕能够承受的重量即可。

iPhone的屏幕可以同时检测到五个物体的存在,所以从理论上来说,它或许可以同时对比五个物体的重量。如上图是用户的使用测试,他们发现这款应用使用起来没有什么问题。3D Touch 屏幕的压力敏感度超出用户的想象,在这里你能够发现它可以感应到不同程度的力量。

 

代码如下:

class ViewController: UIViewController

{

    

    let label = UILabel()

    

    var circles = [UITouch: CircleWithLabel]()

    

    override func viewDidLoad()

    {

        super.viewDidLoad()

        

        view.multipleTouchEnabled = true

        

        label.text = "lay your plums on me."

        

        label.textAlignment = NSTextAlignment.Center

        

        view.addSubview(label)

    }

    

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)

    {

        label.hidden = true

        

        for touch in touches

        {

            let circle = CircleWithLabel()

            

            circle.drawAtPoint(touch.locationInView(view),

                force: touch.force / touch.maximumPossibleForce)

            

            circles[touch] = circle

            view.layer.addSublayer(circle)

        }

        

        highlightHeaviest()

    }

    

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)

    {

        for touch in touches where circles[touch] != nil

        {

            let circle = circles[touch]!

            

            circle.drawAtPoint(touch.locationInView(view),

                force: touch.force / touch.maximumPossibleForce)

        }

        

        highlightHeaviest()

    }

    

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?)

    {

        for touch in touches where circles[touch] != nil

        {

            let circle = circles[touch]!

            

            circles.removeValueForKey(touch)

            circle.removeFromSuperlayer()

        }

        

        highlightHeaviest()

    }

    

    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?)

    {

        guard let touches = touches else

        {

            return

        }

        

        for touch in touches where circles[touch] != nil

        {

            let circle = circles[touch]!

            

            circle.removeFromSuperlayer()

        }

    }

    

    func highlightHeaviest()

    {

        func getMaxTouch() -> UITouch?

        {

            return circles.sort({

                (a: (UITouch, CircleWithLabel), b: (UITouch, CircleWithLabel)) -> Bool in

                

                return a.0.force > b.0.force

            }).first?.0

        }

        

        circles.forEach

        {

            $0.1.isMax = $0.0 == getMaxTouch()

        }

    }

    

    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask

    {

        return UIInterfaceOrientationMask.Landscape

    }

    

    override func viewDidLayoutSubviews()

    {

        label.frame = view.bounds

    }

}

 

// -------------

 

class CircleWithLabel: CAShapeLayer

{

    let text = CATextLayer()

    

    override init()

    {

        super.init()

        

        text.foregroundColor = UIColor.blueColor().CGColor

        text.alignmentMode = kCAAlignmentCenter

        addSublayer(text)

        

        strokeColor = UIColor.blueColor().CGColor

        lineWidth = 5

        fillColor = nil

    }

    

    override init(layer: AnyObject)

    {

        super.init(layer: layer)

    }

    

    required init?(coder aDecoder: NSCoder)

    {

        fatalError("init(coder:) has not been implemented")

    }

    

    var isMax: Bool = false

    {

        didSet

        {

            fillColor = isMax ? UIColor.yellowColor().CGColor : nil

        }

    }

    

    func drawAtPoint(location: CGPoint, force: CGFloat)

    {

        let radius = 120 + (force * 120)

        

        path = UIBezierPath(

            ovalInRect: CGRect(

                origin: location.offset(dx: radius, dy: radius),

                size: CGSize(width: radius * 2, height: radius * 2))).CGPath

        

        text.string = String(format: "%.1f%%", force * 100)

        

        text.frame = CGRect(origin: location.offset(dx: 75, dy: -radius), size: CGSize(width: 150, height: 40))

    }

}

 

// -------------

 

extension CGPoint

{

    func offset(dx dx: CGFloat, dy: CGFloat) -> CGPoint

    {

        return CGPoint(x: self.x - dx, y: self.y - dy)

    }

}

 

posted @ 2015-10-26 16:30  wu大维  阅读(633)  评论(0编辑  收藏  举报