TextureGroup / Texture

Smooth asynchronous user interfaces for iOS apps.
https://texturegroup.org/
Other
8k stars 1.29k forks source link

Texture + UIDynamics #645

Open BrandonMA opened 6 years ago

BrandonMA commented 6 years ago

I'm trying to use UIDynamics with texture, just moving a node to a tap(UITapGestureRecognizer) and animating with UISnapBehavior, but if you run the code I'm posting you will see that the animation is not executed but it jumps to the final state instead. Probably because layout() is getting called, any idea how to use UIDynamics with Texture?

`import AsyncDisplayKit

class SFExperimentNode: ASDisplayNode {

override func didLoad() {
    super.didLoad()
    automaticallyManagesSubnodes = true
}

lazy var middleNode: ASDisplayNode = {
    let node = ASDisplayNode()
    node.backgroundColor = SFAssets.red
    return node
}()

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
    middleNode.style.preferredLayoutSize = ASLayoutSize(width: ASDimension(unit: .points, value: 200), height: ASDimension(unit: .points, value: 200))
    return ASRelativeLayoutSpec(horizontalPosition: .center, verticalPosition: .center, sizingOption: .minimumSize, child: middleNode)
}

}

class SFExperimentController: ASViewController {

var animator: UIDynamicAnimator!
var snap: UISnapBehavior!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    createGestureRecognizer()
    animator = UIDynamicAnimator(referenceView: self.node.view)
}

func createGestureRecognizer() {
    let panGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handlePan(sender:)))
    self.node.view.addGestureRecognizer(panGestureRecognizer)
}

@objc func handlePan(sender: UITapGestureRecognizer) {
    let touchPoint = sender.location(in: self.node.view)

    if snap != nil {
        animator.removeAllBehaviors()
    }

    snap = UISnapBehavior(item: self.node.middleNode.view, snapTo: touchPoint)
    animator.addBehavior(snap)
}

}`

muukii commented 3 years ago

animator.addBehavior causes layoutSublayers in CALayer. Then Texture lays out subnodes again according to the calculated layout. That's why dragged box would back to its original position. To prevent, overriding frame property and skipping setting frame while animating.

CleanShot 2021-04-30 at 21 37 20@2x
muukii commented 3 years ago

CleanShot 2021-04-30 at 21 44 48