I made an animation, fade in and fade out on a cell. When I press the cell(a button on the entire cell) the action is delegate via a protocol on a collectionView and pops to another controller (detailController).
The cell
- (IBAction)cellButtonPressed:(id)sender {
[self fadeIn];
}
-(void)fadeIn {
[UIView animateWithDuration:0.5
delay:0.0
options:0.0
animations:^{
self.coverAlbumPhoto.alpha = 0.0f;
self.shadowView.alpha = 0.0f;
self.mountainBorderImageView.alpha = 0.0f;
} completion:^(BOOL finished) {
[self fadeOut];
}];
}
-(void)fadeOut {
[UIView animateWithDuration:0.5
delay:0.0
options:0.0
animations:^{
self.coverAlbumPhoto.alpha = 1.0f;
self.shadowView.alpha = 1.0f;
self.mountainBorderImageView.alpha = 1.0f;
} completion:^(BOOL finished) {
if ([self.delegate respondsToSelector:#selector(tapCellButtonAtIndexPath:)]) {
[self.delegate tapCellButtonAtIndexPath:self.indexPath];
}
}];
}
Collection View
(void)tapCellButtonAtIndexPath:(NSIndexPath *)indexPath {
ArtworkModel *artworkModel = (ArtworkModel *)[listOfArtworks objectAtIndex:indexPath.row];
FBWorkDetailsViewController *dvc = [[FBWorkDetailsViewController alloc] initWithArtwork:artworkModel];
FBLeftMenuViewController *left = [[FBLeftMenuViewController alloc] init];
MFSideMenuContainerViewController *container = [MFSideMenuContainerViewController
containerWithCenterViewController: dvc
leftMenuViewController: left
rightMenuViewController:nil
withHeader: YES];
[container.titleLabel setText:#"WORK DETAILS"];
[self.navigationController pushViewController: container animated: YES];
}
The problem is that the animation is TOO SLOW. Can anybody explain me why? Thanks.
You have 2 animations, each with a duration of .5 seconds. That gives a total duration of 1 second. If you want it to be faster, use shorter durations. A total animation time of .2 to .3 seconds is probably a good place to start, so try backing down the duration of each step to 0.15 seconds (0.3 seconds total).
Related
I have a One Uibutton in Buttom. when User click on that button a uiview animation is display like popup from buttom to up.
this is my code
-(void)viewDidLoad
{
[super viewDidLoad];
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 1000, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
}
- (IBAction)animated:(id)sender
{
if(_isAnimated)
{
[UIView animateWithDuration:0.3
delay:0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 520, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
}
completion:^(BOOL finished){
}];
_isAnimated=NO;
}
else
{
[UIView animateWithDuration:0.3
delay:0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 1000, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
}
completion:^(BOOL finished)
{
}];
_isAnimated=YES;
}
}
Uiview animation is perfectly working but when uiview appear than background view is create shadow(or blur)like uiactionsheet and after finished animation background view is clear.
i dont know how to implemented.
plz help me
i am new in ios...
You can add a UIView in background and set its backgroundcolor black and alpha 0.5 in storyboard. Then change its alpha from 0.5 to 0 with animation. You can also add an UITapGestureRecognizer to detect taps on it and dissmiss the view when user taps outside.
-(void)viewDidLoad
{
[super viewDidLoad];
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 1000, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
}
- (IBAction)animated:(id)sender
{
if(_isAnimated)
{
[UIView animateWithDuration:0.3
delay:0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 520, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
//showing background view here
self.viewBackground.alpha = 0.5;
}
completion:^(BOOL finished){
}];
_isAnimated=NO;
}
else
{
[UIView animateWithDuration:0.3
delay:0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 1000, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
//dismissing background view here
self.viewBackground.alpha = 0.0;
}
completion:^(BOOL finished)
{
}];
_isAnimated=YES;
}
}
For detecting taps outside and dismissing your view:
Create a UITapGestureRecognizer:
#interface ViewController ()
{
UITapGestureRecognizer *tapGesture;
}
Initialize it in ViewDidLoad:
-(void)viewDidLoad
{
//defining your gesture method
tapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(handleSingleTapGesture:)];
//adding gesture recognizer on the background view
[self.backgroundView addGestureRecognizer:tapGestureRecognizer];
}
In your Gesture Recognizer Method:
-(void)handleSingleTapGesture:(UITapGestureRecognizer *)tapGestureRecognizer
{
[UIView animateWithDuration:0.3
animations:^{
//dismissing background view here
self.viewBackground.alpha = 0.0;
}
completion:^(BOOL finished){
}];
}
Hope this helps.
add your code in viewdidload.add QuartzCore framework
#import <QuartzCore/CAAnimation.h>
self.BuyButtonPopUpView.frame = CGRectMake(self.BuyButtonPopUpView.frame.origin.x, 1000, self.BuyButtonPopUpView.frame.size.width,self.BuyButtonPopUpView.frame.size.height);
CABasicAnimation *animate = [CABasicAnimation animationWithKeyPath:#"shadowOpacity"];
animate.fromValue = [NSNumber numberWithFloat:1.5];
animate.toValue = [NSNumber numberWithFloat:0.5];
animate.duration = 1.0;
[self.BuyButtonPopUpView.layer addAnimation:animation forKey:#"shadowOpacity"];
self.BuyButtonPopUpView.layer.shadowOpacity = 0.0;
you can add a UIVisualEffectView first then add the popup over this view.
here is a tutorial link https://www.raywenderlich.com/84043/ios-8-visual-effects-tutorial
I have one one collectionview in that I have 10 images loaded from webservice. I want to autoscroll that imageview from 1st to last position and then last to 1st position continuously whenever that page appears.
I use below method
-(void)scrollSlowly
{
CATransition *transition = [CATransition animation];
transition.duration = 4.0f;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[UIView animateWithDuration:5.0f
delay:3.0f
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{
[self.CollectionView setContentOffset:CGPointMake(CGFLOAT_MAX ,0)];
}
completion:nil];
[self.CollectionView.layer addAnimation:transition forKey:#"transition"];
}
-(void)scrollSlowlyToPoint
{
self.CollectionView.contentOffset = self.scrollingPoint;
// Here you have to respond to user interactions or else the scrolling will not stop until it reaches the endPoint.
if (CGPointEqualToPoint(self.scrollingPoint, self.endPoint))
{
[self.scrollingTimer invalidate];
}
// Going one pixel to the right.
self.scrollingPoint = CGPointMake(self.scrollingPoint.x+1, self.scrollingPoint.y);
}
I want to autoscroll horizontally in Objective-C. thanks in advance
Create a custom UICollectionViewCell class, create and connect an outlet for image view.
In .h file:
NSMutableArray *imgArr;
NSInteger testIndexPath;
I guess you can implement the datasource methods for UICollectionView.
In cellForItemAtIndexPath add this line after adding images to the imageview
testIndexPath=indexPath.row;//this will give you the indexPath for cell
Now add this two methods in your .m file:
-(void)autoScroll{
CGFloat point = self.collectionVw.contentOffset.x;
CGFloat lo = point + 1;
[UIView animateWithDuration:0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.collectionVw.contentOffset = CGPointMake(lo, 0);
}completion:^(BOOL finished){
if (testIndexPath==8)
{
[self autoScrollReverse];
}
else{
[self autoScroll];
}
}];
}
-(void)autoScrollReverse{
CGFloat point = self.collectionVw.contentOffset.x;
CGFloat lo = point - 1;
[UIView animateWithDuration:0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.collectionVw.contentOffset = CGPointMake(lo, 0);
}completion:^(BOOL finished){
if(testIndexPath == 0){
[self autoScroll];
}else{
[self autoScrollReverse];
}
}];
}
//Call [self autoScroll] in your viewDidLoad
Better way to scroll index from top to bottom and bottom to top.
This will move to index 10 means scroll top to bottom
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:9 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
For again scroll bottom to top which move to index 0
[UIView animateWithDuration:3
delay:0.1
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
completion:nil];
You can also set scrolling from top to bottom in UIVIew animation like above.
Set the first method in ViewWillAppear and set second method in ViewDidAppear if you need animation for every time page appear
Please apply this one. May be its help to you
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyCollectionViewCell" forIndexPath:indexPath];
[UIView animateWithDuration:0.2 animations:^{
cell.transform = CGAffineTransformMakeTranslation(0.0, -50);
}];
[self delayBy:0.5 code:^{ // call block of code after time interval
[UIView animateWithDuration:0.3 animations:^{
cell.transform = CGAffineTransformIdentity;
}];
}];
return cell;
}
This may help solve your problem:
int maxDelay = 4;
int delayInSeconds = arc4random() % maxDelay;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//your codes//
});
This is a continuation of this question
CGRectMake : How To Calculate X and Y For UIPickerView Animation?
answered by https://stackoverflow.com/users/2315974/danypata
I have a picker view that I want to animate on and off screen on a button press and using the code in the previous question/answer I have got it to animate on screen the first time the button is pressed.
the second tome the button is pressed it just disappears and then the third time it is pressed it animates to the wrong place...please help
the code
if (self.pickerSort.hidden == NO) {
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.pickerSort.frame = CGRectMake(0,self.view.frame.size.height
+ self.pickerSort.frame.size.height,-self.pickerSort.frame.size.width,-self.pickerSort.frame.size.height);
}
completion:^(BOOL finished) {
}];
self.pickerSort.hidden = YES;
// [self performSelector:#selector(hidePicker) withObject:nil afterDelay:1];
} else if (self.pickerSort.hidden == YES) {
self.pickerSort.hidden = NO;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.pickerSort.frame = CGRectMake(0 ,
self.view.frame.size.height
- self.pickerSort.frame.size.height,
self.pickerSort.frame.size.width,
self.pickerSort.frame.size.height);
}
completion:^(BOOL finished) {
}];
[self.view bringSubviewToFront:self.pickerSort];
Behavior in images - button press animates onto screen beautifully
Second Press it disappears with no animation
Third Press it animates to here
Any help would be great...functionality I am looking for is how to put the picker view back on an animation so the 3rd press is the same as the first
Please try to use the below code.
self.pickerSort.hidden = NO;
NSTimeInterval duration = 0.5;
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
CGRect pickerFrame = self.pickerSort.frame;
// currently picker is off the screen, show it.
if (pickerFrame.origin.y == self.view.frame.size.height) {
// set frame to show picker
pickerFrame.origin.y = self.view.frame.size.height - self.pickerSort.frame.size.height;
} else {
// set frame to hide picker
pickerFrame.origin.y = self.view.frame.size.height;
}
self.pickerSort.frame = pickerFrame;
}
completion:^(BOOL finished) {
self.pickerSort.hidden = YES;
}];
After playing around with this and learning the ins and outs of frames and CGRects, I achieved this by using the following code
if (pickerSort.hidden == YES) {
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
pickerSort.hidden = NO;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[self.tableStations addSubview:visualEffectView];
pickerSort.frame = CGRectMake(0,0,originalPickerFrame.size.width,originalPickerFrame.size.height);
visualEffectView.frame = CGRectMake(0,0,originalPickerFrame.size.width,originalPickerFrame.size.height - 64);
}
completion:^(BOOL finished) {
self.navigationController.navigationItem.leftBarButtonItem.enabled = NO;
}];
}
else
{
visualEffectView.hidden = YES;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
pickerSort.frame = CGRectMake(0,-originalPickerFrame.size.height,0,0);
}
completion:^(BOOL finished) {
self.navigationController.navigationItem.leftBarButtonItem.enabled = YES;
pickerSort.hidden = YES;
}];
}
I set the original frame size in viewDidLoad like so
pickerSort = [[UIPickerView alloc]initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
originalPickerFrame = pickerSort.frame;
pickerSort.frame = CGRectMake(0,-originalPickerFrame.size.height,0, 0);
Hope this can help somebody in the future
I have made a game of Tic-Tac-Toe. If the game ends in a tie, an animated hudView appears for a couple of seconds. Then the game starts over, and that's when my problems occur. It doesn't respond to me tapping on screen to draw 'X' or 'O''s anymore. My suspicion is that the hudView is still there. I have tried different things to remove it, with no luck.
+ (instancetype)hudInView:(UIView *)view animated:(BOOL)animated
{
HudView *hudView = [[HudView alloc] initWithFrame:view.bounds];
hudView.opaque = NO;
[view addSubview:hudView];
view.userInteractionEnabled = NO;
[hudView showAnimated:YES];
return hudView;
}
And the animation:
- (void)showAnimated:(BOOL)animated
{
if (animated) {
self.alpha = 0.0f;
self.transform = CGAffineTransformMakeScale(1.3f, 1.3f);
[UIView animateWithDuration:4.5 animations:^{
self.alpha = 1.0f;
self.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
self.alpha = 0.0f;
}];
}
}
In the completion block, I have tried the following:
[self.superview removeFromSuperview];
In my ViewController where all of this gets called I've tried:
HudView *hudView = [HudView hudInView:self.view animated:YES];
hudView.text = #"\tIt's a Tie\n";
[hudView removeFromSuperview];
[self.view removeFromSuperview]
[hudView.superview removeFromSuperview];
Nothing I've tried so far is working. Any help would be much appreciated.
I am a bit new to iOS development. I am working on an app that has about 5,000 visual data points, organized in categories. I want to present them in a UICollectionView with very tiny UICollectionViewCells. When a user taps on something in a category, the category zooms in with the selected cell in focus. Pretty much like how the "Photos" tab of the iOS 7 Photos app works: Years > Collections > Moments.
How do I go about implementing a custom transition like that? Are there any open-source libraries already written for accomplishing this?
If you can't find any library, try to play with this code I wrote for custom animations. You can specify a start point, an end point, start scale and end scale of a view that you want to zoom and scale in or out. See below an example how I use it. The point is to use a fake view to push it with animation, then push and pop your real view without animation. viewobj is set to fade in from alpha 0 to alpha 1, zoomableView will scale from the point/scale you give as parameter to the final position you set it in your storyboard/xib. Hope it will help.
# you can create a category vor UIView and add these methods
- (void) addSubView:(UIView*)viewObj animateFromPoint:(CGPoint)point zoomableView:(UIView*)view minScale:(CGSize)scale completion:(void (^)(void))completionBlock{
CGPoint center = view.center;
[view setTransform:CGAffineTransformMakeScale(scale.width, scale.height)];
viewObj.alpha = 0;
view.center = point;
[self addSubview:viewObj];
[self addSubview:view];
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
view.center = center;
[view setTransform:CGAffineTransformMakeScale(1.0, 1.0)];
viewObj.alpha = 1;
}
completion:^(BOOL fin){
if(completionBlock)
completionBlock();
}];
}
- (void) removeFromSuperviewAnimateToPoint:(CGPoint)point zoomableView:(UIView*)view minScale:(CGSize)scale completion:(void (^)(void))completionBlock{
CGRect startFrame = view.frame;
self.alpha = 1;
[self.superview addSubview:view];
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
view.center = point;
[view setTransform:CGAffineTransformMakeScale(scale.width, scale.height)];
self.alpha = 0;
}
completion:^(BOOL fin){
[self removeFromSuperview];
[view removeFromSuperview];
[view setTransform:CGAffineTransformMakeScale(1, 1)];
view.frame = startFrame;
[self addSubview:view];
if(completionBlock)
completionBlock();
}];
}
And to use them:
# your did select item at index path:
self.itemDetails = [self.storyboard instantiateViewControllerWithIdentifier:#"ItemDetailsVC"];
ItemDetailsVC* itd = [self.storyboard instantiateViewControllerWithIdentifier:#"ItemDetailsVC"];
__weak UIViewController* wself = self;
[self.view addSubView:self.itemDetails.view animateFromPoint:self.zoomedFrom zoomableView:self.itemDetails.viewZoomable minScale:CGSizeMake(0.371134, 0.371134) completion:^{
[wself.navigationController pushViewController:itd animated:NO];
}];
self.addSubviewIsUp = YES;
# back button of the view you added:
[self.navigationController popViewControllerAnimated:NO];
# viewdidapear of your main screen
if(self.addSubviewIsUp){
[self.addVc.view removeFromSuperviewAnimateToPoint:CGPointMake(160, 75) zoomableView:self.addVc.zoomableView minScale:CGSizeMake(0.01, 0.01) completion:^{
}];
}
self.addSubviewIsUp = NO;