I've got a problem handling the animators of NSViews.
In the code below I create a (custom) controller which also has got a view. I want it to fade it into the window, and fade the old one out. But it doesn't animate at all, the new view just appears, and the old one gets "removeFromSuperview" instantly.
Also, I have seen that the old view behaves normally, it fades out. But the new one is in the way and doesn't fade at all.
My code:
LTController *newController=[[LTController alloc] init]];
[[newController view] aFrame];
[[newController view] setAlphaValue:0];
[[[self window] contentView] addSubview:[newController view]];
[[[newController view] animator] setAlphaValue:1];
[[[viewController view] animator] setAlphaValue:0];
[viewController view] performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:[[NSAnimationContext currentContext] duration]];
[self setViewController:newController];
How can it be that the animator doesn't do anything to animate? What am I doing wrong?
Thanks in before,
Ivorius
You need to set your views as Layer backed for this to animate
Related
I have an NSTextField in a container:
[textField setFrameOrigin:NSMakePoint(0, -t.frame.size.height)];
content = [[NSView alloc] init];
[content setWantLayer:YES]
content.layer=[CALayer layer];
[content addSubview:textField];
[content scaleUnitSquareToSize:NSMakeSize(1, -1)];
content.frame=textField.frame;
content.layer.backgroundColor=textBGColor.CGColor;
The container itself is located in a view with
[view scaleUnitSquareToSize:NSMakeSize(1, -1)];
This is all for obtaining a top left origin for the TextField and it works great, the only problem consist in the InsertionPoint not drawing (at least not in the visible frame).
I presume the InsertionPoint is either not Scaled or translated with the TextField. Other possibility is that InsertionPoint can't be drawn in a layer backed View.
Is there a way to display the InsertionPoint cursor ?
EDIT
After trying all the possibilities out, it seems the InsertionPoint (and the focusRing) are not drawing because of its frame being positioned out of the superviews bounds and its dirtyDrawRect. Is there a way to remove the clipping of an NSView ? I need to be able to place my TextField on every absolute position possible.
I found a way through: implementing the drawing myself.
1) giving a custom TextView as Editor for the window.
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject
{
if (!myCustomFieldEditor) {
myCustomFieldEditor = [[TextView alloc] init];
[myCustomFieldEditor setFieldEditor:YES];
}
return myCustomFieldEditor;
}
2) Overiding the drawInsertionPoint method in the custom TextView class.
-(void)drawInsertionPointInRect:(NSRect)rect color:(NSColor *)color turnedOn:(BOOL)flag{
[color set];
NSRectFill(rect);
[super drawInsertionPointInRect:rect color:color turnedOn:flag];
}
For insertion point just make your textfield to first responder.
[myTextField becomeFirstResponder];
My NSProgressIndicator is animating in a view
when I switch to another view ,and switch back
my NSProgressIndicator disappear.
why?
Here is my code for switch to another view
- (void)switchToView:(NSView *)newView withAnimate:(BOOL)animate
{
if ([[rootView subviews] count] != 0)
{
[rootView setWantsLayer:YES];
[rootView displayIfNeeded];
NSTimeInterval duration = [[self window] animationResizeTime:newFrame];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.25];
[[rootView animator] replaceSubview:[[rootView subviews] objectAtIndex:0] with:newView];
[NSAnimationContext beginGrouping];
if (duration > 0.25) {
[[NSAnimationContext currentContext] setDuration:0.25];
}
else{
[[NSAnimationContext currentContext] setDuration:duration];
}
[[[self window] animator] setFrame:newFrame display:YES animate:YES];
[NSAnimationContext endGrouping];
[NSAnimationContext endGrouping];
[self performSelector:#selector(endAnimation) withObject:nil afterDelay:0.25f];
}
}
-(void)endAnimation{
[[ _mainWindow contentView] setWantsLayer:NO];
}
I just replace a view,and make a fade out animation NSProgressIndicator animating all the time in a view.
I have solve this by myself ,I think it will be helpful for your guys.
I stop my NSProgressIndicator before I want to replace my view with NSProgressIndicator.
then I replace the view with a new view ,if I switch back I will start NSProgressIndicator with a - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay; method ,just set the delay=0 is OK.
In xib files , you should set NSProgressIndicator DisplayWhenStopped is YES.
And it will work well.
Then reason is after 10.6.5,At least on OS X 10.6.5 and above, as soon as you set an indetermined-progress-indicator's wantsLayer property to YES, the animation stops immediately .
So before it stop immediately ,I stop it by myself.And start it when I want to use it.
NOTICE: You should stop it by yourself better than system does, it can`t work well if system stop it .
I have a NSView in my project that I want to move but the animation I usually use for other objects doesn't work with it... what should I do to make it move?
Here is my code:
[[NSAnimationContext currentContext] setDuration:1.0];
NSRect rect = NSMakeRect(59.0,10.0,682.0,575.0);
[[self.myView animator] setFrame: rect];
I found the way to make it work...
For some reason the animation was working if called alone but not working when called after an IAP...
I found out that calling the void with the animation with this line of code made it work:
[self performSelectorOnMainThread:#selector(myAnimation) withObject:nil waitUntilDone:NO];
I have an app where a movie view is a kind of loading screen, and it's on top of my root controller, splitViewController. When the movie has finished, i want to remove it from the superview, animated. I'm using this code now, where mpmctr my movie controller is:
[UIView beginAnimations:#"blablablab" context:NULL];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:splitViewController.view.superview cache:NO];
[UIView setAnimationDuration:.5];
[mpMCtr.view removeFromSuperview];
[UIView commitAnimations];
When this code runs, mpmctr removes itself from the superview but not animated. This is happening when the splitviewcontroller is already on the screen.
Im using this code for putting mpmctr on the view in the delegate method didfinishlaunching.
[window addSubview:splitViewController.view];
[splitViewController.view addSubview:mpMCtr.view];
I hope that you guys can help me with this problem,
Thanks in advance.
A UIView animation can't animate removal from superview, but you could for example animate its alpha down to zero, then you could do this to remove the view after your animation has completed.
[UIView setAnimationDidStopSelector:#selector(removeMyView)];
- (void) removeMyView
{
[mpMCtr.view removeFromSuperview];
}
Despite what MDT says, you can actually animate the removal of a view with UIView animation. You just have to use the block-based API that was introduced in iOS 4.
This is the exact sample code from the Apples documentation for transitionWithView:duration:options:animations:completion:
[UIView transitionWithView:containerView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[fromView removeFromSuperview];
[containerView addSubview:toView]; }
completion:NULL];
It will flip from left, removing fromView and adding toView to containerView (the view that they are added removed from).
I have an MAAttachedWindow (subclass of NSWindow), which contains a blank view (contentView), and some arbitrary subview (right now an NSImageView).
On load, I'm attempting to resize the window by 100px vertically, in an animated fashion.
This code block initializes my window and views:
_popoverContentView = [[NSView alloc] initWithFrame: aFrame];
NSImageView *img = [[NSImageView alloc] initWithFrame: aFrame];
[img setImage: [NSImage imageName: "#my_debug_image"]];
[img setAutoresizingMask: NSViewHeighSizable];
[_popoverContentView setAutoresizesSubviews: YES];
[_popoverContentView addSubview: img];
popover = [[MAAttachedWindow alloc] initWithView: _popoverContentView attachedToPoint: aPoint inWindow: nil onSide: MAPositionBottom atDistance: aDist];
And this code block is responsible for the animation:
NSRect newPopoverFrame = popover.frame;
NSRect newPopoverContentViewFrame = _popoverContentView.frame;
newPopoverFrame.size.height += 100;
newPopoverContentViewFrame.size.height += 100;
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrame: newPopoverFrame display: YES animate: YES];
Now this all works (almost) as expect, however as shown in this video, the animation is unreliable, shaky, and jumpy. I can't seem to pinpoint what in my code is causing this, or how to go about locking the image view into place.
I think the problem is that you're using the new(ish) animator proxy to animate the window's frame while also using the much older animate: parameter of NSWindow's setFrame:display:animate:, which uses the old NSViewAnimation API.
These two animation methods are probably conflicting as they try to animate the window simultaneously using different code paths.
You also need to wrap multiple calls to the animator proxy in [NSAnimationContext beginGrouping] and [NSAnimationContext endGrouping] if you wish the animations to be simultaneous.
Try doing this:
[NSAnimationContext beginGrouping];
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrame: newPopoverFrame display: YES animate:NO];
[NSAnimationContext endGrouping];
If that doesn't work, you could drop the use of the problematic setFrame:display:animate: method and just animate the position and size independently:
[NSAnimationContext beginGrouping];
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrameOrigin: newPopoverFrame.origin];
[[popover animator] setFrameSize: newPopoverFrame.size];
[NSAnimationContext endGrouping];
The animation context grouping will ensure that everything happens simultaneously.