如果我在a中有一个带有排除路径的TextView,UITableViewCell我如何计算给定字符串的单元格高度?
我在iOS 7中使用Text Kit来创建富文本编辑器.以下是问题所在.
首先,然后字体大小为16:

然后我使用代码插入图像:
// Image Attachment
NSTextAttachment *imageAttachment = [[NSTextAttachment alloc] init];
[imageAttachment setImage:image];
imageAttachment.bounds = CGRectMake(0, 0, width, height);
[self insertTextAttachment:imageAttachment];
Run Code Online (Sandbox Code Playgroud)
和
- (void)insertTextAttachment:(NSTextAttachment*)textAttachment {
NSMutableAttributedString *newContent = [[NSMutableAttributedString attributedStringWithAttachment:textAttachment] mutableCopy];
NSMutableAttributedString *currentContent = [self.contentTextView.attributedText mutableCopy];
[currentContent insertAttributedString:[[NSAttributedString alloc] initWithString:@"\n"] atIndex:mEditingRange.location];
[currentContent insertAttributedString:[[NSAttributedString alloc] initWithString:@"\n"] atIndex:mEditingRange.location];
mEditingRange.location++;
[currentContent replaceCharactersInRange:mEditingRange withAttributedString:newContent];
[currentContent setAttributes:@{NSFontAttributeName: [UIFont fontWithName:kOFontDefault size:16.0]} range:NSMakeRange(mEditingRange.location + newContent.length, 1)];
[self.contentTextView setAttributedText:currentContent];
}
Run Code Online (Sandbox Code Playgroud)
但是,插入图像后,文本字体意外更改:

我尝试使用以下代码来解决问题(在insertTextAttachment:方法中添加):
[currentContent setAttributes:@{NSFontAttributeName: [UIFont fontWithName:kOFontDefault size:16.0]} range:NSMakeRange(mEditingRange.location + newContent.length, 1)];
Run Code Online (Sandbox Code Playgroud)
问题部分修复,新行中的新文本使用正确的字体,但图像旁边的文本仍然是错误:

有人可以帮忙吗?
在我的代码中:
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"12123"];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"002"];
attachment.bounds = CGRectMake(0, 0, 20, 20);
[str insertAttributedString:[NSAttributedString attributedStringWithAttachment:attachment] atIndex:2];
CGRect rect = [str boundingRectWithSize:CGSizeMake(200, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
context:nil];
Run Code Online (Sandbox Code Playgroud)
结构'rect'不正确,为什么?
我正在构建一个自定义NSTextStorage类来查找和匹配自定义用户输入并在我的应用程序中处理它.所以我遵循了几个教程,最着名的是objc.io,并创建了一个子类,并将其设置layoutManager为UITextView通过nib创建的相同:
-(void)setCustomTextStorage:(NSTextStorage *)customTextStorage
{
if (_customTextStorage != customTextStorage)
{
_customTextStorage = customTextStorage;
[_customTextStorage addLayoutManager:self.textView.layoutManager];
}
}
Run Code Online (Sandbox Code Playgroud)
然后在覆盖processEditing的NSTextStorage子类,并添加NSLinkAttributeName适当.
顺便说一下,这里有示例应用程序,请务必签出custom-text-storage分支或只是在这里阅读差异这个问题
现在,当用户点击实际链接时,我得到一个崩溃应用程序的异常:
2014-08-20 23:06:45.223 JSQMessages[63170:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSConcreteTextStorage attribute:atIndex:effectiveRange:]: Range or index out of bounds'
*** First throw call stack:
(
0 CoreFoundation 0x00000001025d2495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001021a999e objc_exception_throw + 43 …Run Code Online (Sandbox Code Playgroud) 我想在UITextView中"突出显示"特定的单词,而不是使用纯色(这可能是通过NSAttributedString),而是使用渐变和其他一些奇特的效果.
因此,我决定有必要使用给定文本的边界矩形手动创建视图并覆盖(或底层)它.
令我惊讶的是,事实证明这非常简单.实施例是一个UIViewController内,txtView被一个UITextView连接为IBOutlet:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Converting to NSString as I need a NSRange for glphyRangeForCharacterRange
// (a normal String in Swift returns a Range)
let charRange = (txtView.text as NSString).rangeOfString("dolor sit er elit")
assert(charRange.location != NSNotFound, "Character Range could not be found.")
let glyphRange = txtView.layoutManager.glyphRangeForCharacterRange(charRange,
actualCharacterRange: nil)
let glyphContainer = txtView.layoutManager.textContainerForGlyphAtIndex(glyphRange.location, effectiveRange: nil)
let glyphRect = txtView.layoutManager.boundingRectForGlyphRange(glyphRange,
inTextContainer: glyphContainer!)
let highlightView = UIView(frame: glyphRect)
highlightView.alpha = 0.3 …Run Code Online (Sandbox Code Playgroud) 我有一个包含UITextView的子类UITableViewCell.我已将NSParagraphStyle作为属性添加到子类NSTextStorage中的字符串中.在下面的代码中,我增加了UITextView中每行之间的空间.
迅速
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 11
myCustomTextStorage.appendAttributedString(NSAttributedString(string: someText, attributes: [NSParagraphStyleAttributeName: paragraphStyle]))
Run Code Online (Sandbox Code Playgroud)
光标高度延长到下一行的高度,如下所示.这仅发生在最后一行之前的行上.

关于这个问题,我已经看了几篇关于SO的帖子,包括这篇文章 ; 但是,提议的解决方案似乎都不适合我.
我已经阅读了TextKit文档,但没有找到任何解决此问题的方法.
有没有办法降低光标高度?
查看文档NSLayoutManager,特别是drawUnderlineForGlyphRange:underlineType:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:方法,我注意到以下内容(强调我的):
underlineVal
画下划线的风格.此值是从NSUnderlineStyleAttributeName-for(例如)(NSUnderlinePatternDash|NSUnderlineStyleThick)的值派生的掩码.子类可以定义自定义下划线样式.
我的问题是:这究竟是怎么做的?
NSUnderlineStyle是一个枚举,你无法扩展或覆盖.您当然可以Int为属性提供随机原始值,但不包括枚举案例:
self.addAttribute(NSUnderlineStyleAttributeName, value: 100022, range: lastUpdatedWordRange)
哪个会传递"无效"但可underlineType用于布局管理器:
但这并不安全,绝对不优雅.
我无法在线找到任何示例,也无法在Apple文档中找到有关神秘自定义下划线样式类型的更多线索.我很想知道我是否遗漏了一些明显的东西.
默认布局管理器填充没有文本(最后一行除外)的背景颜色(通过 NSAttributedString .backgroundColor 属性指定)。
我已经通过子类化 NSLayoutManager 并覆盖来实现我想要的效果,func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint)如下所示:
override func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
guard let textContainer = textContainers.first, let textStorage = textStorage else { fatalError() }
// This just takes the color of the first character assuming the entire container has the same background color.
// To support ranges of different colours, you'll need to draw each glyph separately, querying the attributed string for the
// background color attribute …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个自定义NSTextBlock,就像Apple在WWDC 18上(在23分钟内)所做的那样。
好的,所以当我用带有文本块的段落样式编辑和标记段落时,它的效果很好。
但是,当我剪切并粘贴它(或从磁盘归档/取消归档)时,它将丢失。编辑:它实际上将我的TweetTextBlock子类转换为NSTableViewTextBlock,这也说明了边界。
实作
这是完整的Xcode项目。使用Format顶部菜单项触发markTweet功能。
这是我将属性添加到段落的方法
@IBAction func markTweet(_ sender : Any?){
print("now we are marking")
let location = textView.selectedRange().location
guard let nsRange = textView.string.extractRange(by: .byParagraphs, at: location) else { print("Not in a paragraph"); return }
let substring = (textView.string as NSString).substring(with: nsRange)
let tweetParagraph = NSMutableParagraphStyle()
tweetParagraph.textBlocks = [TweetTextBlock()]
let twitterAttributes : [AttKey : Any] = [
AttKey.paragraphStyle : tweetParagraph,
AttKey.font : NSFont(name: "HelveticaNeue", size: …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建标签/标签/徽章来标记某些单词(实际上有时多个单词可以构成一个标签)。目前,我添加了一个自定义 NSAttributedString 键,用于用词性标记单词。我想用圆形背景色标记这些单词。我已经浏览了此示例代码中的代码,它创建了如下标签:
但示例代码仅采用现有的 NSTextElements(段落级别)并对它们应用样式。当我从文本代码插入相同的委托函数时,所有文本元素都是段落级别的。例如
This is one.
This is two.
Run Code Online (Sandbox Code Playgroud)
将创建两个文本元素:This is one.和This is two.。我很好奇如何将它们分成多个文本元素。例如,如果我只想标记EGGin EGG SANDWICH NO. 2,我猜我需要将该文本元素分成两个(EGG 和 SANDWICH NO.2),但我目前不知道如何做到这一点,或者找到任何示例在MacOS上为文本添加文字标签(该应用程序不需要支持iOS,只支持MacOS)。
我是否走在实现这一目标的正确道路上?如果是这样,拆分 NSTextElements 的最佳方法是什么?
textkit ×10
ios ×8
swift ×6
core-text ×2
uitextview ×2
height ×1
image ×1
ios7 ×1
iphone ×1
nstextview ×1
objective-c ×1
uikit ×1
uitableview ×1