I'm pretty new to iOS animation and I'm wondering if it's possible to combine an transition between two images along with a translation animation of the UIImageView using CGAffineTransform?
In other words I have two images that I want to animate between, and then I want to apply a simultaneous translation so that the whole thing moves across the page while moving back and forth between the two images.
I know I can apply a CGAffineTransformConcat to combine two CGAffineTransforms such as a CGAffineTransformTranslate and something else. But I don't see a CGAffineTransform which allows me to transition to another UIImage.
The only way I know to animate between images is to use the UIImageView animationImages array combined with startAnimating. However, I don't know how to combine this with a translation like so:
UIImageView* textView = [[UIImageView alloc] initWithFrame:bunnyImage.frame];
textView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"bunnyclose.png"],
[UIImage imageNamed:#"bunnytalk.png"],
nil];
textView.animationDuration = 1.0;
textView.animationRepeatCount = 8;
[textView startAnimating];
[self.view addSubview:textView];
Any suggestions?
In answer to my own question, the block animation function transitionFromView:toView:duration:options:completion as discussed in "Creating Animated Transitions Between Views" is the best solution that I have come up with yet. I use this to animate between images and this can be combined with the block animation animateWithDuration:delay:options:animations:completion: using CGAffineTransformTranslate or simply by changing the center of the UIImageView as discussed in Animations.
Reworking my original codeblock and adding my translation looks something like this:
UIImageView* bunny2View = [[UIImageView alloc] initWithFrame:bunny2Image.frame];
[UIView
transitionFromView:bunny2Image
toView:bunny2View
duration:10.0
options:UIViewAnimationOptionShowHideTransitionViews
completion:^(BOOL finished) {
[UIView
animateWithDuration:dur
animations:^(void) {
CGPoint center = bunny2Image.center;
center.y += deltay;
bunny2Image.center = center;
bunny2View.center = center;
}
completion:^(BOOL finished) {
[UIView
transitionFromView:bunny2View
toView:bunny2Image
duration:10.0
options:UIViewAnimationOptionShowHideTransitionViews
completion:nil];
}];
}];
Still a work in progress, but this is what I've come up with so far!
Related
Im pretty new to coding but I'm starting to get the hang of the basics.
how to make an image stay in its new position after an animation?
Example:
I'm giving an animating object a random position, however, the animation causes the object not to animate at the random position, but instead animate at the position it was given in the view controller. This also happens when I animate a completly different object.
Code I used:
int Random1x;
int Random1y;
IBOutlet UIButton *Start;
IBOutlet UIImageview *Object2;
-(void)ObjectMoving;
-(void)Object2Animate;
-(IBAction)Start:(id)sender{
[self ObjectMoving];
[self Object2Animate];
}
-(void)Object2Animate {
Object2.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed: #"3.png"],
[UIImage imageNamed: #"4.png"],
[UIImage imageNamed: #"1.png"], nil];
Object2.animationDuration = .5
[Object2 setanimationRepeatCount: 0]
[Object2 startAnimating];
}
-(void)ObjectMoving {
Random1y = arc4random() % 466;
Random1y = Random1y + 60;
Random1x = arc4random() % 288;
Object2.center = CGPointMake(Random1x, Random1y);
}
I'd greatly appreciate help, thank you!
If you go to your story board file and click on the View Controller and then file inspector you will see a box for Auto Layout
Post back if that worked.
If you do need to use auto layout then you would have to figure out a different way of moving the image.
I want to add a transition effect between images like fade or anything else.
Here's my code:
-(IBAction)startSlideShow:(id)sender;
{
self.imageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"slide01.png"],
[UIImage imageNamed:#"slide02.png"],
[UIImage imageNamed:#"slide03.png"],
[UIImage imageNamed:#"slide04.png"],
[UIImage imageNamed:#"slide05.png"],
nil];
self.imageView.animationDuration = 15.0;
self.imageView.animationRepeatCount = 0;
[self.imageView startAnimating];
}
Try this, I think you looking for this one,.. github.com/jberlana/JBKenBurns
(or)
I found this on someother search, try this too..
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
Other simple way to achieve: Steps to achieve
Add all the images in one scroll view.
Enable paging for that scroll view.
Based on the content offset of the scroll view highlight the appropriate dot(indicator in the bottom).
I have a UIScrollView filled with UIImageView. The UIScrollView are paging enabled to let the users to "flip" those images. Each UIImageView has UIPinchGestureRecognizer for pinch zoom, and UIPanGestureRecognizer for to pan that image when zoomed in.
As probably you have noticed, what I'd like to achieve is just like what iBooks does in its application.
However, I have difficult times to get this work.
In my "BookPageViewController", I have set up UIScrollView, then fill them with images from the folder based on data (page numbers, file names, etc) from sqlite.
_pageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
NSUInteger pageCount = [pages count];
for (int i = 0; i < pageCount; i++) {
CGFloat x = i * self.view.frame.size.width;
// Page Settings
UIImageView *pageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, 0, self.view.frame.size.width, self.view.frame.size.height)];
pageView.backgroundColor = [UIColor greenColor];
pageView.image = [pages objectAtIndex:i];
pageView.userInteractionEnabled = YES;
pageView.tag = i;
// Gesture Reocgnisers
UIPinchGestureRecognizer *pinchGr = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinchImage:)];
pinchGr.delegate = self;
[pageView addGestureRecognizer:pinchGr];
UIPanGestureRecognizer *panGr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panImage:)];
[pageView addGestureRecognizer:panGr];
// Finally add this page to the ScrollView
[_pageScrollView addSubview:pageView];
}
_pageScrollView.contentSize = CGSizeMake(self.view.frame.size.width * pageCount, self.view.frame.size.height);
_pageScrollView.pagingEnabled = YES;
_pageScrollView.delegate = self;
[self.view addSubview:_pageScrollView];
And with the help of another good questions here in Stackoverflow, I have put those:
- (void) pinchImage:(UIPinchGestureRecognizer*)pgr {
[self adjustAnchorPointForGestureRecognizer:pgr];
if ([pgr state] == UIGestureRecognizerStateBegan || [pgr state] == UIGestureRecognizerStateChanged) {
if ([pgr scale]) {
NSLog(#"SCALE: %f", [pgr scale]);
[pgr view].transform = CGAffineTransformScale([[pgr view] transform], [pgr scale], [pgr scale]);
[pgr setScale:1];
} else {
NSLog(#"[PAMPHLET PAGE]: The image cannot be scaled.");
}
}
}
My problem is, when I zoom in the one of the UIImageView with Pinch Gesture, the image exceeds (go over) to the next image and hides it. I believe that there should be the way to "limit" the zoom in/out and the size of UIImageView (not UIImage itself), but I don't know where to go from here. I have also put a code to limit the scale something like:
([pgr scale] > 1.0f && [pgr scale] < 1.014719) || ([pgr scale] < 1.0f && [pgr scale] > 0.98f)
but it didn't work...
I know it's not hard for ios professionals, but I'm quite new to objective-c, and this is my first time to develop real application. If this is not a good practice, I also would like to know any ideas to achieve just how to do this like ibooks do (e.g. put UIImageView in UIScrollView, then put the UIScrollView to another UIScrollView)...
Sorry for another beginner question, but I really need help.
Thanks in advance.
Without trying it out myself, my first guess would be that the transform on the UIImageView also transforms its frame. One way to solve that, would be to put the UIImageView in another UIView, and put that UIView in the UIScrollView. Your gesture recognizers and the transform would still be on the UIImageView. Make sure the UIView's clipsToBounds property is set to YES.
How to shadow documentView in NSScrollView?
The effect look likes iBook Author:
You need to inset the content in your document view to allow space for the shadow to be displayed, then layer back the view and set a shadow on it. Example:
view.wantsLayer = YES;
NSShadow *shadow = [NSShadow new];
shadow.shadowColor = [NSColor blackColor]
shadow.shadowBlurRadius = 4.f;
shadow.shadowOffset = NSMakeSize(0.f, -5.f);
view.shadow = shadow;
The NSScrollView contentView is an NSView subclass, which has a shadow field, if you create a shadow object and assign it to this field, the view will automatically show a drop shadow when drawn
NSShadow* shadow = [[NSShadow alloc] init];
shadow.shadowBlurRadius = 2; //set how many pixels the shadow has
shadow.shadowOffset = NSMakeSize(2, -2); //the distance from the view the shadow is dropped
shadow.shadowColor = [NSColor blackColor];
self.scrollView.contentView.shadow = shadow;
This works because all views when are drawn on drawRect use this shadow property by using [shadow set].
doing [shadow set] during a draw operation makes whatever is drawn after that to be replicated underneath
I'm new to entering posts on stack overflow but I had the same issue and have solved it so I thought after searching the net for hours to find a solution it would be nice to answer it.
My solution is to create a subclass for NSClipView with the following code for drawRect...
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
NSRect childRect = [[self documentView] frame];
[NSGraphicsContext saveGraphicsState];
// Create the shadow below and to the right of the shape.
NSShadow* theShadow = [[NSShadow alloc] init];
[theShadow setShadowOffset:NSMakeSize(4.0, -4.0)];
[theShadow setShadowBlurRadius:3.0];
// Use a partially transparent color for shapes that overlap.
[theShadow setShadowColor:[[NSColor grayColor]
colorWithAlphaComponent:0.95f]];
[theShadow set];
[[self backgroundColor] setFill];
NSRectFill(childRect);
// Draw your custom content here. Anything you draw
// automatically has the shadow effect applied to it.
[NSGraphicsContext restoreGraphicsState];
}
You then need to create an instance of the subclass and set it with the setContentView selector.
You also need to repaint the clip view every time the content view size changes. If you have your content view set up to change in terms of canvas size when the user wants then unless you repaint the clip view some nasty shadow marks will left behind.
You don't need to mess about with clips as others have suggested.
Hope it helps!
I am working on an iPhone games like application, where I have to ask one question and corresponding answers on UIButoons. When user presses any button I show right and wrong image based on chosen answer. I create answer view by following code and attach it to main view:
-(void)ShowOutputImageAsAnswerView:(BOOL)correct
{
viewTimer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:#selector(RemoveSubViewFromMainView) userInfo:nil repeats:YES];
UIView *viewOutput = [[UIView alloc]initWithFrame:CGRectMake(200, 100, 80, 80)];
viewOutput.tag = 400;
viewOutput.backgroundColor = [UIColor clearColor];
UIImageView *imgAns = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
if (correct)
{
imgAns.image = [UIImage imageNamed:#"correct_icon.png"];
}
else
{
imgAns.image = [UIImage imageNamed:#"wrong_icon.png"];
}
[viewOutput addSubview:imgAns];
[self.view addSubview:viewOutput];
[self.view bringSubviewToFront:viewOutput];
[imgAns release];
[viewOutput release];
}
I have to show this answer view in the animated form. And this animation will start from its 0 pixel to 80 pixel. Means expanding and shrinking view.
How can it be implemented?
Can it directly be used with imgAns?
You create an animation by doing something like this:
myView.frame=CGRectMake(myView.frame.origin.x,myView.frame.origin.y,0.,0.);
[UIView animateWithDuration:1
animations:^{
//put your animation here
myView.frame=CGRectMake(myView.frame.origin.x,myView.frame.origin.y,80.,80-);
}];
I haven't tried this code, but it should give you a good perspective of how to do it.