Post not yet marked as solved
In TextKit 1, I can override drawBackground(forGlyphRange:at:) in NSLayoutManager to do custom background drawing. However, I'm not too sure what the designated way of doing background drawing is in TextKit 2.
One thing I've tried is to do custom drawing in my own CALayer that's used in the configureRenderingSurface delegate callback, but I'm unsure if we are suppose to use this API and steal the textViewportLayoutController.delegate away from _UITextLayoutcanvasView?
Post not yet marked as solved
UITextview's Spellchecker seem not to detect spells and show red dots at odd position in MacCatalyst:
It does work well in iPhone and iPad though.
I've activated the Spellcheck through storyboard, also tested with both Normal and Attributed strings. Even tried disabling the scrolling. But nothing seems to help!
Does any one know about this behaviour?
Post not yet marked as solved
When I hover the mouse over the NSTextAttachment image inside the UITextview, it should show this option to MarkUp. All native app including Notes, TextEditor, Mail have this behaviour:
I think, by default, NSTextView will show the NSSharingServicePicker button when you hover over an image inside the text view. That’s true even for custom image-based NSTextAttachments in the attributed string.
But it is not showing the button for UITextview in MacCatalyst. Also NSSharingService class is limited to MacOS only.
Are there any alternative way to achieve this in MacCatalyst?
Post not yet marked as solved
When I tried this, the app crashed immediately with a requirement to use NSTextContentStorage subclass
Post not yet marked as solved
Hi TextKit 2 Team,
I'm trying to configure my own custom rendering surface when using UITextView(usingTextLayoutManager: true).
What I'm currently doing is adding a "contentLayer: CALayer" into my UITextView and adding my rendering surfaces into that.
The issue I'm running into, is that the rendering surface will display the first character I input, but then will not update for subsequent text until:
It becomes long enough to cause a line wrap.
I hit return.
Not sure if I'm doing something wrong? So my questions are:
Is using configureRenderingSurface API intended to be used when I'm using UITextView? Or it's only meant for when I do fully custom InputView?
Should I be inserting my rendering surfaces into my contentLayer or is there some more appropriate place for me to insert into?
How do I properly trigger redraw or invalidation of my rendering surface on text editing changes? Is this a bug or do I have to trigger an update manually somewhere?
Many thanks in advance!
Post not yet marked as solved
Hi TextKit team,
How do I access the textContentStorage of UITextView that is usingTextLayoutManager: true?
I'd like to use the NSTextContentStorageDelegate methods, but unlike NSTextView where it has a property for textContentStorage, it seems UITextView doesn't expose this?
Thanks for your help in advance!
Cheers / Leo
Post not yet marked as solved
Hi TextKit2 Team,
I'm trying to find the link to download the TextKitAndTextView sample code that was mentioned in the "What's new in TextKit and text views" video. I can't seem to find a link to it anywhere though.
Cheers / Leo
Post not yet marked as solved
Is there a simple way to create an NSFontCollection based on NSFontDescriptor querying to gather all installed/available fonts with a MATH table? It doesn't look like there's an attribute for that, but I don't know how else to search other than correlating with features like ssty, dtls, and flac.
It's a simple question. I'm just trying to understand how these things fit together. Core Text doesn't seem to get updated much, but maybe that's because it's low level and doesn't need it. I assume it's still the recommended way to do low-level text things not handled by TextKit. ?
Post not yet marked as solved
I just watched the WWDC22 video: "What's new in Textkit and text views" but don't see a resource link for the sample code for TextKitAndTextViewSampleApp. Does anyone have the link for this sample code?
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)
}
}
Post not yet marked as solved
Hi,
I am setting the attributed string to NSTextStorage and replacing it with another attributed string if need changes. I am getting crash with this stack trace:
CoreFoundation CFCharacterSetIsLongCharacterMember + 0x28
UIFoundation -[NSMutableAttributedString(NSMutableAttributedStringKitAdditions) fixFontAttributeInRange:] + 0x15fc
UIFoundation -[NSMutableAttributedString(NSMutableAttributedStringKitAdditions) fixAttributesInRange:] + 0x70
UIFoundation -[NSTextStorage processEditing] + 0xe0
UIFoundation -[NSTextStorage edited:range:changeInLength:] + 0x14c
Foundation -[NSConcreteMutableAttributedString replaceCharactersInRange:withAttributedString:] + 0x158
UIFoundation __71-[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:]_block_invoke + 0x28
UIFoundation __NSConcreteTextStorageLockedForwarding + 0x34
UIFoundation -[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:] + 0x44 \
Please help with what could be the issue. I have checked that the attributed string is not nil and the font is UIFont *.
Post not yet marked as solved
I need to implement a text editor using UITextView that supports:
Bold/Italic/Underline
Color,Font,font size changes
Paragraph alignment
List format (bullets, numbers, etc.)
Custom selection of text anywhere in the text view and change the properties
So far I have managed to do it without NSTextStorage but it seems I am hitting limits. For instance, to change font, I use UIFontPickerViewController and change the font as follows:
func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
if let selectedFontDesc = viewController.selectedFontDescriptor {
let font = UIFont(descriptor: selectedFontDesc, size: selectedFontDesc.pointSize)
self.selectedFont = font
self.textView.typingAttributes = [NSAttributedString.Key.foregroundColor: self.selectedColor ?? UIColor.white, NSAttributedString.Key.font: self.selectedFont ?? UIFont.preferredFont(forTextStyle: .body, compatibleWith: nil)]
if let range = self.textView.selectedTextRange, let selectedFont = selectedFont {
let attributedText = NSMutableAttributedString(attributedString: self.textView.attributedText)
let location = textView.offset(from: textView.beginningOfDocument, to: range.start)
let length = textView.offset(from: range.start, to: range.end)
let nsRange = NSRange(location: location, length: length)
attributedText.setAttributes([NSAttributedString.Key.font : selectedFont], range: nsRange)
self.textView.attributedText = attributedText
}
}
}
This works but the problem is it resets the color of the selected text and other properties. I need to understand a way in which the existing attributed of the text under selection are not disturbed. I suspect the way to do is with using NSTextStorage but I can't find anything good on internet that explains the right use of NSTextStorage to achieve this.
Post not yet marked as solved
label.text = "Very\u{00AD}VeryVeryVeryVeryVeryLongWordWithASoftHyphenTo"
Post not yet marked as solved
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.
Post not yet marked as solved
I have an implementation of UITextInput that is used to implement note taking with text. We have a custom UIMenuItem that lists suggested text replacements for a misspelled word that a user can interact with to fix the word. This works well on iPhone and iPad where the only path for changing text is via this menu.
On Mac Catalyst, however, the system also presents text replacement options with the best replacement; and when users attempt to replace text with the menu options provided by the system, our UITextInput handler seems to only receive a call to setSelectedTextRange: (the code is in Objective-C). I would expect a call to, for example, replaceRange:WithText: after an autocorrection is made
Any ideas what could possibly be incorrectly implementing? I.e., how can we receive the text that the system attempts to replace?
Post not yet marked as solved
I have an NSTextView which uses syntax highlighting via textDidChange delegate method. Its contents are scaled using scaleUnitSquareToSize.
Automatic scrolling works correctly when user reaches the bottom of the screen and line wraps — if this happens in the middle of the document. At the end, however, the scrolling seems to jump erratically for the first couple of characters.
Causes of the issue
I've tracked down the issue to a certain call order. Normally, textDidChange: is called between NSTextView keyDown: and NSClipView _scrollTo:, but not when the line gets so long it wraps.
When typing will cause the line to wrap, the call stack looks like this (from bottom to top):
[NSTextView adjustScroll:]
[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:]
[NSTextView keyDown:]
This is how it usually looks:
[NSTextView adjustScroll:]
[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:]
[Document textDidChange:]
[NSTextView keyDown:]
I have no idea how keyDown and _scrollTo determine where to scroll, but it seems that at some point, the text view scale is not taken into account, or gets calculated incorrectly.
Solutions?
I've tried wrapping my syntax highlighting in textStorage.beginEditing() and .endEditing(), which kind of fixes the issue, but also causes even more scrolling glitches when pressing space or deleting backwards.
I also tried disabling adjustScroll in the text view while syntax highlighting has not yet taken place, but that, too, causes completely random jumps in scroll position, again when inserting a space or deleting.
I'm trying to figure out how and where NSTextView determines the scroll position. There is no visible method in the call stack, but there has to be a method that checks if caret is in view and how to reposition content view's bounds, right? ...... Right?
Any help or hints would be appreciated.
Post not yet marked as solved
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?
I'm having issues in Xcode with the ContentView. The error says "cannot find ContentView in Scope". How do I fix that?
Post not yet marked as solved
I am trying to implement text checking in my custom text editor by implementing NSTextCheckingClient, but I can't get anything to work. And I can't find much documentation or any example code anywhere.
I have created an example project here:
https://github.com/jessegrosjean/NSTextInputClient