What is the reason for UIgravity not working if not declared as a property?

436 views Asked by At

Okay so i started learning UIDynamics and wanted to just work it out on small box.
I declared UIGravityBehaviour and UIDynamicsBehaviour in my ViewController.m and coded the UIView, but when i executed the code, it was not working.
But just as i declared them as @property in my .h file, the program was working completely fine.
What is the reason behind that?
What is the difference between declaring it as @property and without declaring it as @property?

Here are my files.

Before using @property

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end


ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIView* box = [[UIView alloc]initWithFrame:CGRectMake(100, 50, 100, 100)];
    box.backgroundColor = [UIColor blackColor];
    [self.view addSubview:box];
    UIDynamicAnimator* myAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    UIGravityBehavior* gravityBehaviour = [[UIGravityBehavior alloc] initWithItems:@[box]];
    [myAnimator addBehavior: gravityBehaviour];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

After Declaring it as @property

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (strong,nonatomic) UIDynamicAnimator* myAnimator ;
@property (strong,nonatomic) UIGravityBehavior *gravityBehavior;
@property (strong,nonatomic) UICollisionBehavior *collisionBehavior ;
@end


ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIView* box = [[UIView alloc]initWithFrame:CGRectMake(100, 50, 100, 100)];
    box.backgroundColor = [UIColor blackColor];
    [self.view addSubview:box];
    self.myAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    self.gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[box]];
    self.collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[box]];
    self.collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
    [self.myAnimator addBehavior:self.gravityBehavior];
    [self.myAnimator addBehavior:self.collisionBehavior];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
2

There are 2 answers

3
Joride On

If you are using ARC: The UIDynamicAnimator probably does not have a strong reference to the UIGravityBehavior. So after your viewDidLoad method returns, no one owns that UIGravityBehavior and ARC will make sure that that point it is released. When you make a property for it, your viewController owns it, so the UIGravityBehavior will survive until you viewController gets deallocated.

0
Shimon On

You don't have to move UIGravityBehavior to a property, only UIDynamicAnimator to make it work. However, it's probably a good idea anyway in case you want to remove specific gravity behaviours rather than all of them at once.