UIKit Dynamics和CALayers与UIView脱钩

Con*_*sed 6 microsoft-dynamics calayer uikit uiview ios

在玩UIKit Dynamics时是否可以不使用UIViews,而是将物理属性,锚点,力等等绑定到一个UIView中的CALayers?

根据Ash Farrow的这个页面:

UIDynamicItem是一种定义中心,边界和变换的协议(仅使用二维变换).UIView符合此协议,是UIDynamicBehaviour最常用的用法.您也可以将UICollectionViewLayoutAttributes与UIDynamicBehaviours一起使用,但我们今天不打算介绍它.

这似乎表明任何事情都可以符合协议UIDynamicItem,但我找不到任何关于制作CALayers的其他人.

可以比这种方法更直接地完成:

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

Rob*_*ier 5

正如链接文章所指出的那样,CALayer这些方法存在冲突类型,因此无法直接符合UIDynamicItem.您需要的是某种适配器层,它将CALayer方法转换为所需的类型和含义UIDynamicItem.

幸运的是,UIKit提供了这样一个适配器层.它被称为UIView.只需将每个图层放在视图中并嵌套视图即可.

我一直认为视图非常重要,特别是来自OS X世界.所以我一直认为"如果你想让它变快,你最好用一层来做." 但事实证明,视图实际上非常薄,并且在大多数情况下,与图层相比没有太多开销,特别是对于您在iOS中讨论的数字.请参阅TearOff演示,了解UIKItDynamics可以毫不费力地查看多个视图的示例.

如果你真的需要图层,那么是的,你绝对可以做到.只需自己创建适配器.它只需要持有CALayer并遵守UIKitDynamics.它不需要做任何其他事情.这样的事情应该有效:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您只需为此对象设置动画,这会使图层等效地进行动画处理.