Meet TextKit 2

RSS for tag

Discuss the WWDC21 session Meet TextKit 2.

View Session

Posts under wwdc21-10061 tag

23 Posts
Sort by:
Post not yet marked as solved
0 Replies
145 Views
The demo app has a problem: if you vertically shrink the window using the bottom edge and move it to position y0, then drag the bottom edge again to another position y1, parts of the document after y0 will not be rendered due to the fact the viewport bounds are not recalculated when frame height changes. My fix to this problem is to remove the check that inspects whether the text container width changed and always set the value of the text container size used by the text layout manager whenever frame size changes: this does fix the problem mentioned above. However, I would like to know exactly when will the text layout manager recalculate the viewport bounds. This is not documented anywhere, nor in the video.
Posted
by
Post not yet marked as solved
0 Replies
192 Views
During the presentation (19:43) it says the NSTextLayoutFragment 'Layout information for one or more elements'. But from the documentation it seems that you can only generate a layout fragment from one NSTextElement. Besides there is only one property that associates a text element. What does it mean by 'parent element' anyway?
Posted
by
Post not yet marked as solved
0 Replies
322 Views
Hi there, I have a small question regards to the TextKit 2 demo app: In macOS / TextDocumentView.swift / viewportBounds(for:) / Line 106 , why compare overdrawRect.minY with max(visibleRect.minY, 0)? Isn’t overdrawRect.minY always the smaller one (as it’s an overdraw rect)? Another question would be, if I'm planning to start working on an application with complex text editing features, would you recommend using NSTextView for now and wait for further updates, or just use the TextKit 2 stack (with CALayers) like the one used in the demo? I really love TextKit 2 and so far the demo seems pretty performant. But I don't know if there is any drawbacks if I build a TextKit 2 stack on my own so I'm looking forward to your advice. Many thanks
Posted
by
Post marked as solved
1 Replies
381 Views
Hello :), I want to have a UIView inside of a UITextView. For that I use the new NSTextAttachmentViewProvider class introduced in iOS 15. The views width should always be equal to the width of the UITextView this width should update when, for example, the screen rotates. To do that I am using the tracksTextAttachmentViewBounds property inside of a NSTextAttachmentViewProvider subclass. If I understand correctly, if this property is set to true, the function attachmentBounds(for:location:textContainer:proposedLineFragment:position:) of my NSTextAttachmentViewProvider subclass should be used to determine the views bounds. In the code example below I have set it up in that manner, sadly the function is never called. (The storyboard consists of a UIViewController with a UITextView which four constrains (trailing, leading, bottom, top) are set equal to the safe area, nothing special going on). I have also tried to use a NSTextAttachment subclass in which I override the attachmentBounds(for:location:textContainer:proposedLineFragment:position:) function. It is also not called. The view is appearing, but not with the width and height that I have set in the function (see screenshot below), maybe it is using some default values. When I start typing, the view disappears. I don't know what I am doing wrong. Could somebody help me with that problem? import UIKit class SomeNSTextAttachmentViewProvider : NSTextAttachmentViewProvider { override func loadView() { super.loadView() tracksTextAttachmentViewBounds = true view = UIView() view!.backgroundColor = .purple } override func attachmentBounds( for attributes: [NSAttributedString.Key : Any], location: NSTextLocation, textContainer: NSTextContainer?, proposedLineFragment: CGRect, position: CGPoint ) -> CGRect { return CGRect(x: 0, y: 0, width: proposedLineFragment.width, height: 200) } } class ViewController: UIViewController { @IBOutlet var textView: UITextView? override func viewDidLoad() { super.viewDidLoad() NSTextAttachment.registerViewProviderClass(SomeNSTextAttachmentViewProvider.self, forFileType: "public.data") let mutableAttributedString = NSMutableAttributedString() mutableAttributedString.append(NSAttributedString("purple box: ")) mutableAttributedString.append( NSAttributedString( attachment: NSTextAttachment(data: nil, ofType: "public.data") ) ) textView?.attributedText = mutableAttributedString textView?.font = UIFont.preferredFont(forTextStyle: .body) } }
Posted
by
Post not yet marked as solved
0 Replies
296 Views
The documentation for TextKit 2 is a bit thin. I have a few questions about that: Is more complete documentation available to Developer Program members? When can developers expect for the API documentation to be updated? When will overview documentation, like TextKit 1 has, be available?
Posted
by
Post not yet marked as solved
0 Replies
274 Views
I want to add characters to the display of my paragraphs without modifying the underlying text storage. To be concrete, let's say that I want to prefix each paragraph with "Whereas, ". Further, when I drag out a text selection on a paragraph that's displayed this way, I do not want "Whereas, " to receive a selection highlight. Using TextKit 2, it's pretty easy to accomplish the first part using a NSTextContentStorageDelegate whose method textContentStorage(_: NSTextContentStorage, textParagraphWith: NSRange) -> NSTextParagraph? adds my prefix to each paragraph. I modified the WWDC21 demo program to do it. I appreciate how I can avoid glyph munging by using TextKit 2 instead of TextKit 1, it will save a lot of trouble. If I drag a selection across the prefix, then it receives the selection highlight. What's more, when I drag a selection across the end of the paragraph, the last eight characters (and, I presume, the invisible newline) do not receive the selection highlight. So adding the prefix has skewed the selection indices. It seems to me that the TextKit 2 designers may intend for me to use a NSTextLocation subclass consisting of a "storage" index and a "display" sub-index. On the storage indices there are the characters of the text storage, and at (storage index, display sub-index)-pairs are the characters of my prefix. While the user drags out a selection, I should subtract from the NSTextSelection any NSTextRanges belonging to non-storage text such as my prefix. Am I on the right track, so far?
Posted
by
Post not yet marked as solved
1 Replies
426 Views
The way NSTextView is built it's inevitable to use NSTextStorage with TextKit2, however the NSAttributedString uses NSRange vs the TextKit2 family uses NSTextRange for text location, etc. What I struggle with is the relation between these two. I didn't find a convenient translation between these two. Is NSAttributedStrint NSRange length=1 equal to NSTextRange offset 1? I think it's not (at least it's not necessarily true for every NSTextContentManager. So my question is, given a NSTextRange, what is the corresponding NSRange in NSTextContentStorage.attributedString
Posted
by
Post not yet marked as solved
2 Replies
429 Views
Hi! First apologies if I may have missed this in the forums somewhere, but I have been unable to find any documentation on multi-page layouts with the newer text kit and have not been able to create this using/modifying the sample code provided from the WWDC conference earlier this year. What I am trying to do is create a multipage document where the text is editable and the layout is fairly static. When the text expands in the current view to where there is no room left, a new 'page' will be created and the text will spill over there. Basically standard word or google docs type editor. The position for the pages will need be manipulated depending on some properties. I also intend in wrapping the solution in SwiftUI since the rest of the app this will be used in is a SwiftUI app. If this isn't possible, I may just stick with TextKit1 or punt altogether. Thanks! Sean
Posted
by
Post not yet marked as solved
1 Replies
362 Views
I need to render some view at cursor position, how can I get the current coordinate of cursor? var location = NSRange(location: textView.selectedRange().location, length: 0) // the following is not available textLayoutManager.boundingRect(forGlyphRange: location, in: textContainer) can we use Textkit2 in production? I think there are lots of methods missing in NSTextLayoutManager while available in NSLayoutManager.
Posted
by
Post not yet marked as solved
0 Replies
698 Views
I'm trying to implement custom NSTextContentManager and use it with NSTextView, however it seems that NSTextView expect NSTextContentStorage all the time. final class MyTextContentManager: NSTextContentManager { // ... } It's added to layout manager, and NSTextView instance finds it properly: let textContentManager = MyTextContentManager() textContentManager.addTextLayoutManager(textLayoutManager) however, when I use it, I see errors at: [MyTextContentManager textStorage]: unrecognized selector sent to instance 0x600003d84870 the textStorage property is part of NSTextStorageObserving, that is not NSTextContentManager interface. It looks like NSTextView is not ready to work with custom NSTextContentManager. What did I miss?
Posted
by
Post not yet marked as solved
0 Replies
479 Views
Is it possible to use/draw a SwiftUI view in TextKit 2? The NSTextLayoutManagerDelegate seems to be built around returning a NSTextLayoutFragment. Since NSTextLayoutFragment is a class, I can't subclass it and use SwiftUI. I'd love to create my views using SwiftUI, since it's a lot faster than figuring out CGPaths, pixel perfect anti-aliasing, etc. Thanks!
Posted
by
Post marked as solved
1 Replies
536 Views
We use NSLayoutManager/NSTextStorage/NSTextContainer to display markdown attributed string on a canvas. MarkDown string was processed properly, but NSLayoutManager just exhibits the plain text. The code is as follows:     var layoutmanager = NSLayoutManager()     var textstorage = NSTextStorage()     var textcontainer = NSTextContainer()   var attrStr = try AttributedString.init(markdown: "**test**", options: AttributedString.MarkdownParsingOptions(interpretedSyntax: .inlineOnlyPreservingWhitespace)) var attrString = NSMutableAttributedString(attrStr)  self.textstorage.setAttributedString(attrString!) // draw text layout     let range = self.layoutmanager.glyphRange(for: self.textcontainer)     self.layoutmanager.drawBackground(forGlyphRange: range, at: self.textLocation)     self.layoutmanager.drawGlyphs(forGlyphRange: range, at: self.textLocation) Is it because TextKit 1 does not support markdown string display or I miss something else ? Any help will be appreciated. Thanks!
Posted
by
Post not yet marked as solved
1 Replies
565 Views
Hi there, I am currently trying to extend the TextKit 2 demo project from WWDC 2021 to allow keyboard input under iOS using UITextInteraction. For the most part, it is working well, but the behaviour of the directional cursor text navigation is strange: When moving up or down, it keeps the horizontal location within the current paragraph. But when crossing an empty line into another paragraph, the former horizontal position is lost and the cursor is reset to the line start. This is a video showing the behaviour: https://www.icloud.com/iclouddrive/0Xwf9hpb2DcAoU1CNPZnVgwQw#TextKit2_Selection_Bug I would expect the cursor to restore its former horizontal position in following paragraphs. This is the standard behaviour in UITextView and NSTextView. Does anybody know if this a bug in TextKit2 or if there is a way to achieve the expected beahviours. Thanks Frank
Posted
by
Post marked as solved
1 Replies
888 Views
Although Text will render two lines if you pass it a 2 line String, it will render the text of both lines concatenated if you pass it as a markdown string. Same if you create an AttributeText before. Examining the AT highlights the markdown structure (NSPresentationIntent, NSInlinePresentationIntent, NSLink, Header, Paragraph, CodeBlock, etc) but this is "flattened" if you will (NSLink works, multiline CodeBlock work). The problem isn't only present in Text. My use case was CoreText 2: I expected that each AttributeText run would be turned into a text layout fragment but NSTextLayoutManager also flattens my example. As an example, a screenshot of a markdown file in Xcode and the rendering in the simulator. 2 "paragraphs" aka 2 text layout fragments. The same test with the EGG recipes rtf file of the CoreText2 WWDC21 session gives predictable results, one text layout fragment per paragraph. I'm wondering if this is a bug or a "feature" of this markdown first iteration? I tried to access the NSPresentationIntent without much luck to populate CoreText2 myself. Any hint would be REALLY welcomed. thank.
Posted
by
Post not yet marked as solved
0 Replies
419 Views
Good day, simple question. In TextKit2, there seems to be a Rendering Surface Bounds property. We currently have a text.boundingRect(with...) function call to determine some bounding properties, and this is the accepted proposal for most bounding retrieval, but I am not sure the operation is actually the Rendering Surface Bounds of a provided text, as described in the video. So ... let say I have such a text, and I want to get that fully enclosing bounds, what would be my best bet (cross-platform)
Post not yet marked as solved
0 Replies
317 Views
The iOS demo app set comment with attachment. However, call the textAttachmentViewProviders on the fragment return nothing even the image attachment draw on the screen. The inline doc is:     // Returns NSTextAttachmentViewProvider associated with the receiver. The property contents are only valid with NSTextLayoutFragmentStateLayoutAvailable.     open var textAttachmentViewProviders: [NSTextAttachmentViewProvider] { get } I have checked the state. The state is available. How can I get the attachment frame when drawing. Thanks
Posted
by
Post not yet marked as solved
1 Replies
426 Views
The iOS demo project using updateContentSizeIfNeeded to get the layout frame and set the content size for text view. However, it looks like the height is not correct. There is always a huge spacer from the last paragraph to scroll view content bottom. (a.k.a calculated frame large than the real frame. I'm trying to use the TextKit 2 to layout the text without scrolling enabled. Should I use the old way NSAttirubtedString's boundingRect or there is some new method to calculate the frame size. Thanks.
Posted
by
Post not yet marked as solved
1 Replies
446 Views
I can't get NSTextView to work in textkit2 with the following code, textView.textContentStorage , textContentStorage.textStorage is both nil. does anyone have a working example? hope there is a Frameworks Engineer help me out, appreciate so much. import AppKit open class MyEditor: NSView {   let textView: NSTextView   let textLayoutManager: NSTextLayoutManager   let textContentStorage: NSTextContentStorage   public init() {     textLayoutManager = NSTextLayoutManager()     textContentStorage = NSTextContentStorage()           let textContainer = NSTextContainer(size: NSSize(width: 200, height: 0.0))     textContainer.widthTracksTextView = true     textContainer.heightTracksTextView = true           textLayoutManager.textContainer = textContainer     textContentStorage.addTextLayoutManager(textLayoutManager)           textView = NSTextView(frame: .zero, textContainer: textContainer)               super.init(frame: .zero)           addSubview(textView)   }       public func setAttributedString(_ attrString: NSAttributedString) {     print(textView.textContentStorage) // always nil     textContentStorage.textStorage?.setAttributedString(attrString)   }       public required init?(coder: NSCoder) {     return nil   } }
Posted
by