简体   繁体   中英

How to rotate a NSTextView

I want to have rotatable text edit area like in Adobe Illustrator. I tried several things including subclassing NSTextView and adding coordinate system rotation before the drawing code like this:

@implementation MyNSTextView

-(void)drawRect:(NSRect)dirtyRect
{
    NSAffineTransform * trafo = [NSAffineTransform transform];
    [trafo rotateByDegrees:45];
    [trafo concat];
    [super drawRect:dirtyRect];
}

-(void)drawInsertionPointInRect:(NSRect)rect color:(NSColor *)color turnedOn:(BOOL)flag
{
    NSAffineTransform * trafo = [NSAffineTransform transform];
    [trafo rotateByDegrees:45];
    [trafo concat];
    [super drawInsertionPointInRect:rect color:color turnedOn:flag];
}

Which results in corrupted display of the text. I also tried to implement the functionality myself by subclassing NSView and assembling the text architecture programmatically. I draw the string with the drawGlyphsForRange: method of my NSLayoutManager. This partly works but gets complicated because I have to rotate the coordinates for the drawing and for handling the mouse clicks I have to convert the mouse location back to old coordinates.

So is this the best way to do it or is there something else?

Edit: I now tried to use CALayer like this:

@implementation MyNSTextView
-(id)initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];

    if (self) {
     CALayer *myLayer = [CALayer layer];
     myLayer.transform = CATransform3DMakeRotation(1.6,1,0,1.0);
     [self setLayer:myLayer];
     [self setWantsLayer:YES];
    }
    return self;
 }

But this yields a TextView which doesn't show any text (only a cursor) and is not rotated. Is there something else to add to make it work??

You are making it too complicated. Simply set the rotation on the view itself:

[myView setFrameRotation:angleInDegrees];

There is also setFrameCenterRotation , but that is supposed to work only for layer-backed views (which is OK).

There is one caveat which I am still investigating myself: The blinking text cursor becomes really fat when the view is rotated.

Why not make the views layer-backed? You can then just apply an affine transform to the view's layer.

yourView.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1.0);

The problem is that you're creating an NSAffineTransform , but you're not attaching it to your text view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM