2

我正在尝试使用 swift 在 NSObject 类中使用 UIDynamicAnimator 创建具有动态行为的自定义警报视图,而将 UISnapBehaviour 添加到 NSObject 类初始化方法中的视图捕捉行为不起作用,例如查看下面的代码

import UIKit

class DynamicBehaviour: NSObject {

var Animator:UIDynamicAnimator!
var TargetView:UIView!
var TestView:UIView!

override init() {
    super.init()
}

init(SourceViews:UIView) {
    super.init()

    TestView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    TestView.backgroundColor = UIColor.blueColor()
    TargetView.addSubview(TestView)

    Animator = UIDynamicAnimator(referenceView: TargetView)
    let snapBehavior: UISnapBehavior = UISnapBehavior(item: TestView, snapToPoint: TargetView.center)
    Animator.addBehavior(snapBehavior)

  }
}

“TestView”作为子视图添加到“Target”,但捕捉行为不起作用。

我在 ObjectiveC 中尝试了相同的代码

#import "DynamicBehaviour.h"
#import <UIKit/UIKit.h>

@interface DynamicBehaviour ()
@property(nonatomic,strong)UISnapBehavior * Snap_behaviour;
@property (nonatomic,strong)UIDynamicAnimator * Animator;


@end
@implementation DynamicBehaviour

-(instancetype)initWithSourceView:(UIView *)TargetView{
   if (self = [super init]) {
      UIView * TestView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100,     100)];
      TestView.backgroundColor = [UIColor blueColor];
      [TargetView addSubview:TestView];

      self.Animator = [[UIDynamicAnimator    alloc]initWithReferenceView:TargetView];
       self.Snap_behaviour = [[UISnapBehavior alloc]initWithItem:TestView snapToPoint:TargetView.center];
       [self.Animator addBehavior:self.Snap_behaviour];
   }
  return self;
  }


 @end

它工作正常,“TestView”捕捉到 TargetView 的中心。我不知道 swift 代码有什么问题。

这是我尝试过的:

  1. 在 UIViewController 类中编码时动态效果工作正常,问题仅在 swift 中子类化 NSObject 时存在。
  2. 我已经尝试过其他动态行为,例如 UIGravityBehavior,同样的问题也存在于 swift 中。
  3. 在 ObjectiveC 对象类中完成了相同的示例工作,它工作正常,我也附上了工作的 ObjC 代码。

似乎问题可能存在于 init 方法或变量 decleration 不确定但是,我不知道如何解决该问题。我已经阅读了互联网上的许多文章。我也搜索过 StackOverflow。请帮忙。

4

1 回答 1

0

您在 Swift 中的代码与 Objective-C 代码并不完全相同:Objective-C 代码具有强引用 Snap_behaviour,但 Swift 代码只有本地只读变量。这是 Swift 的等价物:

class DynamicBehaviour: NSObject {

    var Animator:UIDynamicAnimator!
    var snapBehaviour:UISnapBehavior!
    var TargetView:UIView!
    var TestView:UIView!

    override init() {
        super.init()
    }

    init(SourceViews:UIView) {
        super.init()

        TestView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        TestView.backgroundColor = UIColor.blueColor()
        TargetView.addSubview(TestView)

        Animator = UIDynamicAnimator(referenceView: TargetView)
        snapBehaviour = UISnapBehavior(item: TestView, snapToPoint: TargetView.center)
        Animator.addBehavior(snapBehaviour)

    }
}

通常我使用 UIDynamicBehaviour 作为这样的组合行为的基类

class CombinedBehavior: UIDynamicBehavior {

    lazy var collider: UICollisionBehavior = {
        let lazilyCreatedCollider = UICollisionBehavior()
        lazilyCreatedCollider.translatesReferenceBoundsIntoBoundary = true
        lazilyCreatedCollider.collisionMode = UICollisionBehaviorMode.Everything
        return lazilyCreatedCollider
    }()

    lazy var itemBehavior: UIDynamicItemBehavior = {
        let lazilyCreatedBehavior = UIDynamicItemBehavior()
        lazilyCreatedBehavior.allowsRotation = true
        lazilyCreatedBehavior.elasticity = 0
        lazilyCreatedBehavior.resistance = 100
        lazilyCreatedBehavior.angularResistance = 100
        lazilyCreatedBehavior.friction = 100
        return lazilyCreatedBehavior
    }()

    override init() {
        super.init()
        addChildBehavior(collider)
        addChildBehavior(itemBehavior)
    }

    func addBarrier(path: UIBezierPath, named name: String) {
        collider.removeBoundaryWithIdentifier(name)
        collider.addBoundaryWithIdentifier(name, forPath: path)
    }

    func addView(view: UIView) {
        dynamicAnimator?.referenceView?.addSubview(view)
        collider.addItem(view)
        itemBehavior.addItem(view)
    }

    func removeView(view: UIView) {
        collider.removeItem(view)
        itemBehavior.removeItem(view)
        view.removeFromSuperview()
    }
}

将此代码放入您的控制器中

lazy var animator: UIDynamicAnimator = {
    let lazilyCreatedDynamicAnimator = UIDynamicAnimator(referenceView: self.view) // or any view you needed
    // if you need delegate in your controller uncomment this
    //        lazilyCreatedDynamicAnimator.delegate = self
    return lazilyCreatedDynamicAnimator
}()

var combinedBehavior = CombinedBehavior()

override func viewDidLoad() {
    // your other code
    animator.addBehavior(combinedBehavior)
}
于 2016-05-04T08:08:56.057 回答