简体   繁体   English

UIKit Dynamics和CALayers与UIView脱钩

[英]UIKit Dynamics and CALayers decoupled from UIView

Is it possible to not use UIViews when playing with UIKit Dynamics, and instead bind the physics properties, anchors, forces etc to CALayers all within one UIView? 在玩UIKit Dynamics时是否可以不使用UIViews,而是将物理属性,锚点,力等等绑定到一个UIView中的CALayers?

According to this page by Ash Farrow: 根据Ash Farrow的这个页面:

UIDynamicItem is a protocol that defines a centre, a bounds, and a transform (only two-dimensional transforms are used). UIDynamicItem是一种定义中心,边界和变换的协议(仅使用二维变换)。 UIView conforms to this protocol, and is the most common use of UIDynamicBehaviour. UIView符合此协议,是UIDynamicBehaviour最常用的用法。 You can also use UICollectionViewLayoutAttributes with UIDynamicBehaviours, but we're not going to cover that today. 您也可以将UICollectionViewLayoutAttributes与UIDynamicBehaviours一起使用,但我们今天不打算介绍它。

Which seems to indicate that anything can be made to conform to the protocol UIDynamicItem, but I can't find anything about others playing around with making CALayers. 这似乎表明任何事情都可以符合协议UIDynamicItem,但我找不到任何关于制作CALayers的其他人。

Can it be done more directly than this approach: 可以比这种方法更直接地完成:

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

As the linked article notes, CALayer has conflicting types for these methods, so it can't directly conform to UIDynamicItem . 正如链接文章所述, CALayer对这些方法的类型存在冲突,因此无法直接符合UIDynamicItem What you'd need would be some kind of adapter layer that converted the CALayer methods into the types and meanings needed by UIDynamicItem . 您需要的是某种适配器层,它将CALayer方法转换为UIDynamicItem所需的类型和含义。

Luckily, UIKit offers exactly such an adapter layer. 幸运的是,UIKit提供了这样一个适配器层。 It's called UIView . 它被称为UIView Just put each layer in a view and nest the views. 只需将每个图层放在视图中并嵌套视图即可。

I had long thought of views as very heavyweight, particularly coming from the OS X world. 我一直认为视图非常重要,特别是来自OS X世界。 So I always thought "if you want this to be fast, you'd better do it with a layer." 所以我一直认为“如果你想让它变快,你最好用一层来做。” But it turns out that views are actually quite thin and there isn't a lot of overhead vs a layer in most cases, particularly for the numbers you're talking about in iOS. 但事实证明,视图实际上非常薄,并且在大多数情况下,与图层相比没有太多开销,特别是对于您在iOS中讨论的数字。 See the TearOff demo for an example that does UIKItDynamics with many dozens of views without trouble. 请参阅TearOff演示,了解UIKItDynamics可以毫不费力地查看多个视图的示例。

If you really do need layers, then yes, you can definitely still do it. 如果你确实需要图层,那么是的,你绝对可以做到。 Just create the adapter yourself. 只需自己创建适配器。 It just needs to hold a CALayer and conform to UIKitDynamics . 它只需要持有CALayer并符合UIKitDynamics It doesn't have to do anything else. 它不需要做任何其他事情。 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'd just animate this object, and that causes the layer to animate equivalently. 您只需为此对象设置动画,这会使图层等效地进行动画处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM