I have a auto-resizing NSTableView subclass in NSScrollView in a layer backed view. I'm using the 10.6 SDK and targeting 10.5 as well.
When I resize, the contents "jump" in the table view. I believe it is because there's an implicit animation to move the bounds and/or position. Or maybe something in the clip? I'd also not like it to fade in if I toggle between layer-backed and not.
I've searched on the mailing lists, StackOverflow, and Google in general for this, but I haven't found a solution.
I've tried the following but without any change to the behavior:
1. Custom NSScrollView and NSTableView, each of which implement what I believe should disable animations:
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key {
return (id<CAAction>)[NSNull null];
}
I also tried returning nil as well.
2. Setting the actions (position, bounds, frame, hidden, onOrderIn) on the layers to NSNull.
3. Bracketing live resize methods with a CATransaction to disable animations. The results were not pretty.
I have a small sample project available: <http://nekotech.com/Code/Splitter.zip>
Oddly enough, when the view is small and the scroll bar is present, the "jumping" doesn't occur.
Thoughts and suggestions welcomed!
Dan
-----------------------------------------
Dan Waylonis | nekotech.com
650.887.3711
_______________________________________________
Cocoa-dev mailing list (Coco...@lists.apple.com)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/cocoa-dev-garchive-98506%40googlegroups.com
This email sent to cocoa-dev-ga...@googlegroups.com
Make sure that in your implementation of -resizeWithOldSuperviewSize:
that you call super's implementation. This bit us for a long time, but
apparently that's one of the places where the layer glue fixes up the
layer's geometry to match the AppKit geometry. You need to do this
even if you have custom logic in this method that will completely
nullify what super did. You may need to wrap the call to super in a
CATransaction with +setDisableActions:YES.
rdar://problem/8659667
--Kyle Sluder
> Hi Kyle,
>
> Thanks for the suggestion.
>
> Unfortunately:
>
> - (void)resizeWithOldSuperviewSize:(NSSize)oldSize {
> [CATransaction begin];
> [CATransaction setDisableActions:YES];
> [super resizeWithOldSuperviewSize:oldSize];
> [CATransaction commit];
> }
>
> is still exhibiting the jumpy behavior.
Does it only happen on live resize?
>
> Perhaps I'm not overriding the right action? I'm returning "[NSNull null]" for the "onLayout" key in my actionForLayer:forKey: method as well as setting the layer's actions to have [NSNull null] for: position, bounds, frame, hidden, sublayers, onLayout, anchorPoint, onOrderOut, onOrderIn.
>
> If you happen to have a sample that work for you, I'd really appreciate you sending it my way!
Unfortunately I'm about to board a plane for a week of vacation, so you might have better luck bringing this back on list.
I don't have any code handy, but we do have a public beta of OmniPlan 2 that has a custom view (not NSTableView) that has had all the kinks worked out of it. I might be forgetting another important fix we implemented.
--Kyle Sluder_______________________________________________
I've got a blog post in the editing phase describing all the things we
do to get NSScrollViews working, but the only other thing we do that I
can think of is to swizzle -[NSClipView scrollToPoint:] to look like
the following:
- (void)scrollToPoint:(NSPoint)newOrigin {
originalScrollToPoint(self, _cmd, newOrigin);
[self fixLayerGeometry];
[[self subviews] makeObjectsPerformSelector:@selector(fixLayerGeometry)];
}
-[NSView(LayerBackedFix) fixLayerGeometry] is defined like this:
- (void)fixLayerGeometry {
if (![self layer])
return;
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (NSView *subview in [self subviews]) {
CALayer *layer = [subview layer];
CGPoint layerPosition = NSPointToCGPoint([self
convertPointToBase:[subview frame].origin]); // note: on Lion, we want
to use -convertPointToBacking: instead.
layer.position = layerPosition;
}
[CATransaction commit];
}
Pay attention to that note, since on Lion base coordinate systems
don't mean the same thing as backing coordinate systems.
I'm going to CC this to the list, since it's helpful information.
Hope that helps!
--Kyle Sluder