Manage text storage and perform custom layout of text-based content in your app's views using TextKit.

TextKit Documentation

Posts under TextKit tag

49 Posts
Sort by:
Post not yet marked as solved
0 Replies
295 Views
Good day together, I am currently trying to adjust the height of my TextEditor automatically. The whole thing should not increase further once 3 lines are reached. The whole thing is modeled after the text field in the iMessage app. Now to my problem: I'm trying to recreate the whole thing in SwiftUI and so far it works quite well, but I currently have the problem that the height of the control is not automatically adjusted and I unfortunately do not know how to do it best. Does anyone have a suggestion or even a solution for this? SwiftUI Snippet: VStack{           List{           }.listStyle(.plain)           HStack(alignment: .center){             Button{                             }label:{               Image(systemName: "plus.circle")                 .resizable()                 .frame(width: 25, height: 25, alignment: .center)             }             HStack{               TextEditor(text: $message)                 .focused($focusedField, equals: .messageView_TextEditor)                 .foregroundColor(self.message == "Message" ? .gray : .primary)                 .frame(height:35.0)                 .onTapGesture {                   if self.message == "Message"{                     self.message = ""                   }                 }                 .padding(.leading,10)                               Button{                                 }label:{                 Image(systemName: "arrow.up.circle.fill")                   .resizable()                   .frame(width: 25, height: 25, alignment: .center)                   .padding(.trailing,5)                   .foregroundColor(.green)               }             }.overlay(               RoundedRectangle(cornerRadius: 8)                 .stroke(Color.gray, lineWidth: 1)             )           }           .padding(.bottom)                                 }
Posted
by Cliplicht.
Last updated
.
Post not yet marked as solved
0 Replies
294 Views
I have a simple project where I replace the NSLayoutManager for a UITextView initialized in a storyboard using UITextView.textContainer.replaceLayoutManager(…). On iOS 14.5, the layout manager is correctly replaced and the overridden drawUnderline function is called to correctly render the text using the subclassed NSLayoutManager. On iOS 15.2, none of the overridden functions in the NSLayoutManager subclass are being called, and no text is rendered in the UITextView. Custom NSLayoutManager: CaptionTextLayoutManager.swift ViewController: ViewController.swift Result (iOS 14.5 on the left, iOS 15.2 on the right): I think this is a regression in iOS 15 and not from my code, however I could be missing something.
Posted
by zer0x.
Last updated
.
Post not yet marked as solved
0 Replies
264 Views
I'm trying to make a text editor with formatting for Mac OS. Which I have working using an NSTextView together with a custom NSTextStorage class. Which applies attributes like bold etc to NSAttributableStrings. This all seems to work fine as seen in screenshot one below. Which is an NSTextView with a custom NSTextStorage class attached to it. Which applies the formatting through attributes on an NSAttributeableString However, having everything the same, but getting a scrollable NSTextView from the Apple supplied function NSTextView.scrollableTextView() it does not display any text at all. Even though you can see in the screenshot that the NStextView is actually visible. Also, moving my mouse over the editor changes the cursor to the editor cursor. But I can't select, type or do anything. Doing the exact same thing as above, but not supplying a text container to the text view does show that it is wired up correctly, since I do get a scrollable text view then. Where the scrolling actually works, but then of course the formatting is no longer applied. So I'm confused on what I have to do now. This is basically my setup: // // TextDocumentViewController.swift // // Created by Matthijn on 15/02/2022. // Based on LayoutWithTextKit2 Sample from Apple import Foundation import AppKit class TextDocumentViewController: NSViewController { // Extends NSTextStorage, applies attributes to NSAttributeAbleString for formatting private var textStorage: TextStorage // Not custom yet, default implementation - do I need to subclass this specifically and implement something to support the scrolling behaviour? Which seems weird to me since it does work without scrolling support private var layoutManager: NSLayoutManager // Also default implementation private var textContainer: NSTextContainer private var textDocumentView: NSTextView private var scrollView: NSScrollView required init(content: String) { textStorage = TextStorage(editorAttributes: MarkdownAttributes) layoutManager = NSLayoutManager() textStorage.addLayoutManager(layoutManager) textContainer = NSTextContainer() // I'm not 100% sure if I need this on false or true or can just do defaults. No combination fixes it // textContainer.heightTracksTextView = false // textContainer.widthTracksTextView = true layoutManager.addTextContainer(textContainer) scrollView = NSTextView.scrollableTextView() textDocumentView = (scrollView.documentView as! NSTextView) // Basically commenting this out, stops applying my NSTextContainer, NSLayoutManager and NSTextContainer, but then of course the formatting is not applied. This one line changes it between it works without formatting, or it doesn't work at all. (Unless I have my text view not embedded in a scroll view) then it works but the scrolling of course then does not work. textDocumentView.textContainer = textContainer textDocumentView.string = content textDocumentView.isVerticallyResizable = true textDocumentView.isHorizontallyResizable = false super.init(nibName: nil, bundle: nil) } override func loadView() { view = scrollView } }
Posted
by Matthijn.
Last updated
.
Post not yet marked as solved
1 Replies
227 Views
The recent upgrade of the Mac OS seems to have removed some of the inspector bar tools from the NSTextView that formerly appears after setting usesInspectorBar to true. I see nothing in the documentation for any API for making these tools reappear. I notice that the TextEdit app's inspector bar is not missing them. Please tell me how to get my app's text view's inspector bar to look and behave like TextEdit.
Posted Last updated
.
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 Last updated
.
Post not yet marked as solved
3 Replies
1.4k Views
In the "old" TextKit, page-based layout is accomplished by providing an array of NSTextContainers to NSLayoutManager, each with its own NSTextView. TextKit 2, NSTextLayoutManager allows only a single text container. Additionally, NSTextParagraph seems to be the only concrete NSTextElement class. Paragraphs often need to break across page boundaries. How would one implement page-based layout in TextKit 2?
Posted
by sjs.
Last updated
.
Post not yet marked as solved
1 Replies
476 Views
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];      attachment.image = image;      attachment.bounds = CGRectMake(0, (font.capHeight - image.size.height) / 2, 15, image.size.height);      NSMutableAttributedString *imageString = [[NSAttributedString attributedStringWithAttachment:attachment] mutableCopy];
Posted
by Chang12.
Last updated
.
Post not yet marked as solved
0 Replies
343 Views
I have made a Scan to Text app with the help of sources from the internet, but I can’t figure out a way to get my output text to be editable. Here’s my code private func makeScannerView()-> ScannerView {         ScannerView(completion: {             textPerPage in             if let outputText = textPerPage?.joined(separator: "\n").trimmingCharacters(in: .whitespacesAndNewlines){                 let newScanData = ScanData(content: outputText)                 self.texts.append(newScanData)             }             self.showScannerSheet = false                      })     }
Posted
by YashSinha.
Last updated
.
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 Last updated
.
Post not yet marked as solved
5 Replies
1.3k Views
We are facing the below crash quite for some days, With key NSInternalInconsistencyException, after our users got updated their OS to iOS 15, for earlier versions it works fine without any crash. We are clueless as nothing in the stack call our native code and each line in the stack relates to UI. this issue is happening for most of our users repeatedly, we tried various scenarios but unable to find the root cause. Similar issues have found in the forum when upgrading from iOS 12 to 13 but they related to threading issues, this is of a kind range exception, please do the needful. Appreciate your help in advance. Fatal Exception: NSInternalInconsistencyException out of bounds characterRange {0, 0} specified to _drawTexCorrectionMarker:characterRange:atOrigin:graphicsContext: Fatal Exception: NSInternalInconsistencyException 0 CoreFoundation 0x9905c __exceptionPreprocess 1 libobjc.A.dylib 0x15f54 objc_exception_throw 2 Foundation 0x13099c _userInfoForFileAndLine 3 UIFoundation 0xa933c -[NSTextLineFragment _drawTexCorrectionMarker:characterRange:atOrigin:graphicsContext:] 4 UIFoundation 0x8b08 -[NSTextLineFragment drawTextCorrectionMarkersAtPoint:graphicsContext:] 5 UIFoundation 0x65c44 -[NSTextLineFragment drawAtPoint:graphicsContext:] 6 UIFoundation 0x69ef4 -[NSTextLineFragment drawAtPoint:inContext:] 7 UIFoundation 0x3eb80 -[NSTextLayoutFragment drawAtPoint:inContext:] 8 UIKitCore 0x649ce4 _UITextCanvasDrawWithFadedEdgesInContext 9 UIKitCore 0x77cb4c -[_UITextLayoutFragmentView drawRect:] 10 UIKitCore 0x188930 -[UIView(CALayerDelegate) drawLayer:inContext:] 11 QuartzCore 0x4d2c8 CABackingStoreUpdate_ 12 QuartzCore 0x8fe60 invocation function for block in CA::Layer::display_() 13 QuartzCore 0x91ae0 -[CALayer _display] 14 QuartzCore 0x31bc4 CA::Layer::layout_and_display_if_needed(CA::Transaction*) 15 QuartzCore 0x460b0 CA::Context::commit_transaction(CA::Transaction*, double, double*) 16 QuartzCore 0x4f174 CA::Transaction::commit() 17 QuartzCore 0x3121c CA::Transaction::flush_as_runloop_observer(bool) 18 UIKitCore 0x544c28 _UIApplicationFlushCATransaction 19 UIKitCore 0x7dead8 _UIUpdateSequenceRun 20 UIKitCore 0xe56294 schedulerStepScheduledMainSection 21 UIKitCore 0xe55760 runloopSourceCallback 22 CoreFoundation 0xbb030 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ 23 CoreFoundation 0xcbcf0 __CFRunLoopDoSource0 24 CoreFoundation 0x5ff8 __CFRunLoopDoSources0 25 CoreFoundation 0xb804 __CFRunLoopRun 26 CoreFoundation 0x1f3c8 CFRunLoopRunSpecific 27 GraphicsServices 0x138c GSEventRunModal 28 UIKitCore 0x51b060 -[UIApplication _run] 29 UIKitCore 0x298b8c UIApplicationMain 30 mobilex 0x41673c (Missing) 31 User Mobile 0x25f18 main + 43 (main.m:43) 32 ??? 0x1056f9a24 (Missing)
Posted
by Vinay0919.
Last updated
.
Post marked as solved
1 Replies
696 Views
On iOS 14 when attaching an image to a NSAttributedString the resulting height of the label is correct, however on iOS 15 it is too tall. iOS 14: iOS 15: Code: view.backgroundColor = .black label.layer.borderColor = UIColor.red.cgColor label.layer.borderWidth = 1 let font = UIFont.systemFont(ofSize: 11, weight: .bold) let text = NSMutableAttributedString(string: "LIVE", attributes: [.foregroundColor: UIColor.systemGreen, .font: font]) let attach = NSTextAttachment() attach.image = UIImage(named: "live_indicator_image")! let imageString = NSMutableAttributedString(attachment: attach) text.append(imageString) label.attributedText = text Image: Xcode version: 13.1 Simulator: iPhone 13 (15.0), iPhone 12 (14.4)
Posted Last updated
.
Post not yet marked as solved
64 Replies
8.7k Views
Hi, I'm an avid user of TextEdit to keep track of my thoughts and To-Do's through my work day. The result is, I end up with a fairly long text file, but not big on size in terms of storage. After updating to Big Sur 11.0.1, I'm noticing an odd behaviour. When every I press [Delete] more than thrice, the scroll bar jumps to the top of the text, i.e. the first line in the text file. This is very frustrating, especially, when you have lot of text and it scrolls all the way to the top. The only solution I have found is to press [Delete] slowly (may be one character per second) to avoid the scroll bar jumping to the first line of the text file. Also noticed, it does not happen in a full sentence, but only when when there's a short word and a line break [Enter] above and below the word. I'm continuing with the same file I had saved on Catalina and never had this issue. Looks like a bug to me. [PS: I am a user experience designer, not a developer and only have minimal knowledge of coding. ] Thanks, Anish
Posted
by Anish81.
Last updated
.
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 Last updated
.
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 Nuix.
Last updated
.
Post not yet marked as solved
0 Replies
295 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 gnuoyd.
Last updated
.
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 gnuoyd.
Last updated
.
Post not yet marked as solved
2 Replies
428 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 PilotSSW.
Last updated
.