我最近决定解决我遇到的问题的最佳方法是使用NSAttributedString实例.文档似乎缺乏,至少对新手而言.stackoverflow的答案主要有两种类型:
我真的很喜欢第二个答案.但是我想更好地理解NSAttributedString,所以我在这里提供了最小的(?)组装和显示属性字符串的示例,以防它帮助其他人.
我使用Storyboard和ARC在Xcode(4.5.2)中为iPad创建了一个新的单窗口项目.
AppDelegate没有任何变化.
我创建了一个基于UIView的新类,将其命名为AttributedStringView.对于这个简单的示例,最简单的方法是使用drawAtPoint:方法将属性字符串放在屏幕上,这需要一个有效的图形上下文,并且在UIView子类的drawRect:方法中最容易获得.
这是完整的ViewController.m(没有对头文件进行任何更改):
#import "ViewController.h"
#import "AttributedStringView.h"
@interface ViewController ()
@property (strong, nonatomic) AttributedStringView *asView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.asView];
}
- (AttributedStringView *)asView
{
if ( ! _asView ) {
_asView = [[AttributedStringView alloc] initWithFrame:CGRectMake(10, 100, 748, 500)];
[_asView setBackgroundColor:[UIColor yellowColor]]; // for visual assistance
}
return _asView;
}
@end
Run Code Online (Sandbox Code Playgroud)
这里是完整的AttributedStringView.m(没有对头文件进行任何更改):
#import "AttributedStringView.h"
@interface AttributedStringView ()
@property (strong, nonatomic) NSMutableAttributedString *as;
@end
@implementation AttributedStringView
- (id)initWithFrame:(CGRect)frame
{ …Run Code Online (Sandbox Code Playgroud) 是否可以在同一个UILabel中使用不同的字体大小或重量?我可以在故事板中作为属性标签来做,但我需要以编程方式进行.
cell.lblOne.text = [NSString stringWithFormat:
@"FontSize15:: %@, FontSize20:: %@",monkey, goat];
Run Code Online (Sandbox Code Playgroud)
编辑:我看到了一些关于NSAttributedString但我不能让它工作的东西.
iOS 7用于NSString::sizeWithAttributes计算NSString给定NSDictionary属性的边界框的大小.但是,我找不到列出可用于其中的所有枚举键的资源NSDictionary.
这些属性可以应用于NSAttributedString对象
但是没有列出它们,它们也没有在NSAttributedString文档中列出.
另外:可用的属性键,这是调整多线标签的最基本的?似乎字体大小和换行模式是最重要的,但没有可用选项的列表,很难说...
我在计算 a 的高度时遇到了一个非常奇怪的问题UITableViewCell。
似乎如果我实例化一个包含一些 HTML的NSAttributedStringwith NSData,则会在当前视图上强制执行一个布局循环,最终会tableView:heightForRowAtIndexPath:再次调用。而且,在此传递中要求所有其他行的高度。幸运的是,行高请求的内部循环中没有另一组递归调用。
这是堆栈跟踪:(注意第 0 帧和第 25 帧)
#0 0x0024422c in -[FeedVC tableView:heightForRowAtIndexPath:] at /Users/me/project/Classes/controllers/FeedVC.m:371
#1 0x024516cc in __66-[UISectionRowData refreshWithSection:tableView:tableViewRowData:]_block_invoke ()
#2 0x02450fd9 in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] ()
#3 0x02455e2f in -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] ()
#4 0x02455f40 in -[UITableViewRowData heightForTable] ()
#5 0x022c68c2 in -[UITableView _adjustExtraSeparators] ()
#6 0x022da6d3 in -[UITableView layoutSubviews] ()
#7 0x0225a964 in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#8 0x040d582b in -[NSObject performSelector:withObject:] ()
#9 0x01f7145a in -[CALayer layoutSublayers] ()
#10 …Run Code Online (Sandbox Code Playgroud) 我正在使用下一个代码将图像添加到UITextView:
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(200,200,140,140)];
textView.font = [UIFont systemFontOfSize:20.0f];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Test with emoji"];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:@"Angel.png"];
//for the padding inside the textView
textAttachment.image = [UIImage imageWithCGImage:textAttachment.image.CGImage scale:3.0 orientation:UIImageOrientationUp];
NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedString replaceCharactersInRange:NSMakeRange(5, 1) withAttributedString:attrStringWithImage];
[attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, attributedString.length)];
textView.attributedText = attributedString;
NSLog(@"Text view: %@", textView.attributedText);
[self.view addSubview:textView];
Run Code Online (Sandbox Code Playgroud)
结果如下:

