Dynamics UIKit and CALayers disconnected from UIView

Is it possible to use UIView when playing with UIKit Dynamics and instead bind the properties of physics, anchors, forces, etc. to CALayers within the same UIView?

According to this page Ash Farrow:

UIDynamicItem is a protocol that defines center, boundaries, and transform (only two-dimensional transforms are used). UIView conforms to this protocol and is the most common use of UIDynamicBehaviour. You can also use UICollectionViewLayoutAttributes with UIDynamicBehaviours, but today you were not going to talk about it.

Which, apparently, indicates that something can be done to comply with the UIDynamicItem protocol, but I can not find anything about other games with the creation of CALayers.

Can this be done more directly than this approach:

https://www.invasivecode.com/weblog/uikit-dynamics-layer-constraint/

+5
source share
1 answer

As a related article notes, CALayer has conflicting types for these methods, so it cannot directly match UIDynamicItem . You will need some kind of adapter layer that converted the CALayer methods to the types and values ​​needed by UIDynamicItem .

Fortunately, UIKit offers just such an adapter layer. It is called UIView . Just put each layer in the view and paste the views.

I have long thought of views as heavy weight, especially from the OS X world. Therefore, I always thought: "If you want it to be fast, you better do it with a layer." But it turns out that the views are actually quite subtle, and in most cases there is not much overhead and level, especially for the numbers you talk about in iOS. See the TearOff Demo for an example that calls UIKItDynamics with many dozens of views without problems.

If you really need layers, then yes, you can still do it. Just create an adapter yourself. You just need to hold CALayer and match UIKitDynamics . He does not need to do anything. Something like this should work:

 public class DynamicLayerItem : NSObject, UIDynamicItem { let layer: CALayer init(layer: CALayer) { self.layer = layer} public var center: CGPoint { get { return layer.position } set { layer.position = center } } public var bounds: CGRect { return layer.bounds } public var transform: CGAffineTransform { get { return layer.affineTransform() } set { layer.transform = CATransform3DMakeAffineTransform(newValue) } } } 

You just animate this object, and this makes the layer animate equivalently.

+3
source

Source: https://habr.com/ru/post/1212874/