如何在 NSObject 类中添加动态行为:Swift
Posted
技术标签:
【中文标题】如何在 NSObject 类中添加动态行为:Swift【英文标题】:How do i add dynamic behaviour in NSObject class : Swift 【发布时间】:2016-05-04 06:39:57 【问题描述】:我正在尝试使用 swift 在 NSObject 类中使用 UIDynamicAnimator 创建具有动态行为的自定义警报视图,而将 UISnapBehaviour 添加到 NSObject 类 init 方法中的视图捕捉行为不起作用,例如查看下面的代码
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 代码有什么问题。
这是我尝试过的:
-
在 UIViewController 类中编码时动态效果工作正常,问题仅在 swift 中子类化 NSObject 时存在。
我已经尝试过其他动态行为,例如 UIGravityBehavior,Swift 中也存在同样的问题。
在 ObjectiveC 对象类中完成了相同的示例工作,它工作正常,我也附上了工作的 ObjC 代码。
似乎问题可能存在于 init 方法或变量 decleration 不确定 但是,我不知道如何解决这个问题。我已经阅读了互联网上的许多文章。我也搜索过 ***。请帮忙。
【问题讨论】:
【参考方案1】:您在 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)
【讨论】:
感谢 Andriy 的回复,现在我已经强烈声明“Snap_behaviour”,但我仍然无法对我的代码产生动态影响。那么您推荐的代码运行完美。我有将 UIGravityBehaviour 添加到您的“CombinedBehavior”类中,它工作正常。当我尝试添加 UISnapBehaviour 时,它会引发运行时错误 init is undefined for objects of type UISnapBehavior 。你能帮我解决吗? var snap: UISnapBehavior? willSet if snap != nil animator.removeBehavior(snap!) didSet if snap != nil animator.addBehavior(snap!) // 把这个放在你需要捕捉的地方,通常在 UILongPressGestureRecognazier 中: snap = UISnapBehavior(item: selectedDrop!, snapToPoint: point) // 完成后删除 snap: snap = nil以上是关于如何在 NSObject 类中添加动态行为:Swift的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中单击 NSObject 内部的 tableView 中的项目时,如何在 NSObject 类中的 UIViewController 上的 UIView 之间正确切换?
iOS9如何调用NSObject类中的UIAlertviewController?
如何在 Swift 4 的 NSObject 类中初始化 json 内的数组?
在 NSObject 类中设置协议并在 UIViewController 类中调用它们