繁体   English   中英

如何将多个UIDynamicItem彼此附加

[英]How to attach multiple UIDynamicItems to each other

我正在尝试通过UIDynamicAnimator实现彼此相连的圈子,例如在Apple的Music App中。 我需要将圆圈彼此连接并查看中心。 我试图通过UIAttachmentBehavior实现此UIAttachmentBehavior ,但似乎不支持多个附件。 结果,圆圈彼此重叠:)

let attachment = UIAttachmentBehavior(item: circle, attachedToAnchor: CGPoint(x: view.center.x, y: view.center.y))
attachment.length = 10
animator?.addBehavior(attachment)

let push = UIPushBehavior(items: [circle], mode: .continuous)

collision.addItem(circle)

animator?.addBehavior(push)

苹果音乐 在此处输入图片说明

我做错了什么?

我不认为苹果音乐类型选择器使用UIAttachmentBehavior ,它更接近于用一根杆子或一根绳子附加两个视图。 但是,似乎您遇到的问题可能是所有视图都添加到了同一位置,从而将它们放置在彼此的顶部,并且碰撞行为导致它们本质上被粘在一起。 一件事是通过调用animator.setValue(true, forKey: "debugEnabled")来打开UIDynamicAnimator调试。

为了重新创建上面的圆形选择器设计,我将研究使用UIFieldBehavior.springField()

例如:

class ViewController: UIViewController {

    lazy var animator: UIDynamicAnimator = {
        let animator = UIDynamicAnimator(referenceView: view)
        return animator
    }()
    lazy var collision: UICollisionBehavior = {
        let collision = UICollisionBehavior()
        collision.collisionMode = .items
        return collision
    }()
    lazy var behavior: UIDynamicItemBehavior = {
        let behavior = UIDynamicItemBehavior()
        behavior.allowsRotation = false
        behavior.elasticity = 0.5
        behavior.resistance = 5.0
        behavior.density = 0.01
        return behavior
    }()
    lazy var gravity: UIFieldBehavior = {
        let gravity = UIFieldBehavior.springField()
        gravity.strength = 0.008
        return gravity
    }()
    lazy var panGesture: UIPanGestureRecognizer = {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.didPan(_:)))
        return panGesture
    }()

    var snaps = [UISnapBehavior]()
    var circles = [CircleView]()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addGestureRecognizer(panGesture)
        animator.setValue(true, forKey: "debugEnabled")
        addCircles()
        addBehaviors()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        gravity.position = view.center
        snaps.forEach {
            $0.snapPoint = view.center
        }
    }

    func addCircles() {
        (1...30).forEach { index in
            let xIndex = index % 2
            let yIndex: Int = index / 3
            let circle = CircleView(frame: CGRect(origin: CGPoint(x: xIndex == 0 ? CGFloat.random(in: (-300.0 ... -100)) : CGFloat.random(in: (500 ... 800)), y: CGFloat(yIndex) * 200.0), size: CGSize(width: 100, height: 100)))
            circle.backgroundColor = .red
            circle.text = "\(index)"
            circle.textAlignment = .center
            view.addSubview(circle)
            gravity.addItem(circle)
            collision.addItem(circle)
            behavior.addItem(circle)
            circles.append(circle)
        }
    }

    func addBehaviors() {
        animator.addBehavior(collision)
        animator.addBehavior(behavior)
        animator.addBehavior(gravity)
    }

    @objc
    private func didPan(_ sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: sender.view)
        switch sender.state {
        case .began:
            animator.removeAllBehaviors()
            fallthrough
        case .changed:
            circles.forEach { $0.center = CGPoint(x: $0.center.x + translation.x, y: $0.center.y + translation.y)}
        case .possible, .cancelled, .failed:
            break
        case .ended:
            circles.forEach { $0.center = CGPoint(x: $0.center.x + translation.x, y: $0.center.y + translation.y)}
            addBehaviors()
        @unknown default:
            break
        }
        sender.setTranslation(.zero, in: sender.view)
    }
}

final class CircleView: UILabel {

    override var collisionBoundsType: UIDynamicItemCollisionBoundsType {
        return .ellipse
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.height * 0.5
        layer.masksToBounds = true
    }
}

截图

有关更多信息,我将观看WWDC 2015的UIKit Dynamics和Visual Effects中的新增功能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM