我正在使用新的Text Kit API为某些属性文本添加附件:
// create an attachment for each image
NSTextAttachment* ta = [NSTextAttachment new];
ta.image = [UIImage imageNamed:@"imageName"];
// add to the attributed text string
NSAttributedString* rep = [NSAttributedString attributedStringWithAttachment:ta];
[myAttributedTextString appendAttributedString:rep];
Run Code Online (Sandbox Code Playgroud)
这工作正常,我可以看到我的图像在输出中呈现.但是,我找不到任何方法来指定图像对齐方式,或者在图像周围包装文本.
有任何想法吗?
注意:文本附件与排除路径不同 - 文本附件是"模型"的一部分,即它是布局管理器执行文本布局的属性文本字符串的一部分.而排除路径是视图的一部分.
我有一个UIImage包含多个图像帧和一个从动画GIF文件切片的持续时间.如果我将图像加载到UIWebView其中将按预期动画,但我想使用UITextView替代.显而易见的选择是使用带有自定义NSLayoutManger和许多自定义NSAttributedString属性的TextKit 来实现各种绘图效果.我有一个单一的UITextView,我想给一个NSAttributedString包含NSTextAttachments的所有图像我需要内联显示.它工作得很好,除了当我加载其中一个动画时UIImages,它们没有动画通过它们的帧.有关如何实现这一点的任何想法?我想出了一个理论选择:
UIImageView使用动画图像创建s,添加为子视图并调用startAnimating我还没有试过这个,但它相当hacky.我想知道是否有更好的选择.
总结:我想一个动画UIImage内UITextView通过NSTextAttachment内部NSAttributedString而不需要额外的UIImageView对象.你可以忽略这个以前用a做的事实UIWebView.UIImage具有用于设置动画帧的属性(images,duration),我目前已配置.如果我将它分配给UIImageView它动画,如果我将其设置为a NSTextAttachment,则不动画.
我将不胜感激任何反馈.谢谢!
问题
我需要了解TextKit的工作原理以及如何使用它来构建文本编辑器.我需要弄清楚如何仅绘制最终用户与之交互的可见文本,或者确定如何在不将属性应用于processEditing方法中的整个更改范围的文本的情况下懒惰地将属性应用于可见文本.
背景
iOS 7推出了TextKit.我有一个完全实现TextKit的tokenizer和代码(参考Apple的TextKitDemo项目 - 下面提供了一个链接)......它的工作原理.但是,它真的很慢.在通过NSTextStorage解析文本时,它要求您在processEditing方法中在同一线程上着色已编辑文本的ENTIRE范围.将工作卸载到线程没有帮助.这太慢了.我到了可以仅重新定义修改范围的点,但是如果范围太大,则过程将变慢.在某些情况下,整个文档可能会在更改后失效.
以下是我的一些想法.如果其中任何一个有用,或者可能在正确的方向上推动我,请告诉我.
1)多个NSTextContainers
阅读文档似乎我可以在NSLayoutManager中添加多个NSTextContainer.我假设通过这样做我不仅可以定义可以在NSTextContainer中绘制的行数,而且我还应该能够知道哪个NSTextContainer对最终用户可见.我知道,如果我走这条路,我需要投入大量时间才能看出它是否可行.初步测试表明您只需要一个NSTextContainer.所以我必须子类化NSLayout或创建一个包装器,布局管理器确定哪个文本进入哪个文本容器.呸.此外,我不知道TextKit如何让我知道是时候绘制一个特定的NSTextContainer ...也许这不是它的工作方式!
2)使用NSLayoutManager使范围无效
使用invalidateLayoutForCharacterRange:actualCharacterRange:使layoutManager无效.但这实际上做了什么以及如何卸载文本归属阶段?什么时候让我知道需要突出显示特定文本?另外,我看到NSLayoutManager会懒洋洋地绘制字形......怎么样?什么时候?这对我有什么帮助?如何点击此调用以便在实际布置文本之前我可以将支持字符串归属?
3)覆盖NSLayoutManager drawGlyphsForGlyphRange:atPoint:方法.
我真的不想这样做.话虽这么说,在Mac OS X中,NSAttributedStrings具有临时属性的概念,其中样式信息仅用于表示.这加快了突出显示的过程!问题是,它在iOS 7 TextKit框架中不存在(或者它就在那里,我只是不知道它).我相信通过覆盖这种方法,它会给我与使用临时属性所获得的相同类型的速度......因为我可以回答此方法中的所有布局,颜色和格式问题,而无需触及NSTextStorage归因串.唯一的问题是,我不知道这个方法如何与NSLayoutManager类中提供的其他方法相关.它是否保持宽度和高度的状态?当它太小时,它是否会修改NSTextContainer的大小?此外,它仅为已在文本缓冲区中添加的字符绘制字形.它不会重新绘制整个屏幕.它只是它的一小部分......而且非常好.我有一些关于如何使用它的想法...但我真的不想布置字形.这是太多的工作,我没有找到一个很好的例子来做到这一点.
非常感谢您提供的任何帮助.
谢谢你,我列出了过去几年我用过的所有框架和参考资料,这些框架和参考资料帮助我到达了现在的位置,希望它们对你有所帮助.
突出显示框架的语法:
资源:
大多数这些框架都是相同的.它们要么不考虑上下文切换(或者你必须编写包装器以提供上下文),要么它们不修复上下文范围,因为用户修改了文本(例如字符串,多行注释等).最后一项要求非常重要.因为如果标记生成器无法确定哪些范围受更改影响,则最终必须再次解析并归因整个字符串.唯一的例外是Crimson Editor.此标记化程序的问题是它在标记化时不保存状态.在绘制时,算法使用标记来确定绘图的状态.它从文档的顶部开始,直到达到可见的文本范围.不用说,
另一个问题是框架不遵循与Apple相同的MVC模式 - 这是预期的.具有完整工作编辑器的框架都使用由它们构建的API(即GTK,Windows等)提供的钩子,这些钩子为它们提供了绘制到屏幕的哪个部分的位置和时间的信息.在我的例子中,TextKit似乎要求您在processEditing中归因整个更改的范围.
也许我的观察是错误的.(我希望它们是!!)也许,ParseKit,例如,将适用于我需要它做什么,我只是不明白如何使用它.如果是这样,请告诉我!再次感谢!
我有一个显示NSAttributedString的UIView.它设置为调整大小以适应其内容.
我想在文本和视图之间创建一些填充,但它不是很有效.如果我这样做......
view.textContainerInset = UIEdgeInsetsMake(0, 15, 0, 15);
Run Code Online (Sandbox Code Playgroud)
...然后左边和右边填充,顶部和底部没有空间.这是对的.然后我添加一个顶部插图:
view.textContainerInset = UIEdgeInsetsMake(15, 15, 0, 15);
Run Code Online (Sandbox Code Playgroud)
现在顶部有15个点填充,但突然底部也有一点填充(大约10点).
如果我然后添加15点底部填充,底部变得太大,并且间距不是一直相同.相反,我必须捏造它:
view.textContainerInset = UIEdgeInsetsMake(15, 15, 5, 15);
Run Code Online (Sandbox Code Playgroud)
这是iOS 7的错误还是我误解了什么?我不喜欢在不了解正在发生的事情的情况下捏造最低价值.
在WWDC 2013的会话220(高级文本布局和带有文本工具包的效果)中,他们明确地说NSLayoutManager可以与创建高级文本动画一起使用NSTextStorage并NSTextContainer创建高级文本动画.他们没怎么说.
我想使用NSLayoutManager/ NSTextStorage/ NSTextContainer来创建自定义文本动画.简单地说,我想为各个字形的大小和位置设置动画,并淡化和解开特定的字形.
似乎没有专门的方法和动画文档,NSLayoutManager我发现的唯一教程就在这里.然而,它展示了如何破解NSLayoutManager动画,而不是如何以它应该使用的方式使用它们(它们CATextLayer为每个单独的字形创建!).
有人能指出我正确的方向吗?我知道如何使用NSLayoutManager/ NSTextStorage/ NSTextContainer来呈现静态文本.一些演示,显示动画文本的原理NSLayoutManager将是完美的.为了让我开始,我可以自己弄清楚细节.
我有一个设置的标签,adjustsFontSizeToFitWidth = YES我需要获得实际显示的字体大小.
现在,iOS 7弃用了之前有效的所有方法,所有关于SO的问题建议使用这些弃用的方法.
一旦我被SO允许,我就会把这个问题作为赏金.请不要关闭.
我正在使用"使用文本工具包管理iOS应用程序中的文本"教程.它是为Objective C编写的,但我认为无论如何我都会尝试使用Swift.
但是,当我得到以下代码时,我无法弄清楚如何为UITextView使用Swift 设置标题和其他样式.这是Objective C代码:
- (IBAction)applyHeadlineStyle:(id)sender {
[_textView setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]];
}
- (IBAction)applySubHeadlineStyle:(id)sender {
[_textView setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]];
}
- (IBAction)applyBodyStyle:(id)sender {
[_textView setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]];
}
- (IBAction)applyFootnoteStyle:(id)sender {
[_textView setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]];
}
- (IBAction)applyCaption1Style:(id)sender {
[_textView setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]];
}
- (IBAction)applyCaption2Style:(id)sender {
[_textView setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleCaption2]];
}
Run Code Online (Sandbox Code Playgroud)
我试过了
textView.setFont =
textView.preferredFontForTextStyle =
Run Code Online (Sandbox Code Playgroud)
然而,这些似乎都不起作用,而且我找不到任何Swift答案.
我正在开发一个文本视图,用UITextFields替换占位符.我传递了一个对象(结构或字典),其中包含多个占位符令牌实例的文本.该字典还包含我们想要从中收集数据的字段数组.我的目标是在我的文本中放置UITextFields(或其他视图),并隐藏令牌.
使用NSLayoutManager方法计算文本容器中占位符标记的位置,我将这些点转换为CGRects然后排除路径到文本字段周围.这是看起来像:
func createAndAssignExclusionPathsForInputTextFields () {
var index = 0
let textFieldCount = self.textFields.count
var exclusionPaths : [UIBezierPath] = []
while index < textFieldCount {
let textField : AgreementTextField = self.textFields[index]
let location = self.calculatePositionOfPlaceholderAtIndex(index)
let size = textField.intrinsicContentSize()
textField.frame = CGRectMake(location.x, location.y, size.width, size.height)
exclusionPaths.append(textField.exclusionPath())
index = index + 1
}
self.textContainer.exclusionPaths = exclusionPaths
}
Run Code Online (Sandbox Code Playgroud)
// ...
func calculatePositionOfPlaceholderAtIndex(textIndex : NSInteger) -> CGPoint {
let layoutManager : NSLayoutManager = self.textContainer.layoutManager!
let delimiterRange = self.indices[textIndex]
let characterIndex = …Run Code Online (Sandbox Code Playgroud) 每当我尝试在UITextView的attributedText上设置下划线或删除线属性时,我都会遇到运行时故障.其他属性,如字体和背景颜色没有问题.这是一段代码片段.我所拥有的只是一个带有单个UITextView的测试项目.我在iOS 11上.
class ViewController: UIViewController {
@IBOutlet weak var myTextView: UITextView!
var myMutableString = NSMutableAttributedString(string: "")
override func viewDidLoad() {
super.viewDidLoad()
let string = "The cow jumped over the moon" as NSString
myMutableString = NSMutableAttributedString(string: string as String)
let underlineAttribute = [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle]
myMutableString.addAttributes(underlineAttribute, range: string.range(of: "cow"))
myTextView.attributedText = myMutableString
}
}
Run Code Online (Sandbox Code Playgroud)
这导致文本消失并打印出一些错误:
2017-11-05 19:43:34.708830-0800 UITextView_Test[11771:907014]
-[_SwiftValue _getValue:forType:]: unrecognized selector sent to instance 0x60c00004eb50 2017-11-05 19:43:34.709351-0800 UITextView_Test[11771:907014] <NSATSTypesetter: 0x60800016be80>: Exception -[_SwiftValue _getValue:forType:]: unrecognized selector sent to instance 0x60c00004eb50 raised during …Run Code Online (Sandbox Code Playgroud) 为了支持该UIAccessibilityReadingContent协议,我需要我的UITextView来回答有关其行的问题.这些是我需要实现的协议的方法:
accessibilityLineNumberForPoint: < - 提供坐标,返回行号accessibilityContentForLineNumber: < - 返回给定行的文本accessibilityFrameForLineNumber: < - 给定行号,返回其帧accessibilityPageContent< - 整个文本内容.我有.:)我认为NSLayoutManager可以帮助我,但我对它没有经验.我已经想到了一些(我认为),但仍然需要一些帮助.
Apple有一些示例代码(此处)可以获取文本视图中的行数:
NSLayoutManager *layoutManager = [textView layoutManager];
unsigned numberOfLines, index, numberOfGlyphs =
[layoutManager numberOfGlyphs];
NSRange lineRange;
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index
effectiveRange:&lineRange];
index = NSMaxRange(lineRange);
}
Run Code Online (Sandbox Code Playgroud)
我用lineRange上面的数字来计算,我可以使用这个方法计算行数NSLayoutManager:
- (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container
Run Code Online (Sandbox Code Playgroud)
鉴于lineRanges我应该能够计算一个点的行号(通过找到lineRange包含字形索引的行号):
- (NSUInteger)glyphIndexForPoint:(CGPoint)point inTextContainer:(NSTextContainer *)container fractionOfDistanceThroughGlyph:(CGFloat *)partialFraction
Run Code Online (Sandbox Code Playgroud)
剩下的是,如果给出行号,我如何得到一行(作为一个NSString)的内容?
textkit ×10
ios ×9
uitextview ×4
objective-c ×3
uikit ×3
ios7 ×2
uilabel ×2
animation ×1
appkit ×1
layout ×1
nsstring ×1
parsekit ×1
swift ×1
text-styling ×1
voiceover ×1