Как добавить динамическое поведение в классе NSObject: Swift
Я пытаюсь создать настраиваемое представление предупреждений с динамическим поведением, используя UIDynamicAnimator в классе NSObject, используя swift, хотя добавление UISnapBehaviour в представление в поведении привязки метода init класса 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. Я не знаю, что не так с быстрым кодом.
Вот что я попробовал:
- Динамический эффект работает нормально при кодировании в классе UIViewController, проблема существует только при создании подкласса NSObject в swift.
- Я пробовал другие динамические поведения, такие как UIGravityBehavior, та же проблема существует в Swift.
- Проделал тот же пример работы в объектном классе ObjectiveC, он работает нормально, я также прикрепил рабочий код ObjC.
Кажется, что проблема может существовать в методе init или в переменной decleration, я не уверен в этом. Однако я не знаю, как решить эту проблему. Я прочитал много статей в Интернете. Я также искал Stackru. Пожалуйста помоги.
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)
}