I have 1 image that i want it to move across the screen. in my case its an image of a little motorcycle that rides form left to right across the screen.
I there any way to take this one image & make it move one step every time for make it like animation image? instead of taking a lot of pictures frame by frame and make animation from it because in my case i have 367 pictures & it makes the project very big.
Thanks.
#property(nonatomic, strong) UIImage *animation;
You can display it in an UIImageView and animate the view itself:
UIImageView *imgView = [[UIImageView alloc] initWithImage:motorcycleImage];
[self.view addSubview:imgView];
[imgView release];
And when you want to animate it:
[UIView beginAnimations:NULL context:NULL];
[UIView setAnimationDuration:1.0];
CGRect rect = imgView.rect;
rect.origin.x += 320 - rect.size.width;
// EDIT: how to put the view on the bottom of the screen
rect.origin.y += 480 - rect.size.height;
imgView.rect = rect;
[UIView commitAnimations];
Hope it helps.
Related
I am working on a OSX/Cocoa graphics application which (for performance reasons) I would like to render at 640x480 when the user selects "full screen" mode. For what it's worth, the content is a custom NSView which draws using openGL.
I understand that rather than actually change the user's resolution, it's preferable to change the backbuffer (as explained on another SO question here: Programmatically change resolution OS X).
Following that advice, I end up with the following two methods (see below) to toggle between fullscreen and windowed. The trouble is that when I go fullscreen, the content does indeed render at 640x480 but is not scaled (IE it appears as if we stayed at the window's resolution and "zoomed" into a 640x480 corner of the render).
I'm probably missing something obvious here - I suppose I could translate the render according to the actual screen resolution to "center" it, but that seems overcomplicated?
- (void)goFullscreen{
// Bounce if we're already fullscreen
if(_isFullscreen){return;}
// Save original size and position
NSRect frame = [self.window.contentView frame];
original_size = frame.size;
original_position = frame.origin;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO],NSFullScreenModeAllScreens,
nil];
// In lieu of changing resolution, we set the backbuffer to 640x480
GLint dim[2] = {640, 480};
CGLSetParameter([[self openGLContext] CGLContextObj], kCGLCPSurfaceBackingSize, dim);
CGLEnable ([[self openGLContext] CGLContextObj], kCGLCESurfaceBackingSize);
// Go fullscreen!
[self enterFullScreenMode:[NSScreen mainScreen] withOptions:options];
_isFullscreen=true;
}
- (void)goWindowed{
// Bounce if we're already windowed
if(!_isFullscreen){return;}
// Reset backbuffer
GLint dim[2] = {original_size.width, original_size.height};
CGLSetParameter([[self openGLContext] CGLContextObj], kCGLCPSurfaceBackingSize, dim);
CGLEnable ([[self openGLContext] CGLContextObj], kCGLCESurfaceBackingSize);
// Go windowed!
[self exitFullScreenModeWithOptions:nil];
[self.window makeFirstResponder:self];
_isFullscreen=false;
}
Update
Here's now to do something similar to datenwolf's suggestion below, but not using openGL (useful for non-gl content).
// Render into a specific size
renderDimensions = NSMakeSize(640, 480);
NSImage *drawIntoImage = [[NSImage alloc] initWithSize:renderDimensions];
[drawIntoImage lockFocus];
[self drawViewOfSize:renderDimensions];
[drawIntoImage unlockFocus];
[self syphonSendImage:drawIntoImage];
// Resize to fit preview area and draw
NSSize newSize = NSMakeSize(self.frame.size.width, self.frame.size.height);
[drawIntoImage setSize: newSize];
[[NSColor blackColor] set];
[self lockFocus];
[NSBezierPath fillRect:self.frame];
[drawIntoImage drawAtPoint:NSZeroPoint fromRect:self.frame operation:NSCompositeCopy fraction:1];
[self unlockFocus];
Use a FBO with a texture of the desired target resolution attached and render to that FBO/texture in said resolution. Then switch to the main framebuffer and draw a full screen quad using the texture rendered to just before. Use whatever magnification filter you like best. If you want to bring out the big guns you could implement a Lancosz / sinc interpolator in the fragment shader to upscaling the intermediary texture.
I've implemented some code, which is working nicely, to scroll a UIScrollview automatically based on a timer being triggered.
Here it is:
....
CGPoint offset;
....
offset = scroller.contentOffset;
....
- (void) scrollWords: (NSTimer *) theTimer
{
offset.y = offset.y+300;
[UIScrollView beginAnimations:#"scrollAnimation" context:nil];
[UIScrollView setAnimationDuration:50.0f];
[scroller setContentOffset:offset];
[UIScrollView commitAnimations];
}
However, I've noticed that the while the scrolling is happening, the scroll rate varies; half way through it scrolls 2 or 3 lines of text per second, but at the start and finish it's much slower, perhaps only 0.5 lines per second. Is there any way of controlling the scroll rate?
Thanks in advance.
Paul.
You're looking for setAnimationCurve:. Specifically what you're describing is the effect of UIViewAnimationCurveEaseInOut. Try adding [UIScrollView setAnimationCurve:UIAnimationCurveLinear];
Also, you're using old style animation code. If you're targeting iOS 4 or above, check out this new style that's much more friendly (in my opinion):
- (void) scrollWords: (NSTimer *) theTimer
{
offset.y = offset.y+300;
[UIScrollView animateWithDuration:50.0f delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[scroller setContentOffset:offset];
}];
}
Using the delay parameter, you can probably even get rid of your NSTimer. With this code you can scroll the table view after 5 seconds.
- (void) scrollWordsLater
{
offset.y = offset.y+300;
[UIScrollView animateWithDuration:50.0f delay:5.0 options:UIViewAnimationOptionCurveLinear animations:^{
[scroller setContentOffset:offset];
}];
}
I have a NSView, subclassed, with custom background drawing, filling it with a gradient.
In IB, I've put a checkbox on it, somewhere in the middle.
This is the drawRect method.
-(void) drawRect:(NSRect)dirtyRect {
CGFloat sc = 0.9f;
CGFloat ec = 0.6f;
NSColor* startingColor = [NSColor colorWithDeviceRed:sc green:sc blue:sc alpha:1];
NSColor* endingColor = [NSColor colorWithDeviceRed:ec green:ec blue:ec alpha:1];
NSGradient *grad = [[NSGradient alloc] initWithStartingColor:startingColor endingColor:endingColor];
[grad drawInRect:dirtyRect angle:270];
}
What happens is, this same method gets called to draw the whole view area first and then for the part, where NSButton (checkbox) lies on top of it. OF course the checkbox background is drawn with a complete gradient and it is not right, since the portion is much smaller. The same happens with other controls I put on the said NSView.
What is the suggested approach on such thing?
One option is to make controls height the same as the views' but this will result in problems in the future.
The answer is, always draw the WHOLE area of the view, not just the dirtyRect
[grad drawInRect:[self bounds] angle:270];
I have a small animation at the begining of my app, two doors open up horizontally, top and bottom to reveal screen. All good so far, the top section moves off fine, however as i have a scroll view the page is longer than standard, 175000 to be exact. Im usure of how to modify the code to send the bottom png off the screen as at the moment its stuck going to where the standard screen would end. Could someone advise? Ive tried so far manually adding the height after self.view.size.height; but that didn't work, im assuming its around there somewhere I should be altering
CGRect doortopFrame = doortop.frame;
doortopFrame.origin.y = -doortopFrame.size.height;
CGRect doorbottomFrame = doorbottom.frame;
doorbottomFrame.origin.y = self.view.bounds.size.height;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationDelay:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
doortop.frame = doortopFrame;
doorbottom.frame = doorbottomFrame;
[UIView commitAnimations];
Fixed this, changing bottom animation to origin.X does the trick
I need to animate a view frame size adding 100px of height, but I need the window grow up simultaneously with the view.
I tried with this code :
//resize Window
NSRect winsize = [window frame];
winsize.size.height += 100;
[self.window setFrame:winsize display:YES animate:YES];
//resize View
NSRect viewsize = [myview frame];
viewsize.size.height += 100;
[[myview animator] setFrame:viewsize];
It works but I obtain an ugly effect, Window and View had some delay in resize. Thus, I get the Window frame resizing before than the View frame.
How can I modify my code to make them resizing simultaneously ?
add:
I found this answer but it tdoesn't seems to work for me:
Simultaneously modify window frame and view frame
I found a good solution: using autoresizingMask to mantain min and max Y Margin and allow height resize.
[myview setAutoresizingMask:NSViewHeightSizable];