Scaling with Core Animation - cocoa

I have a NSScrollView that I want to scale down 50%. I do this with the below code:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
animation.fromValue = [NSNumber numberWithFloat:1.00];
animation.toValue = [NSNumber numberWithFloat:0.50];
[animation setDuration:0.20f];
[animation setFillMode:kCAFillModeForwards];
[animation setRemovedOnCompletion:NO];
[self.scrollView.layer addAnimation:animation forKey:#"drag"];
This works, but the scroll view's document view receives mousedown events when I click outside of the scaled down view. So although the scroll view and its content visually looks scaled down, they technically aren't.
How would I go about doing this?
Thanks!

Layer animation acts exactly as you describe (The animations only change the appearance, not the underlying geometry.)
Try using UIView block animation and change the scroll view's transform rather than the layer's.
EDIT:
Oh. Sorry, I thought this was iOS. I guess I should have noticed that you said it was an NSView, not a UIView. I do most of my work in iOS these days, and my OSX experience is mostly from before the days of Core Animation.
I think the answer is to get the view's animation proxy and set the change on that, but I've only done a few learning exercises with animation proxies in Mac OS, so I'd have to do some digging to look up the specifics.

Related

NSImage is always being scaled and looks bad

I want to create an NSImage of an NSScrollView object, so I can use the flat graphic for animation purposes.
When I render my scrollview object into a graphic and add it back to my window, it works but looks really bad like it's been scaled to 99% or something. I want the image to not be scaled and 100% pixel accurate. (Note: the image isn't scaled, it's the same size, it just looks like it's been poorly rescaled - the text looks rough and poor compared to the view onscreen in the scrollview)
My code:
(scrollView is my NSScrollView object)
NSData *pdf = [scrollView dataWithPDFInsideRect:[scrollView bounds]];
NSImage *image = [[NSImage alloc] initWithData:pdf];
NSImageView *imageView = [[NSImageView alloc] initWithFrame:[scrollView bounds]];
[imageView setImage: image];
[mainGUIPanel addSubview: imageView];
I've tried a heap of things, messed with pixel sizes, bounds, used IB to create the destination NSView and put the image inside that but just cannot get the image to not look bad. Any ideas?
Edit:
I tried writing the pdf data to a pdf file and viewed it, and it looked ok. So the bitmap image is being captured ok, it's just on the display that it looks like it's being scaled somewhat.
Edit2:
Also tried getting the bitmap like this:
NSBitmapImageRep *bitmap = [scrollView bitmapImageRepForCachingDisplayInRect:[scrollView bounds]];
[scrollView cacheDisplayInRect:[scrollView bounds] toBitmapImageRep:bitmap];
NSImage * image = [[NSImage alloc] initWithSize:[bitmap size]];
[image addRepresentation: bitmap];
Same results - the bitmap looks exactly the same, bad and scaled when displayed.
This leads me to believe that capturing the bitmap data either way works fine, it's creating the view and rendering the image that is doing the scaling. How can I make sure that the view and image are shown at the correct size and scaling?
Edit3:
Ok, I started a new blank project and set this up, and it works perfectly - the new imageview is identical to the grabbed bitmap. So I suspect my issue is stemming from some rendering/compositing issue when drawing the bitmap to the view. Investigating further...
It turns out the issue stems from the scrollView that I am rendering from. This has a transparent background (Draw Background is off in IB) and the text is the scrollView looks good. If I turn "Draw Background ON", with a transparent background color, the text is rendered badly, exactly as it is when I capture the image programatically.
So, in my app, even though Draw Background is off, the scrollView image is captured as though Draw Background is on. So I need to understand why the text is rendered badly when Draw Background is on and set to transparent, and hopefully this will lead me towards a solution.
Also tried creating an NSClipview with background drawing turned off and putting the bitmap view into that, but it sill renders the same. I can't find a way to render the transparent image to the screen without horrible artifacting.
Ok, I've found a solution. Instead of getting a grab of the transparent background scrollview object itself, I'm instead getting a grab of the parent view (essentially the window background), and restricting the bounds to the size of the scrollview object.
This captures both the background, and the contents of the scrollview, and displays correctly without any issues of transparency.

