首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift -未调用的UICollisionBehavior委托方法

Swift -未调用的UICollisionBehavior委托方法
EN

Stack Overflow用户
提问于 2017-09-27 07:43:07
回答 1查看 518关注 0票数 0

我正在做一个简单的动画,这需要我处理一些与边界的碰撞。

我有一个类,viewcontroller,我将它扩展为一个UICollisionBehaviorDelegate,这样我就可以识别和处理视图冲突。

由于某些原因,当发生冲突时,我的委托方法永远不会触发。

代码语言:javascript
复制
class ViewController: UIViewController {

    var fallingImageViews: [UIImageView]!
    var downAnimator: UIDynamicAnimator!

    override func viewDidLoad() {
        super.viewDidLoad()

        //imagine fallingImageViews Initializers happening here

        downAnimator = initializeAnimators()
    }

    func initializeAnimators() -> UIDynamicAnimator {
        let downwardAnimator = UIDynamicAnimator(referenceView: self.view)

        downwardAnimator.addBehavior(setBoundaries())
        downwardAnimator.addBehavior(setGravity())
        downwardAnimator.addBehavior(setBounciness())
        downwardAnimator.delegate = self

        return downwardAnimator
    }

    func setBoundaries() -> UICollisionBehavior {
        let boundaries = UICollisionBehavior(items: fallingImageViews)
        boundaries.collisionDelegate = self

        // prevent collisions between items
        boundaries.collisionMode = .boundaries

        boundaries.setTranslatesReferenceBoundsIntoBoundary = true

        return boundaries
    }
}

// MARK: Collision Behavior Delegate
extension ViewController: UICollisionBehaviorDelegate, UIDynamicAnimatorDelegate {

    func collisionBehavior(_ behavior: UICollisionBehavior, endedContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?) {
        print(identifier)
    }
    func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint) {
        print(identifier)
    }
}
EN

回答 1

Stack Overflow用户

发布于 2017-09-27 08:54:20

我完全放弃了我的旧答案,并更新了它。很抱歉我误导了你,但这是我修改后的答案:

其思想是将行为添加到要设置动画的对象(在本例中为fallingImageViews)。

因此,这里的所有代码实际上都应该放到一个继承自UIImageView的类中(在我的示例代码中,您将看到我继承的是一个CardCtrl对象,但它也可能是一个UIImageView)。

您必须进行的唯一更改是UIDynamicAnimator的引用视图必须为superview,并且所有动画行为的所有引用视图都设置为[self]

下面是我的一个旧项目中的一些示例代码:

代码语言:javascript
复制
@IBDesignable class SlidingCard: CardCtrl, UICollisionBehaviorDelegate
{
   ...
    //MARK: - Private Properties

    private var gripHeightAnch: NSLayoutConstraint = NSLayoutConstraint()
    private var animator: UIDynamicAnimator!
    private var dynamicItem: UIDynamicItemBehavior!
    private var collisionBnds: UICollisionBehavior!
    private var snap: UISnapBehavior!
    private var botBndryPt: CGFloat!
    private var gravity: UIGravityBehavior!
    private var pan: UIPanGestureRecognizer!

    ...

    //MARK: - Delegate Methods

    func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem,
                           withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint)
    {
        guard let identifier = identifier else {return}
        if String(describing: identifier) == "bot"
        {
            sendActions(for: .touchDragOutside)
        }
        else
        {
            sendActions(for: .touchDragInside)
        }
    }

    ...

    //MARK: - Private Setup Methods

    private func defineSlideBehavior()
    {
        if animator == nil
        {
            animator = UIDynamicAnimator(referenceView: superview!)
        }
        animator!.removeAllBehaviors()

        //Check to see if behaviors are already installed because .removeAllBehaviors() doesn't
        //always work
        var addItem = true
        var addBounds = true
        var addGravity = true
        for blarHar in animator!.behaviors
        {
            if blarHar.isKind(of: UIDynamicItem.self)
            {
                addItem = false
            }
            if blarHar.isKind(of: UICollisionBehavior.self)
            {
                addBounds = false
            }
            if blarHar.isKind(of: UIGravityBehavior.self)
            {
                addGravity = false
            }
        }
        //Make it so the card doesn't wobble
        if dynamicItem == nil && addItem
        {
            dynamicItem = UIDynamicItemBehavior(items: [self])
            dynamicItem.allowsRotation = false
            dynamicItem.elasticity = 0
        }
        animator!.addBehavior(dynamicItem)

        //Add two boundaries for the drawer to collide with
        if collisionBnds == nil && addBounds
        {
            collisionBnds = UICollisionBehavior(items: [self])
            collisionBnds.collisionDelegate = self
        }
        botBndryPt = frame.maxY * 2 + 1.5
        collisionBnds.removeAllBoundaries()
        collisionBnds.addBoundary(withIdentifier: "top" as NSCopying,
                                  from: CGPoint(x: frame.minX, y: frame.minY - 1.5),
                                  to: CGPoint(x: frame.maxX, y: frame.minY - 1.5))
        collisionBnds.addBoundary(withIdentifier: "bot" as NSCopying,
                                  from: CGPoint(x: frame.minX, y: botBndryPt),
                                  to: CGPoint(x: frame.maxX, y: botBndryPt))
        animator!.addBehavior(collisionBnds)

        //Define the initial gravity that affects the drawer
        if addGravity
        {
            gravity = UIGravityBehavior(items: [self])
            gravity.gravityDirection = CGVector(dx: 0, dy: -gravityStrength)
            animator!.addBehavior(gravity)
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46437361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档