UIDynamicItem update transform manually

淺唱寂寞╮ 提交于 2020-01-01 09:24:14

问题


I know that external change to center, bounds and transform will be ignored after UIDynamicItems init.

But I need to manually change the transform of UIView that in UIDynamicAnimator system.

Every time I change the transform, it will be covered at once.

So any idea? Thanks.


回答1:


Any time you change one of the animated properties, you need to call [dynamicAnimator updateItemUsingCurrentState:item] to let the dynamic animator know you did it. It'll update it's internal representation to match the current state.


EDIT: I see from your code below that you're trying to modify the scale. UIDynamicAnimator only supports rotation and position, not scale (or any other type of affine transform). It unfortunately takes over transform in order to implement just rotation. I consider this a bug in UIDynamicAnimator (but then I find much of the implementation of UIKit Dynamics to classify as "bugs").

What you can do is modify your bounds (before calling updateItem...) and redraw yourself. If you need the performance of an affine transform, you have a few options:

  • Move your actual drawing logic into a CALayer or subview and modify its scale (updating your bounds to match if you need collision behaviors to still work).
  • Instead of attaching your view to the behavior, attach a proxy object (just implement <UIDyanamicItem> on an NSObject) that passes the transform changes to you. You can then combine the requested transform with your own transform.



回答2:


You can also use the .action property of the UIDynamicBehavior to set your desired transform at every tick of the animation.

UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];
attachment.damping = 0.8f;
attachment.frequency = 0.8f;
attachment.action = ^{
    CGAffineTransform currentTransform = item.transform;
    item.transform = CGAffineTransformScale(currentTransform, 1.2, 1.2)
};

You would need to add logic within the action block to determine when the scale should be changed, and by how much, otherwise your view will always be at 120%.




回答3:


Another way to fix this (I think we should call it bug) is to override the transform property of the UIView used. Something like this:

override var transform: CGAffineTransform {
    set (value) {

    }
    get {
        return super.transform
    }
}

var ownTransform: CGAffineTransform. {
    didSet {
        super.transform = ownTransform
    }
}

It's a kind of a hack, but it works fine, if you don't use rotation in UIKitDynamics.



来源:https://stackoverflow.com/questions/20631383/uidynamicitem-update-transform-manually

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!