NSView with layer is drawn over all content

I have an NSView, which I change some properties to give make it a rounded rectangle, with a gray color, and add it to my view (behind everything)
float gray = 60.0f/255.0f;
NSView* background = [[NSView alloc] initWithFrame: self.iconContainer.frame];
CALayer *viewLayer = [CALayer layer];
[viewLayer setBackgroundColor:CGColorCreateGenericRGB(gray, gray,gray, 1)]; //RGB plus Alpha Channel
[viewLayer setCornerRadius:5.0f];
[background setWantsLayer:YES]; // view's backing store is using a Core Animation Layer
[background setLayer:viewLayer];
// Place view behind all other views
[self.iconContainer addSubview:background positioned:NSWindowBelow relativeTo:nil];
However no matter what I try, that particular view is drawn above everything else.
Usually, this behaviour is caused by the use of Core Animation layers on a subview, while the superview hasn't any.
Enabling Core Animation layers on the superview should fix the issue, as any subviews will then be drawn using Cora Animation layers, making the drawing process respect the order of subviews.

UIScrollview setContentOffset and animation

I want to setContentOffset with different animation transition.
Now I use:
[UIScrollView animateWithDuration:speed animations:^ {
[scrollView setContentOffset:offset];
}];
Can you help me, How I achieve animation during set offset.
I am not quite sure, I understand what you are looking for. However, in the case you are looking for a UIScrollView class whose contentOffset is animated with a non-linear timing function you might take a like at my MOScrollView. I use a CADisplayLink to animate the contentOffset. Though, please note that it might not work perfectly as I did not yet use this class in production.

Rendering NSView to image: cacheDisplayInRect draws transparent areas differently from usual drawRect call

Greetings! I have a problem and Googling brought no results...
I implemented the drawRect method for my NSView (subclass) to draw some shadows and semi-transparent fills. Everything looks great! But now I need to create an NSImage from my NSView (make snapshot) for drag&drop purposes.
It works, but draws in some different manner: darker and not so contrast as should be.
Why? Maybe because of NSGraphicContext different options? Need help and/or advice!
Here is the code for getting NSImage from NSView:
- (NSImage *)makeImageSnapshot {
NSSize imgSize = self.bounds.size;
NSBitmapImageRep * bir = [self bitmapImageRepForCachingDisplayInRect:[self bounds]];
[bir setSize:imgSize];
[self cacheDisplayInRect:[self bounds] toBitmapImageRep:bir];
NSImage* image = [[[NSImage alloc] initWithSize:imgSize] autorelease];
[image addRepresentation:bir];
return image;
}
And here are the images to compare visually:
Normal - drawn by drawRect usual call: http://cl.ly/image/213C1Y1V0v2H
Bad - captured into NSImage: http://cl.ly/image/183q442S2J14
Thought the difference might seem very small, believe me - it is obvious while working with application. I don't undertand why that is happening. And hope someone can help...
Thanks in advance!
I believe the transparency problem is caused by not having other things to blend it against when it's cached on its own.
Try -dataWithPDFInsideRect: or -dataWithEPSInsideRect: and get your image reps from there.

UIView backed by CATiledLayer in UIScrollView doesn't scroll initially

I'm adding a CATiledLayer backed UIView in UIScrollView.
When the view is first loaded, I'm trying to fit the UIView, by setting the zoomScale of UIScrollView - this fits the UIView and the layered contents.
I'm having a method to fetch the tiles of image and I'm rendering them in drawLayer:inContext:
Now even if the contentsize of scrollview/frame of CATiledLayer view is greater than UIScrollView, it doesn't scroll initially.
The moment I try to zoom by pinching the screen, I'm able to scroll perfectly.
I can't scale the CGContext in drawLayer:inContext, since the context I receive is of a tile and not whole image and I have 20 tiles which make up my image.
At the end of the initWithFrame of the PDFScrollView i added the line:-
self.zoomScale = 1.0;
This worked for me.
The code is pretty much doing the same stuff as apple example
http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40010281-Intro-DontLinkElementID_2
which also doesnt scroll on loading

Resources