I have a UIVIew (container) and another UIView (box) the box view is inside of the ContainerView. When a UIButton is pressed I would like the box view to drop down off the bottom of the screen, and bounce with 10px left; then once the bouncing has stopped I still want the box to have 10px showing. Here is some sample code of from another question:
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self]; //self is the container
UIGravityBehavior* gravityBehavior = [[UIGravityBehavior alloc] initWithItems:#[box]];
[animator addBehavior:gravityBehavior];
UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:#[reportBar.bar]];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[animator addBehavior:collisionBehavior];
UIDynamicItemBehavior *elasticityBehavior =
[[UIDynamicItemBehavior alloc] initWithItems:#[box]];
elasticityBehavior.elasticity = 0.7f;
[animator addBehavior:elasticityBehavior];
The code is running when it should but the box isn't dropping.
Edit 1:
Self refers to the container UIView
I have also tried changing self for the currentViewController.view, no change.
Edit 2:
all of this code is inside the container view implementation file.
give a try to make animator property,
#property UIDynamicAnimator *animator;
and then your code,
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self];
...
I think you didn't specify the correct reference view. It should be either self.view or self.containerView
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self];
Update
I think you should put the code in the ViewController for this scene and as #BaSha suggested create a animator property and after a button click you will add the behavior and will reference self.containerView
Just make sure that boxView is inside of the containerView
The following code snippet can provide BOUNCE EFFECT on your views.
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:#"position.y"];</br>
[animation setFromValue:[NSNumber numberWithFloat:y-position1]];
[animation setToValue:[NSNumber numberWithFloat:y-position2]];
[animation setDuration:.7]; // time gap between the bounces
animation.repeatCount=500; // no:of times bounce effect has to be done
[YOURVIEW.layer addAnimation:animation forKey:#"somekey"];
Related
What I want to achieve: I want to create a copy of selected view.
I have two UIImageViews on UIView. I am selecting both the views and want to clone both the views.
Everything is working fine until I am not rotating the UIImageView. If am rotating the view UIImageView changing its frame.
UIView *viewClone = [[UIView alloc]initWithFrame:CGRectMake(fltLeadingMin, fltTopMin, fltCloneViewWidth, fltCloneViewHeight)];
viewClone.backgroundColor = [UIColor redColor];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[viewClone addGestureRecognizer:panGesture];
for (UIImageView *imgView in arrSelectedViews) {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:imgView];
UIImageView *imgViewClone = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
imgViewClone.frame = CGRectMake(imgViewClone.frame.origin.x - viewClone.frame.origin.x, imgViewClone.frame.origin.y - viewClone.frame.origin.y, imgView.frame.size.width, imgView.frame.size.height);
imgViewClone.backgroundColor = UIColor.blueColor;
[viewClone addSubview:imgViewClone];
}
Here is a screenshot of how it looks like now:
After rotating the image, its frame won't work anymore and that's the reason for your issue.
You can take a look at Apple document for UIView's transform property
When the value of this property is anything other than the identity transform, the value in the frame property is undefined and should be ignored.
The solution for this situation is using center and transform properties instead of frame.
UIView *viewClone = [[UIView alloc]initWithFrame:CGRectMake(fltLeadingMin, fltTopMin, fltCloneViewWidth, fltCloneViewHeight)];
viewClone.backgroundColor = [UIColor redColor];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[viewClone addGestureRecognizer:panGesture];
for (UIImageView *imgView in arrSelectedViews) {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:imgView];
UIImageView *imgViewClone = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
// This is the frame before you rotate image, can be replace with another size
CGRect originalFrame = CGRectMake(0, 0, 200, 200);
imgViewClone.frame = originalFrame
// Using center and transform instead of current frame
imgViewClone.center = imgView.center;
imgViewClone.transform = imgView.transform;
imgViewClone.backgroundColor = UIColor.blueColor;
[viewClone addSubview:imgViewClone];
}
I'm trying to use UIKit Dynamics to implement swipe-to-delete on my UICollectionViewCells. Things aren't going as planned, though. Here's the code in UICollectionViewCell's awakeFromNib method:
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.contentView];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:#[self.contentView]];
[collisionBehavior setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(0, 0, 0, -20)];
[self.animator addBehavior:collisionBehavior];
self.gravityBehavior = [[UIGravityBehavior alloc] initWithItems:#[self.containerView]];
self.gravityBehavior.gravityDirection = CGVectorMake(0, 0);
[self.animator addBehavior:self.gravityBehavior];
self.pushBehavior = [[UIPushBehavior alloc] initWithItems:#[self.containerView] mode:UIPushBehaviorModeInstantaneous];
self.pushBehavior.magnitude = 0.0f;
self.pushBehavior.angle = 0.0f;
[self.animator addBehavior:self.pushBehavior];
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:#[self.containerView]];
itemBehavior.elasticity = 0.45f;
[self.animator addBehavior:itemBehavior];
But this is not working so well. This is what happens at launch with the code above:
That behavior seems to be mostly generated by UICollisionBehavior. If I comment it out, the container view with everything that's not the red background doesn't animate, but does show up offset a few points to the left.
Am I right to try to implement this within UICollectionViewCell? What's the right way of doing this?
Thanks!
Never mind. It was pretty much a typo. The collision behavior was attached to the wrong object.
The right code should be
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:#[self.containerView]];
[collisionBehavior setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(0, 0, 0, -20)];
[self.animator addBehavior:collisionBehavior];
Presenting a UIView from under the nav bar with "bounce effect" self.dropDownBar
Despite setting up boundaries the UIView continues to drop off the bottom of the screen
Checked here https://developer.apple.com/library/ios/documentation/uikit/reference/UICollisionBehavior_Class/Reference/Reference.html#//apple_ref/occ/instm/UICollisionBehavior/addBoundaryWithIdentifier:fromPoint:toPoint:
That states:
addBoundaryWithIdentifier:fromPoint:toPoint:
p1
The starting point for the boundary line segment.
p2
The ending point for the boundary line segment. Seem to be doing that,
and here Collision not working between items (no accepted answer and nothing suitable)
.h
<UICollisionBehaviorDelegate>
#property (strong, nonatomic) UIDynamicAnimator *animator;
.m
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
UIGravityBehavior* gravityBehavior =
[[UIGravityBehavior alloc] initWithItems:#[self.dropDownBar]];
[self.animator addBehavior:gravityBehavior];
UICollisionBehavior* collisionBehavior =
[[UICollisionBehavior alloc] initWithItems:#[self.dropDownBar]];
//To - from boundries
[collisionBehavior addBoundaryWithIdentifier:#"NotificationBoundary" fromPoint:CGPointMake(0, 45)
toPoint:CGPointMake(0, 90)];
[self.animator addBehavior:collisionBehavior];
What am I missing here?
I am trying my hand at UIKit Dynamics and am trying to create a simple animation with a ball that bounces off of the screen boundaries.
As shown in the code below, when I add the gravity behavior the ball seems to go off the screen as expected. But when I add the collision behavior, nothing happens. The ball stays as is at the center of the screen where I have drawn it initially.
I also trie to add a push behavior with continuous push force option, but still the ball does not move.
#implementation TAMViewController
UIDynamicAnimator* animator;
UIGravityBehavior* gravity;
UICollisionBehavior* collision;
UIPushBehavior* push;
- (void)viewDidLoad
{
[super viewDidLoad];
TAMBouncyView *ballView = [[TAMBouncyView alloc] initWithFrame:CGRectMake(0,0,
self.view.frame.size.width,
self.view.frame.size.height)];
[self.view addSubview:ballView];
animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
gravity = [[UIGravityBehavior alloc] initWithItems:#[ballView]];
[animator addBehavior:gravity];
collision = [[UICollisionBehavior alloc] initWithItems:#[ballView]];
[collision setTranslatesReferenceBoundsIntoBoundary:YES];
[animator addBehavior:collision];
push = [[UIPushBehavior alloc] initWithItems:#[ballView]
mode:UIPushBehaviorModeContinuous];
[animator addBehavior:push];
// Do any additional setup after loading the view, typically from a nib.
}
I'm trying to modify Apple's PhotoScroller example to make the scrollview that is created into a subview instead of it being a view that takes up the entire screen. Any ideas on how this can be accomplished?
- (void)loadView
{
// Step 1: make the outer paging scroll view
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
pagingScrollView.delegate = self;
// When I do this it fails
[self.view addSubview:pagingScrollView];
// Step 2: prepare to tile content
recycledPages = [[NSMutableSet alloc] init];
visiblePages = [[NSMutableSet alloc] init];
[self tilePages];
}
You just need to modify the frame of the scrollview to be positioned and sized how you want:
This is the line in the view controller that sets it up in the example
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
As an example here is a sample frame with some hardcoded values:
CGRect scrollFrame = CGRectMake(100,100,100,100);
pagingScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
So, I found out that I was able to add the scrollView as a subview by changing the method from loadView to viewDidLoad.
I have no clue why that works, but it does. I'd love to know why that's the case however...