TextKit简介
在iOS7之前我们要实现图文混排要使用CoreText,iOS6时有了Attribute string 可以解决一些简单的富文本需求。直到iOS7 苹果推出了TextKit,TextKit是基于CoreText的并且做了面向对象的封装,这也决定了TextKit的易用性。
NSAttributeString示例
let label = UILabel(frame: CGRectMake(0, 20, view.bounds.size.width, 100)) let labelString = "¥2000 元/位" let attributeString = NSMutableAttributedString(string: labelString) let attributes = [ NSForegroundColorAttributeName : UIColor.redColor(), NSFontAttributeName : UIFont.systemFontOfSize(36) ] attributeString.addAttributes(attributes, range: NSRange(location: 0, length: 5)) label.attributedText = attributeString view.addSubview(label)
上面个例子主要使用addAttributes/addAttribute来实现富文本的效果,一些常用的键:
- NSForegroundColorAttributeName:(UIcolor)文字颜色。
- NSFontAttributeName:(UIFont)文字字体。
- NSBackgroundColorAttributeName:(UIColor)背景色。
- NSKernAttributeName:(NSNumber(float))字符之间的间距。
- NSStrikethroughStyleAttributeName:(NSNumber(integer))删除线,值为宽度。
- NSStrikethroughColorAttributeName:(UIColor)删除线颜色。
- NSUnderlineStyleAttributeName:(NSNumber(integer))下划线,值为宽度。
- NSShadowAttributeName:(NSShadow)阴影。
- NSObliquenessAttributeName:(NSNumber(float))倾斜。
- NSAttachmentAttributeName:(NSTextAttachment)图文混排。
- NSParagraphStyleAttributeName:(NSParagraphStyle)段落样式。
Dynamic Type(动态文本)
Dynamic Type是iOS7中给我们的开发带来变化最多的特性之一,它的作用是让应用中的字体大小遵循你设置的字体大小和粗细,这会更加增强可读性和用户体验。
为了让自己的应用支持Dynamic Type需要设置文本支持某一个风格而不是指定具体的字体,方法是:UIFont.preferredFontForTextStyle(样式)。
这个方法会根据你设置的样式和用户设置的字体大小来返回一个字体。
注意:在iOS8中Tableview的cell如果没有自定义,那么无需设置动态文本 它是已经封装好的,并且在切出程序进入设置调整字体大小后再切回 也会即可做出字体改变。但是在iOS7中或自定义cell时需要手动设置动态文本。
cell.textLabel?.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline) textView.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
但是现在还有一个问题,如果是iOS7环境只需要设置这些是不够的,需要监听通知 这样在切出应用设置字体后才能及时作出改变。
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NoteListController.preferredContentSizeDidChange(_:)), name: UIContentSizeCategoryDidChangeNotification, object: nil) } // 刷新tableview数据 func preferredContentSizeDidChange(notification: NSNotification) { tableView.reloadData() }
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NoteContentController.preferredContentSizeDidChange(_:)), name: UIContentSizeCategoryDidChangeNotification, object: nil) textView.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) } // 设置textview的font func preferredContentSizeDidChange(notification: NSNotification) { textView.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) }
设置好后是这样的效果
创建环绕路径
先来看下效果:
可以看出textview的文字避开了时间视图,下面来看下代码:
// 首先创建timeview 添加到textview上 let date = TimeView(date: NSDate()) textView.addSubview(date) self.timeView = date // 重写viewDidLayoutSubviews 在controller布局子视图的时候更新timeview的size 然后设置frame 最后指定环绕路径 override func viewDidLayoutSubviews() { timeView.updateSize() timeView.frame = CGRectOffset(timeView.frame, textView.frame.width - timeView.frame.width, 0) // 注意 指定的环绕路径是数组 这证明textview可以指定多个环绕路径 类型为[UIBezierPath] curvePathWithOrigin方法是通过一个CGPoint返回一个UIBezierPath 这个路径就是圆形的路径 textView.textContainer.exclusionPaths = [timeView.curvePathWithOrigin(timeView.center)] }