If the intent is to scale the view (and not actually change the attributes in the string), I would suggest using scaleUnitSquareToSize: method: along with the ScalingScrollView (available with the TextEdit sample code) for the proper scroll bar behavior.
The core piece from the ScalingScrollView is:
- (void)setScaleFactor:(CGFloat)newScaleFactor adjustPopup:(BOOL)flag
{
CGFloat oldScaleFactor = scaleFactor;
if (scaleFactor != newScaleFactor)
{
NSSize curDocFrameSize, newDocBoundsSize;
NSView *clipView = [[self documentView] superview];
scaleFactor = newScaleFactor;
// Get the frame. The frame must stay the same.
curDocFrameSize = [clipView frame].size;
// The new bounds will be frame divided by scale factor
newDocBoundsSize.width = curDocFrameSize.width / scaleFactor;
newDocBoundsSize.height = curDocFrameSize.height / scaleFactor;
}
scaleFactor = newScaleFactor;
[scale_delegate scaleChanged:oldScaleFactor newScale:newScaleFactor];
}
The scale_delegate
is your delegate that can adjust your NSTextView
object:
- (void) scaleChanged:(CGFloat)oldScale newScale:(CGFloat)newScale
{
NSInteger percent = lroundf(newScale * 100);
CGFloat scaler = newScale / oldScale;
[textView scaleUnitSquareToSize:NSMakeSize(scaler, scaler)];
NSLayoutManager* lm = [textView layoutManager];
NSTextContainer* tc = [textView textContainer];
[lm ensureLayoutForTextContainer:tc];
}
The scaleUnitSquareToSize:
method scales relative to its current state, so you keep track of your scale factor and then convert your absolute scale request (200%) into a relative scale request.