我感兴趣的是,我怎么知道在文本字段和巫婆位置插入了什么图片?我正在考虑使用attributedText,因为你可以在代码中观察,因为它记录:
Text view: Test {
NSFont = "<UICTFont: 0x7ff0324f2110> font-family: \".HelveticaNeueInterface-Regular\"; font-weight: normal; font-style: …Run Code Online (Sandbox Code Playgroud) 我想保存我的UItextview'text的attributedString.我试图转换为字符串并保存.但是当我回到设置text'attributedString时,它不起作用.
这是我转换为String的方式:
var a = String(stringInterpolationSegment: text.attributedText)
Data.setValue(a, forKey: "font")
Data.managedObjectContext?.save(nil)
Run Code Online (Sandbox Code Playgroud)
这是我回到设置的方式:
text.attributedText = NSAttributedString(string: size)
Run Code Online (Sandbox Code Playgroud)
但是我的TextView只显示了AttributedSting
{
NSFont = "<UICTFont: 0x7fa9fa82aec0> font-family: \"Helvetica Neue\"; font-weight: normal; font-style: normal; font-size: 18.00pt";
NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0, HeaderLevel …Run Code Online (Sandbox Code Playgroud) 我想将 NSAttributedString 转换为 HTML 字符串。我一直在寻找如何解决它,但还没有结果。
知道我该怎么做吗?
所以,在我的 UILabel 子类的awakeFromNib 方法中,我有:
let termsArg = "Terms & Conditions"
self.linkText = termsArg
let exampleText = String(format:"By signing up you agree to our %@ and Privacy Policy", termsArg)
let underlinedAttributedString = NSMutableAttributedString(string: exampleText)
self.linkTextRange = (exampleText as NSString).range(of: termsArg)
let attributes = [NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle]
underlinedAttributedString.addAttributes(attributes, range: self.linkTextRange)
self.attributedText = underlinedAttributedString
Run Code Online (Sandbox Code Playgroud)
但是,我添加这些属性的行最终导致了严重崩溃,其中只有以下内容被吐出到控制台:
-[_SwiftValue _getValue:forType:]: 无法识别的选择器发送到实例 0x60c00005e510
我想知道出了什么问题,因为看起来我做对了一切。
iOS 15 中的新增功能,我们可以像这样形成 Swift AttributedString:
var att = AttributedString("Howdy")
att.font = UIFont(name:"Arial-BoldMT", size:15)
att.foregroundColor = UIColor(red:0.251, green:0.000, blue:0.502, alpha:1)
print(att)
Run Code Online (Sandbox Code Playgroud)
很酷,但是还有另一种方法。我们可以通过 AttributeContainer 来创建属性字典,将修饰符函数链接到 AttributeContainer 来形成字典,而不是连续的命令式属性设置:
let att2 = AttributedString("Howdy",
attributes: AttributeContainer()
.font(UIFont(name:"Arial-BoldMT", size:15)!)
.foregroundColor(UIColor(red:0.251, green:0.000, blue:0.502, alpha:1))
)
print(att2)
Run Code Online (Sandbox Code Playgroud)
(在现实生活中我会说.init()而不是AttributeContainer()。)
所以我的问题是,这在语法上是如何工作的?我们这里似乎有一个 DSL,我们可以在其中根据属性键的名称链接看起来像函数调用的内容。在幕后,似乎有一些动态成员查找的组合,callAsFunction也许还有某种中间构建器对象。我可以看到每个callAsFunction调用都返回 AttributeContainer,这显然是链接的工作原理。但是我们如何编写自己的对象,使其在语法上的行为方式与 AttributeContainer 的行为方式相同呢?
在针对 iOS 16.4 进行构建时,我们注意到在 NSAttributedString 上使用 benchmarkOffset 时存在不同的行为。
现在正值的处理方式与以前的 iOS 版本不同(不再需要 /2),但 StackOverflow 上已经有帖子讨论这一点。
我遇到的问题是使用负基线偏移时。当在 NSAttributedString 上使用时,它工作正常,但可以理解地增加了标签的大小。
当与 NSParagraphStyle 的maximumLineHeight 和minimumLineHeight 一起使用时,baselineOffset 的负值将被完全忽略。
我用这段代码来展示差异:
let label1 = UILabel()
let label2 = UILabel()
let label3 = UILabel()
self.view.addSubview(label1)
self.view.addSubview(label2)
self.view.addSubview(label3)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = 20
paragraphStyle.maximumLineHeight = 20
let attr1: [NSAttributedString.Key: Any] = [
.paragraphStyle: paragraphStyle,
.baselineOffset: 0]
let attr2: [NSAttributedString.Key: Any] = [
.paragraphStyle: paragraphStyle,
.baselineOffset: 5]
let attr3: [NSAttributedString.Key: Any] = [
.paragraphStyle: paragraphStyle,
.baselineOffset: -5]
let …Run Code Online (Sandbox Code Playgroud) ios ×9
swift ×4
objective-c ×2
uilabel ×2
uitextview ×2
core-data ×1
html ×1
ios15 ×1
nsstring ×1
string ×1
uifont ×1
uitableview ×1