在 iOS 8(甚至可能在 iOS 7/7.1)NSAttributedString
中,iOS 添加了呈现文本表格的能力。此 API在 OS X 上是公开的,但在 iOS 上不公开。但是,可以通过将包含表格的 HTML 传递到-[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 characters, 1884 glyphs, 417 laid glyphs, 3 laid line fragments, 3 nodes, 192 node bytes, 1568 storage bytes, 1760 total bytes, 0.93 bytes per character, 0.93 bytes per glyph, 139.00 laid glyphs per laid line fragment, 586.67 bytes per laid line fragment, glyph range {417 4}. Ignoring...
这是回溯:
thread #1: tid = 0x14334, 0x000000010ec0bb8a libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010ec0bb8a libobjc.A.dylib`objc_exception_throw
frame #1: 0x000000010ef72e6d CoreFoundation`+[NSException raise:format:] + 205
frame #2: 0x0000000112ebe9f6 UIFoundation`-[NSConcreteTextStorage attribute:atIndex:effectiveRange:] + 131
frame #3: 0x0000000112e8a51b UIFoundation`-[NSAttributedString(NSAttributedStringUIFoundationAdditions) rangeOfTextTable:atIndex:] + 65
frame #4: 0x0000000112ec0e1b UIFoundation`-[NSTextBlockLayoutHelper initWithTextTable:charIndex:text:layoutManager:containerWidth:collapseBorders:] + 376
frame #5: 0x0000000112ec585f UIFoundation`-[NSTextTable rectForBlock:layoutAtPoint:inRect:textContainer:characterRange:] + 355
frame #6: 0x0000000112ec3c3b UIFoundation`-[NSTextTableBlock rectForLayoutAtPoint:inRect:textContainer:characterRange:] + 116
frame #7: 0x0000000112ecdb3b UIFoundation`-[NSTypesetter getLineFragmentRect:usedRect:remainingRect:forStartingGlyphAtIndex:proposedRect:lineSpacing:paragraphSpacingBefore:paragraphSpacingAfter:] + 2204
frame #8: 0x0000000112e702c3 UIFoundation`-[NSATSTypesetter _layoutLineFragmentStartingWithGlyphAtIndex:characterIndex:atPoint:renderingContext:] + 1716
frame #9: 0x0000000112e71dfc UIFoundation`-[NSATSTypesetter layoutParagraphAtPoint:] + 156
frame #10: 0x0000000112ecb643 UIFoundation`-[NSTypesetter _layoutGlyphsInLayoutManager:startingAtGlyphIndex:maxNumberOfLineFragments:maxCharacterIndex:nextGlyphIndex:nextCharacterIndex:] + 3391
frame #11: 0x0000000112ecccf9 UIFoundation`-[NSTypesetter layoutCharactersInRange:forLayoutManager:maximumNumberOfLineFragments:] + 246
frame #12: 0x0000000112e72761 UIFoundation`-[NSATSTypesetter layoutCharactersInRange:forLayoutManager:maximumNumberOfLineFragments:] + 388
frame #13: 0x0000000112e5cb4a UIFoundation`-[NSLayoutManager(NSPrivate) _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] + 1258
frame #14: 0x0000000112e5e5b7 UIFoundation`-[NSLayoutManager(NSPrivate) _fillLayoutHoleAtIndex:desiredNumberOfLines:] + 201
frame #15: 0x0000000112e5ec3f UIFoundation`-[NSLayoutManager(NSPrivate) _markSelfAsDirtyForBackgroundLayout:] + 344
frame #16: 0x0000000112e68e3d UIFoundation`-[NSLayoutManager(NSPrivate) _invalidateLayoutForExtendedCharacterRange:isSoft:invalidateUsage:] + 2143
frame #17: 0x0000000112e9484b UIFoundation`-[NSLayoutManager textContainerChangedGeometry:] + 315
frame #18: 0x0000000112eb906d UIFoundation`-[NSTextContainer setSize:] + 200
frame #19: 0x000000010fcb5a0e UIKit`__47-[UITextView _performLayoutCalculation:inSize:]_block_invoke + 229
frame #20: 0x0000000112e9e718 UIFoundation`-[NSLayoutManager(TextLocking) coordinateAccess:] + 55
frame #21: 0x000000010fcb591a UIKit`-[UITextView _performLayoutCalculation:inSize:] + 223
frame #22: 0x000000010fcb5d04 UIKit`-[UITextView _intrinsicSizeWithinSize:] + 411
frame #23: 0x000000010fcb5f17 UIKit`-[UITextView intrinsicContentSize] + 130
frame #24: 0x000000010fc21ea4 UIKit`-[UIView(UIConstraintBasedLayout) _generateContentSizeConstraints] + 33
frame #25: 0x000000010fc21c64 UIKit`-[UIView(UIConstraintBasedLayout) _updateContentSizeConstraints] + 422
frame #26: 0x000000010fc290d6 UIKit`-[UIView(AdditionalLayoutSupport) updateConstraints] + 163
frame #27: 0x000000010fcb62e7 UIKit`-[UITextView updateConstraints] + 271
frame #28: 0x000000010fc286fa UIKit`-[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 248
frame #29: 0x000000010fc288f2 UIKit`-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
frame #30: 0x000000010ee7b194 CoreFoundation`CFArrayApplyFunction + 68
frame #31: 0x000000010fc2869b UIKit`-[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
frame #32: 0x000000010fc288f2 UIKit`-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
frame #33: 0x000000010ee7b194 CoreFoundation`CFArrayApplyFunction + 68
frame #34: 0x000000010fc2869b UIKit`-[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
frame #35: 0x000000010fc288f2 UIKit`-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
frame #36: 0x000000010fc28dbe UIKit`__60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 96
frame #37: 0x000000010fc28a86 UIKit`-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded] + 231
frame #38: 0x000000010fa1e8b8 UIKit`-[UITableViewCellContentView updateConstraintsIfNeeded] + 95
frame #39: 0x000000010fc253a9 UIKit`-[UIView(AdditionalLayoutSupport) _systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:hasIntentionallyCollapsedHeight:] + 298
frame #40: 0x000000010f82790d UIKit`-[UITableViewCell systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:] + 316
frame #41: 0x000000010f69fd65 UIKit`-[UITableView _heightForCell:atIndexPath:] + 363
frame #42: 0x000000010f6926e7 UIKit`__53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1917
frame #43: 0x000000010f6135ce UIKit`+[UIView(Animation) performWithoutAnimation:] + 65
frame #44: 0x000000010f691f5b UIKit`-[UITableView _configureCellForDisplay:forIndexPath:] + 312
frame #45: 0x000000010f6994cc UIKit`-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 533
frame #46: 0x000000010f678fb1 UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 2846
frame #47: 0x000000010f68ee3c UIKit`-[UITableView layoutSubviews] + 213
frame #48: 0x000000010f61b973 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
frame #49: 0x000000010e11dde8 QuartzCore`-[CALayer layoutSublayers] + 150
frame #50: 0x000000010e112a0e QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 380
frame #51: 0x000000010e11287e QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
frame #52: 0x000000010e08063e QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 242
frame #53: 0x000000010e08174a QuartzCore`CA::Transaction::commit() + 390
frame #54: 0x000000010e081db5 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 89
frame #55: 0x000000010eea7dc7 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #56: 0x000000010eea7d20 CoreFoundation`__CFRunLoopDoObservers + 368
frame #57: 0x000000010ee9db53 CoreFoundation`__CFRunLoopRun + 1123
frame #58: 0x000000010ee9d486 CoreFoundation`CFRunLoopRunSpecific + 470
frame #59: 0x00000001139eb9f0 GraphicsServices`GSEventRunModal + 161
frame #60: 0x000000010f5a2420 UIKit`UIApplicationMain + 1282
frame #61: 0x000000010d8cb33e MyApp`top_level_code + 78 at AppDelegate.swift:12
frame #62: 0x000000010d8cb37a MyApp`main + 42 at AppDelegate.swift:0
frame #63: 0x0000000111cbd145 libdyld.dylib`start + 1
我认为这是 Apple 的一个错误,并试图创建一个最小的项目来重现该问题,但无法这样做。在我的测试项目中呈现完全相同的属性字符串效果很好,但在我的应用程序中仍然无法正常工作,这让我相信也许我做错了什么。在没有表格的情况下渲染属性字符串可以正常工作,这是渲染表格特有的问题。有没有其他人遇到过类似的问题?