Attributed strings - and bounding rects
Attributed strings - and bounding rects
- Subject: Attributed strings - and bounding rects
- From: Peter Hudson <email@hidden>
- Date: Fri, 03 Mar 2017 21:59:37 +0000
Thanks to both of you for helpful code.
I’m still not out of the wood yet though.
Insofar as I can now determine the size of the rect to hold the attributed string,
I can’t write it to the cell correctly.
This is what i do :-
// aString is a preprepared attributed string
// Determine the height to set the table row to
let sizeLimit = CGSize(width: 60.0, height: CGFloat.greatestFiniteMagnitude)
let size = aString?.boundingRect(with: sizeLimit, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).integral.size
rowHeight = (size?.height)!
// Setup the text field to the correct height...
guard let vw = tableView.make(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil }
vw.textField?.setFrameSize(size!)
// Assign the string
vw.textField?.attributedStringValue = aString
I set the height of the row independently - and that is fine.
But only part of the attributed string appears occupying one line across the middle of the row - truncated and not wrapped over a few lines to fill the rect.
I have tried to play with the text cell in IB to to tell it to wrap its’ content.
But all to no avail.
Any thoughts ?
Peter
> ------------------------------
>
> Message: 2
> Date: Fri, 03 Mar 2017 14:23:40 +0000
> From: Jonathan Mitchell <email@hidden>
> To: "email@hidden" <email@hidden>
> Subject: Re: Attributed strings - and bounding rects
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=utf-8
>
> Hi
>
> I needed to do this for my pdf builder implementation:
>
> Using the NSLayoutManager directly gives the best level of control.
>
> https://github.com/ThesaurusSoftware/PDFPageBuilder/blob/master/PDFPageBuilder/TSPageTextItem.m#L95
>
> NSRect boundingRect = self.containerRect;
>
> // if no rect height defined then use default
> BOOL containerHasExplicitHeight = YES;
> if (boundingRect.size.height == 0) {
> boundingRect.size.height = self.pageHeight - self.containerRect.origin.y ;
> containerHasExplicitHeight = NO;
> }
>
> // allocate text container and layout manager
> NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:boundingRect.size];
> textContainer.lineFragmentPadding = 0; // defaults to non zero
>
> NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
> [layoutManager addTextContainer:textContainer];
> layoutManager.usesFontLeading = YES;
>
> // allocate text storage and assign layout manager
> self.textStorage = [[NSTextStorage alloc] initWithAttributedString:self.attributedString];
> [self.textStorage addLayoutManager:layoutManager];
>
> // do glyph layout
> // NOTE: cannot quite get glyphRangeForBoundingRect configured correctly here
> //self.glyphRange = [layoutManager glyphRangeForBoundingRect:boundingRect inTextContainer:textContainer];
> self.glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
>
> // get rect used for actual glyph layout
> self.usedTextRect = [layoutManager usedRectForTextContainer:textContainer];
>
> Jonathan
>
>> On 3 Mar 2017, at 13:28, Igor Ranieri <email@hidden> wrote:
>>
>> Hi Peter.
>>
>>
>> Have you tried also passing `usesLineFragmentOrigin` as one of the options? It works here.
>>
>> Here’s some code I’m currently using to achieve a similar effect:
>>
>> let sizeLimit = CGSize(width: 80.0, height: CGFloat.greatestFiniteMagnitude)
>> let size = attrString.boundingRect(with: sizeLimit, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).integral.size
>>
>> And it returns the expected size.
>>
>>
>> best,
>> elland
>>
_______________________________________________
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