CALayer with Animation on Scroll View - uiscrollview

So, I have a CALayer added to a UIScrollView that does some path animations. In my application, I resize the scroll view and shift everything to create a "negative" region. Using contentOffset with UIScroll views, all my subviews are shifted and there is no flashing effect. However, when the lines on the CALayer are shifted, there is a flashing effect because they are drawn in the "negative" area first, then shifted over.
This was happening as an animation at first, but I used CATransaction -begin and -commit to remove the animation. The flashing is still occurring though because the lines are still drawn and then moved.
Is there anyway to solve with?
Thanks in advance.
Edit: I figured out a way to fix this. Before, I was adding each animation to an animation layer, which was then added to the UISCrollView. Instead, I added each animation directly to the UISCrollView and then shift all layers appropriately as before. CATransaction -begin and -commit are still needed to remove any sort of animation of the shift.

I figured out a way to fix this. Before, I was adding each animation to an animation layer, which was then added to the UISCrollView. Instead, I added each animation directly to the UISCrollView and then shift all layers appropriately as before. CATransaction -begin and -commit are still needed to remove any sort of animation of the shift.

Related

Improve CGContextDrawImage performance

I have a custom NSView that has it's own drawRect. I draw a lot of images using CGContextDrawImage into the view. The NsView is in a NSScrollView. The issue I am having is, while scrolling, the drawrect takes too long. the scrolling isn't smooth.
I did try setting wantslayer to true, to enable layer-backed drawing. Now the scrolling is smooth until the next drawrect is called, i.e till next time a new dirtyRect has to be redrawn.
Since I have to use drawrect to draw the contents, is there a way to improve scrolling performance?
if not, is there an alternative?
Update:
the call that's taking time.
I tried what Rob suggested below (using NSImageView for each image). that helped. I see smooth scrolling while setting the images as well.
But I would like to know why CGContextDrawImage takes time? especially rgbaf16_sample_rgbaf_inner. is there a way to avoid it?

subview of IKImageView appears below image instead of above

I have a IKImageView and a NSImageView as a subview. Subviews are supposed to get drawn above their master view. I tried an NSImageView with the same subview, and it worked fine, but I really need to be able to move the image around with the mouse, and zoom it with a slider, and I think IKImageView is a bit easier.
What happens is this:
As you can see, the small picture (subview) is below the image on the IKImageView, but in front of the background of IKImageView.
How can I fix this?
ps: Do you think I should use NSImageView? If so, how would I move it around, and zoom?
call addSubview again everytime after I set the IKImageView's image.
That work for me.

How to animate horizontal bar with right cap, by UIView animation in iPhone

I got wiered but unsurprising animation from call UIView animation, I don't know if it works the same by using CALayer animation. I guess it is.
please see this picture: what I want is to animate a horizontal bar growing horizontally, what I do is:
Subclass a UIView, called UIViewBar, and in its drawRect:rect method, I draw the shape of rectangle and a right cap, it's done by
CGContextMoveToPoint A
CGcontextAddLineToPoint B
CGContextAddArcToPoint D
CGContextAddLineToPoint C
//then close the path and fill the context
Then I call this UIViewBar (initWithFrame:rect) in my UIViewController, and the shape is what I want, looks fine. BUT when I perform [UIView animation] say from original rect to rectGrew it does not perform nicely. Instead, it perform as the picture says.
Well, after thinking, it's not totally unreasonable because when the UIView horizontally stretches itself, it does not know the cap will not be changed. So is there another way to do this?
Actually, I'm very new to drawing, graphic, and animation. What I know is that (if wrong please kindly correct me):
If I want to "draw something", I should override the UIView's drawRect method, and this is done by initing the UIView, should not or better not to be called outside. Say I drew a rectangle in a UIView by CGContextFillRect.....
But what if I want to animate this rectangle? I cannot make animation based on Quartz2D, but from UIView animation or CALayer(deeper tech), so What I have to do is to make the rectangle itself as a seperate UIViewRect seperately, so I can call the [UIViewRect animation] method, AM I RIGHT ON THIS
If so, I have to make every rectangle that I want to animate to be UIView respectively. Doesn't it affect performance? Or it is just the way apple prefers to do ?
Any suggestion will be much helpful, GREAT thanks.
Wow, it's the first time that no answer posted at all! TO answer my question: it requires to consider animate custom property of CALayer. The custom property is the AB width (the width without cap width, that should work). If someone wants detailed code. Please google custom property animate in CALayer.

Drastic slowdown using layer backed NSOpenGLView

I needed to display some Cocoa widgets on top of an NSOpenGLView in an existing app. I followed the example in Apple's LayerBackedOpenGLView example code. The NSOpenGLView is given a backing layer using:
[glView setWantsLayer:YES]
Then the Cocoa NSView with the widgets is added as a subview of the glView. This is basically working and is twice ad fast as my previous approach where I added the NSView containing the widgets to a child window of the window containing the glView (this was the other solution I found on the web).
There were two problems.
The first is that some textures that I use with blending were no longer getting the blend right. After searching around a bit it looked like I might need to clear the alpha channel of the OpenGLView. This bit of code that I call after drawing a frame seems to have fixed this problem:
Code:
glColorMask(FALSE, FALSE, FALSE, TRUE); //This ensures that only alpha will be effected
glClearColor(0, 0, 0, 1); //alphaValue - Value to which you need to clear
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(TRUE, TRUE, TRUE, TRUE); //Put color mask back to what it was.
Can someone explain why this is needed when using the CALayer, but not without?
The second problem I don't have a solution for. It seems that when I pan to the part of the scene where problem is #1 was observed, the frame rate drops from something like 110 FPS down to 10 FPS. Again, this only started happening after I added the backing layer. This doesn't always happen. Sometimes the FPS stays high when panning over this part of the scene but that is rare. I assume it must have something with how the textures here are blended, but I have no idea what.
Any thoughts?
I did figure out a workaround to the slowdown. The OpenGL view has a HUD (heads up display) view that goes on top of it. I had installed another NSView as a subview if it. Both the HUD and the subview have lots of alpha manipulation and for some reason that tickled a real slowdown in compositing the layers. I could easily instal this subview as a subview of the OpenGL view and when I did this everything sped up again. So although I don't fully understand the slowdown, I do have a good work around for it.

NSWindow Content Border messing with CALayer's geometry

I have an NSWindow with a 32px bottom content border. Inside the window's view, I have two custom subviews. Each of them are layer backed, and I'm tracking the mouse with an NSTrackingArea. Part of what I'm doing is some mouseOver effects with CoreAnimation. This is not a problem in general, but I noticed something kind of strange and wondered if anyone knows why this is happening.
When setting up the trackingArea and mouseOver method, I hitTest the root layer and log the layer's name so I can see if the geometry of the various sublayers hold water when I resize the window. Internally, they seem (and look) fine. Visually, they are in the right place, but when I move the mouse, I notice that the though the mouse is physically over a layer, hitTest is returning whatever layer is 32 px above it. However, if I remove the content border, it works as you would expect and the correct layer is returned.
I obviously need the content border, so I have a very simple workaround which involves offsetting the hitTest point by 32px. This works fine, but it just seems weird that the presence of a content border seems to skewing the co-ordinate system of these subviews. Does anyone know why this could be happening?
NSEvent returns mouse locations relative to the window's coordinate system, not the targeted view's. You probably need to call convertRect:fromView: to get the correct coordinates.

Resources