1

I'm trying to move a UIView across the screen.

UIGravityBehavior and UIPushBehavior both take things like density, velocity and friction into account. I tried to implement my own dynamic behavior that ignores those physics.

My UIDynamicBehavior subclass and some basic implementation

// MYDynamicBehavior.h
@interface MYDynamicBehavior : UIDynamicBehavior
- (void)addItem:(id<UIDynamicItem>)item;
- (void)removeItem:(id<UIDynamicItem>)item;
@end

// MYDynamicBehavior.m
@interface MYDynamicBehavior ()
@property (strong, nonatomic) NSMutableArray *items;
@end

@implementation MYDynamicBehavior
- (void (^)(void))action
{
    __weak MYDynamicBehavior *weakSelf = self;
    for (UIView *item in weakSelf.items)
        item.center = CGPointMake(item.center.x + 10.0, item.center.y);
}

- (instancetype)init
{
    if (self=[super init]) {
        __weak MYDynamicBehavior *weakSelf = self;
        weakSelf.action = ^{
            for (UIView *item in weakSelf.items)
                item.center = CGPointMake(item.center.x + 10.0, item.center.y);
        };
    }
    return self;
}

- (void)addItem:(id<UIDynamicItem>)item
{
    [self.items addObject:item];
}
@end

// ViewController.m
// #includes
@interface ViewController ()
@property (strong, nonatomic) UIDynamicAnimator *ani;
@property (strong, nonatomic) UIView *kin;
@property (strong, nonatomic) MYDynamicBehavior *skywalk;
@end

@implementation ViewController
…
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.ani = [[UIDynamicAnimator alloc] init];
    self.kin = // some view
    self.skywalk = [[MYDynamicBehavior alloc] init];
    [self.ani addBehavior:self.skywalk];
    [self.skywalk addItem:kin];
}
@end

I'm trying to recreate this from memory, I think the basics are here

Anyway, it's my impression from the documentation that the action property is where I need to implement my animation. It doesn't appear that my action black is ever called, however.

This is the closest I've come to a solution, but I still haven't solved this problem yet.

What am I missing? Why isn't my custom UIDynamicBehavior subclass working?

Community
  • 1
  • 1
Alex John
  • 65
  • 4

1 Answers1

1

I haven't found the documentation that states this explicitly, and I can't guess at the underlying reason, but I have found that if my custom UIDynamicBehavior classes call their action blocks only if there is a child behavior added which has at least one item in it.

It's weird enough that I think I'm experiencing a side effect rather than this working as intended, but that does reliably get the action block to fire. Would be really interested if anybody could shed light on the why, though. :1

Jonathan Zhan
  • 1,883
  • 1
  • 14
  • 17