我有一个简单的文本编辑器的NSDocument子类(使用Lion的基于新文档的应用程序模板,几乎没有自定义),我遇到了一个奇怪的错误,将文件内容加载到文本存储中.
这是我的代码:
- (void)loadTextContentIntoStorage
{
if (!self.textStorage || !textContentToLoad)
return;
...
[self.textStorage beginEditing];
// NSLog(@"storage: %@ length: %lu textContent: %@", self.textStorage, (unsigned long)self.textStorage.length, textContentToLoad);
// [self.textStorage replaceCharactersInRange:NSMakeRange(0, self.textStorage.length) withString:textContentToLoad];
[self.textStorage replaceCharactersInRange:NSMakeRange(0, 0) withString:@"hello world"];
..
[self.textStorage endEditing];
}
Run Code Online (Sandbox Code Playgroud)
当我发生错误时:
它崩溃-replaceCharactersInRange:withString:了"无法将字符串0x10004d430中的字节转换为_NSCStringEncoding".
但它只是发生在每一秒推出的应用程序(第三发射不会崩溃,它会自动重新打开它坠毁试图打开上次的文件).它也只发生在我从Xcode运行应用程序时.发布版本从未在发布时崩溃.
我认为这可能是自动保存系统的编码问题,但是当我注释掉该代码并将@"hello world"字符串加载到文本视图中时它甚至会崩溃(如上面的代码所示).同样,注释掉NSLog()并没有显示任何奇怪的东西.文本存储有效(从xib文件加载),文本存储长度为0,textContent是要打开的文件的内容.
---编辑---
我已经知道这个问题在某种程度上与com.apple.security.app-sandbox权利有关.如果启用了权利/沙箱,那么我的应用程序不会崩溃.如果禁用了权利或app-sandbox功能,那么我的应用程序会在尝试恢复以前打开的文档的每次启动时崩溃.
我只注意到在xcode内部进行构建/运行时崩溃,因为这是我唯一一个禁用沙箱的构建配置.
--- /编辑---
有没有人有任何想法?完整的例外如下,完整的源代码在github上:https://github.com/abhibeckert/Dux/blob/master/Dux/DuxTextView.m
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', …Run Code Online (Sandbox Code Playgroud) 根据文档,我尝试子类化NSTextStorage并在文本视图中使用它:
/*
NSTextStorage is a semi-abstract subclass of NSMutableAttributedString. It
implements change management (beginEditing/endEditing), verification of
attributes, delegate handling, and layout management notification. The one
aspect it does not implement is the actual attributed string storage --- this is
left up to the subclassers, which need to override the two
NSMutableAttributedString primitives:
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range;
*/
Run Code Online (Sandbox Code Playgroud)
所以我尝试使用delegate来处理具有相同功能的所有需要的事件:
@implementation MyTextStorage
- (id) init {
self = [super init];
if (self != nil) {
storage = [[NSMutableAttributedString …Run Code Online (Sandbox Code Playgroud) 我有一个NSTextView子类充当其NSTextStorage委托.我正在尝试做两件事:
我在两种不同的方法中执行此操作,这两种方法都由- (void)textStorageWillProcessEditing:(NSNotification *)notification委托回调调用.
我可以很好地进行语法突出显示,但是当附加我的答案时,插入点会跳到行的末尾,我不知道为什么.我的评估方法如下所示:
NSString *result = ..;
NSRange lineRange = [[textStorage string] lineRangeForRange:[self selectedRange]];
NSString *line = [[textStorage string] substringWithRange:lineRange];
line = [self appendResult:result toLine:line]; // appends the answer
[textStorage replaceCharactersInRange:lineRange withString:line];
Run Code Online (Sandbox Code Playgroud)
这样做会很好地追加我的结果,但问题是,如上所述,插入点会跳到最后.
我试过了:
[textStorage beginEditing]和-endEditing.我这样做了吗?我试图以最少的hackish方式做到这一点,我也不确定这是否是进行解析/突出显示的理想场所.文档让我相信这一点,但也许这是错的.
在AppKit中有没有办法快速测量大量NSString对象(比如一百万)的宽度?我尝试了3种不同的方法:
Count\Mechanism sizeWithAttributes NSAttributedString NSLayoutManager
1000 0.057 0.031 0.007
10000 0.329 0.325 0.064
100000 3.06 3.14 0.689
1000000 29.5 31.3 7.06
NSLayoutManager显然是要走的路,但问题在于
如果你想玩,这是github项目.
cocoa objective-c nslayoutmanager nsattributedstring nstextstorage
我正在尝试实现一个非常简单的文本编辑器,该文本编辑器应可同时NSTextView在macOS和UITextViewiOS上使用。该文本编辑器有一个工具栏按钮“分节符”,每次单击它都会在当前光标位置插入一个新节。一节应为:
在视觉上可识别为一个部分(通过在两个后续部分之间添加视觉分隔符,并可能添加一些垂直空白),
参考。用户应该能够在编辑器中看到所有部分的列表,并且通过单击该列表中的项目,文本视图应立即滚动到该部分的开头。
在另一个问题,我问怎么解决的第一个问题,不幸的是,我还没有发现在这部分的答案,但(即使是一个解决方案,仅在MacOS作品)。
但是,这个问题集中在第二个方面:
如何在我的文本视图中维护所有部分的列表,其中每个部分都能准确地引用相关文本?
此任务的复杂性在于用户可以随时复制和粘贴或简单地编辑文本的任何部分。因此,我无法保留简单的段落编号数组或类似的内容。
我曾经有一个想法是继承NSTextStorage并使用可变属性字符串数组作为其内部存储。然后,我将使用的特殊子类NSTextAttachment并将其用作文本存储中的分节符指示符。问题在于,每当用户编辑文本时,文本视图仅调用以下方法:
func replaceCharacters(in range: NSRange,
with str: String)
Run Code Online (Sandbox Code Playgroud)
和
func setAttributes(_ attrs: [NSAttributedString.Key : Any]?,
range: NSRange)
Run Code Online (Sandbox Code Playgroud)
第一种方法仅传递不带任何属性的纯字符串,第二种方法仅获取属性。这意味着在第一种方法中,我无法确定替换字符是否实际上应该是分节符,因此我无法确定此时在内部文本存储数组中的哪个位置创建新元素。
在第二种方法中,我不知道用户是否实际添加了新文本(在这种情况下,我将不得不在文本存储数组中为每个分节符属性添加一个新元素)还是用户只是更改了现有的某些属性文本(在这种情况下,先前已经创建了新的数组元素)。
我还考虑了在表视图或堆栈视图中使用多个文本视图的想法。但是,这不起作用,因为它将使用户无法选择(和删除)多个后续部分中的文本。
最后,我尝试了子类化NSLayoutManager,但是关于它的文档确实很薄,对我来说似乎是错误的地方。(毕竟,布局经理的职责是文本的布局,而不是跟踪其结构。)
我正在制作一些文本查看器应用程序 目前我需要非常频繁和精确的线路处理能力,所以我想要继承NSTextStorage类.但我找不到任何方法来设置新的文本存储NSTextView.我能找到的唯一方法是
-[NSLayoutManager replaceTextStorage:]
Run Code Online (Sandbox Code Playgroud)
方法.但令人困惑的是,这是我正在寻找的.因为它似乎只是替换链接的NSLayoutManagers而不是NSTextView的文本存储.
我还考虑了子类化NSTextView和重写-textStorage方法,但如果该类不是为子类设计的,那么它将产生未定义的结果.
有人试图在NSTextView上使用自定义NSTextStorage吗?我怎样才能做到这一点?或者这是否被设计禁止?
在iOS 8(或甚至可能在iOS 7/7.1中)NSAttributedStringiOS上添加了渲染文本表的功能.此API 在OS X上公开,但在iOS 上不公开.但是,可以通过将包含表的HTML传递给iOS,在iOS上创建包含文本表的属性字符串-[NSAttributedString initWithData:options:documentAttributes:error:].
正确创建了属性字符串,但是当我尝试使用a渲染字符串时UITextView,会抛出此异常:
<NSATSTypesetter: 0x7f8900faec90>: Exception *** -[NSConcreteTextStorage attribute:atIndex:effectiveRange:]: Range or index out of bounds raised during typesetting layout manager <NSLayoutManager: 0x7f8902e13440>
1 containers, text backing has 1884 characters
Currently holding 1884 glyphs.
Glyph tree contents: 1884 characters, 1884 glyphs, 1 nodes, 64 node bytes, 7680 storage bytes, 7744 total bytes, 4.11 bytes per character, 4.11 bytes per glyph
Layout tree contents: 1884 …Run Code Online (Sandbox Code Playgroud) 我继承NSTextStorage做一些链接高亮和我多读我可以对 话题.一切正常,直到我输入 emoji character.
private let ims = NSMutableAttributedString()
override var string: String {
return ims.string
}
override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] {
return ims.attributesAtIndex(location, effectiveRange: range)
}
override func replaceCharactersInRange(range: NSRange, withString str: String) {
ims.replaceCharactersInRange(range, withString: str)
self.edited(.EditedCharacters, range: range, changeInLength:(str as NSString).length - range.length)
}
override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) {
ims.setAttributes(attrs, range: range)
self.edited(.EditedAttributes, range: range, changeInLength: 0)
}
Run Code Online (Sandbox Code Playgroud)
Nothing complicated. …
objective-c ios nstextstorage nsmutableattributedstring swift
我正在使用 Markdown 语法的 Mac 应用程序中的富文本编辑器。我NSTextStorage过去常常在 Markdown 语法中观察匹配项,然后NSAttributedString像这样实时地将样式应用到:
在这一点上,我已经在这方面不知所措,但我很高兴能够取得进展。:)本教程非常有帮助。
作为下一步,我想在呈现 's 字符串时隐藏 Markdown 字符NSTextView。所以在上面的例子中,一旦最后一个星号被输入,我希望* *字符被隐藏,只是sample以粗体显示。
我正在使用NSLayoutManager委托,我可以看到匹配的字符串,但我不清楚如何使用该shouldGenerateGlyphs方法生成修改后的字形/属性。这是我到目前为止所拥有的:
func layoutManager(_: NSLayoutManager, shouldGenerateGlyphs _: UnsafePointer<CGGlyph>, properties _: UnsafePointer<NSLayoutManager.GlyphProperty>, characterIndexes _: UnsafePointer<Int>, font _: NSFont, forGlyphRange glyphRange: NSRange) -> Int {
let pattern = "(\\*\\w+(\\s\\w+)*\\*)" // Look for stuff like *this*
do {
let regex = try NSRegularExpression(pattern: pattern)
regex.enumerateMatches(in: textView.string, range: glyphRange) {
match, _, _ in …Run Code Online (Sandbox Code Playgroud) 我的目标是使用TextKit来斜体,设置某些单词的文本大小等.
首先,我只想在文本字符串中突出显示一个字符.作为TextKit的新手(以及一般的编程),我遵循obc.io问题#5的语法高亮主题.
当我使用内置于我创建的UITextView的NSLayoutManager时,我的文本出现在屏幕上,没有抛出异常.当我在我的视图控制器(下面)中将我的UITextView设置为我的NSTextStorage子类的布局管理器时,我收到了无效字形索引的异常错误.
_textStorage = [BBRSyntaxHighlightTextStorage new];
[_textStorage addLayoutManager: self.readerTextView.layoutManager];
Run Code Online (Sandbox Code Playgroud)
控制台输出如下:
_NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 528
2013-12-01 15:23:24.949 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange invalid char range 1
2013-12-01 15:23:24.956 BibleReader[6077:70b] !!! _NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 528
2013-12-01 15:23:24.957 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange invalid char range 1
2013-12-01 15:23:24.957 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange character count mismatch
2013-12-01 15:23:24.958 BibleReader[6077:70b] !!! _NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 4040
2013-12-01 15:23:24.959 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange invalid char range 1
Run Code Online (Sandbox Code Playgroud)
我已多次阅读Apple的文本编程指南,并认为我理解文本系统是如何建立的,但不知道为什么我的字形数量会超过字形的数量......
nstextstorage ×10
objective-c ×6
cocoa ×5
ios ×4
nstextview ×4
macos ×2
textkit ×2
uitextview ×2
subclassing ×1
swift ×1