UIKit动力学和CALayer解耦自UIView

6

在使用UIKit Dynamics时,是否可以不使用UIView,而是将物理属性、锚定点、力等绑定到一个UIView内的所有CALayer中?

根据Ash Farrow的这篇文章:

UIDynamicItem是一个协议,定义了中心、边界和变换(只使用二维变换)。UIView符合此协议,并且是UIDynamicBehavior最常见的用法。您还可以使用UICollectionViewLayoutAttributes与UIDynamicBehaviours,但我们今天不会涉及这个。

这似乎表明任何东西都可以遵循UIDynamicItem协议,但我找不到有关其他人尝试制作CALayer的信息。

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

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

1个回答

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)
        }
    }
}

您只需要对该对象进行动画处理,这会导致该层的等效动画。

这段关于UIView的内容对我来说也是一种思想上的解放。非常感谢你! - Confused

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接