Re: resizing window containing NSView with CALayer
Re: resizing window containing NSView with CALayer
- Subject: Re: resizing window containing NSView with CALayer
- From: Graham Cox <email@hidden>
- Date: Mon, 08 Aug 2011 23:00:44 +1000
On 08/08/2011, at 10:42 PM, julius wrote:
>> The reason this happens is that once either the width or height goes to 0, there's nothing for the view sizing code to mutliply by to end up with the destination size - once you hit a zero, the sizing information is lost. To prevent this, set a minimum size on the window. This is a good idea in any case - there is no possible use for a zero-sized window.
>>
> Of course.
> Normal behaviour and understandable.
> Bit of a surprise when I came across it but!
There's a fairly easy way to avoid this with layers. If you set a layoutManager on the root layer, then it will be called when the host view is resized, and you can use that to calculate the content layer's size & position from known values. This gives you the ability to lay out layers in a more complex way than is possible with the 'struts and springs' model (which is being superseded in Lion forward anyway).
I'd suggest that you add a layer to the window which is the size of the window at all times, then add any other layers that you want as sublayers of this. That way, you have a layer behind everything that you can rely on to host any other layers you need. If that root layer sets the view as its layoutManager, then you can do this for example:
// in MyView:
- (void) layoutSublayersOfLayer:(CALayer*) layer
{
CGRect insetRect = CGRectInset(layer.bounds, 30, 30 ); // or however this layer relates to the root
myRealContentLayer.frame = insetRect;
}
This supposes the view has a data member 'myRealContentLayer' which is initialised to the layer you created AND ADDED as a sublayer to the master layer. So your view's init method might look like this:
- (id) initWithFrame:(NSRect) frame
{
self = [super initWithFrame:frame];
if( self )
{
CALayer* root = [CALayer layer];
root.frame = NSRectToCGRect( frame );
self.layer = root;
[self setWantsLayer:YES];
root.layoutManager = self;
root.autoresizingMask = kCAWidthSizable | kCAHeightSizable;
myRealContentLayer = [CALayer layer];
myRealContentLayer.backgroundColor = .... // whatever color
[root addSublayer:myRealContentLayer];
}
return self;
}
Doing it this way should make your layer immune from the zero size problem.
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden