TextKit之便笺实战

便笺练习功能点:

通过实现以下特效,练习并掌握布局管理器(layout manger),文本容器(text containers)和文本存储器(text storage)等用法。

  • 动态样式(Dynamic type)
  • 凸版印刷效果(Letterpress effects)
  • 环绕路径(Exclusion paths)
  • 动态文本格式及存储(Dynamic text formatting and storage)

这个应用中我们将实现回流文本,字体大小的动态变换,以及闪回文本等效果。 效果图:
image
App开始运行后自动生成一组便笺实例并利用tableViewController显示出来。Storyboardssegues会将被选中的单元格所对应的便笺内容显示出来以供用户编辑。 项目开发包:Notepad.zip

动态样式

动态样式(Dynamic type)是iOS 7里面变化最大的特性之一; 它使得app可以遵从用户选择的字体大小和粗细。 选择 通用->文字大小通用->辅助功能 来查看app中的字体设置。

image
iOS 7 支持通过粗体设置字体大小等方式提高支持动态文本的应用的易读性。 例如**UIFont**新增的一个方法: preferredFontForTextStyle 用来根据用户对字体大小的设置来自动制定字体样式。
下面表格中是六种可用字体样式的示例:
image
最左边一列是最小字体;中间一列是最大字体;最右边一列是粗体效果。

使用系统动态字体样式

使用动态文本,是通过给文本字体设置字体样式style而不是指定具体的字体名称大小。这样,系统会在运行时自动根据这一样式以及用户的字体大小设置来选择使用合适的字体。

preferredFontForTextStyle:方法设置字体样式

  1. 打开 NoteEditorViewController.m/swiftviewDidLoad:方法实现的最后面加入以下代码: {%codeblock lang:objc%} self.textView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; {%endcodeblock%} {% codeblock lang:swift %} self.textView.font = UIFont.preferredFont(forTextStyle: .body) {% endcodeblock %}
  2. 打开 NotesListViewController.m/swifttableView:cellForRowAtIndexPath: 方法中增加如下代码: {%codeblock lang:objc%} cell.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; {%endcodeblock%} {% codeblock lang:swift %} cell.textLabel?.font = UIFont.preferredFont(forTextStyle: .headline) {% endcodeblock %} 上面两行代码都用到了新版iOS的字体样式.

字体样式:通过语义法命名字体,例如 UIFontTextStyleSubHeadline, 可以避免在代码里每一处都指定具体的字体名称和样式, 而且确保app能对用户的字体大小设置做出恰当的回应。

APP响应用户字体设置

  1. 设置系统字体 返回到通用->文字大小重新修改字体设置. 再运行App, Note页面的文字大小是当前设定的字体大小;前后截屏对比,分辨率小了一半。
    image
  2. 设置系统字体生效 当我们返回到通用->文字大小重新修改字体设置. 再打开Note页面, 会发现app并没有立即对字体设置的变化做出相应反应。
监听系统通知:实现APP响应用户字体设置

当用户修改了他们的字体大小设置之后,这一样式对应的字体并不会自动更新,必须重新请求才能获取新的值。用户设置变化后,preferredFontForTextStyle:方法返回的字体也会变化。

  1. 添加监听系统通知UIContentSizeCategoryDidChangeNotification通知APP响应用户字体设置的变化 打开 NoteEditorViewController.m 并在 viewDidLoad 方法的实现的最后加入以下代码: {%codeblock lang:objc%} [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; {%endcodeblock%} {%codeblock lang:swift%} //字体变化通知:调用preferredContentSizeChanged:方法 NotificationCenter.default.addObserver(self, selector: #selector(NoteEditorViewController.preferredContentSizeChanged(_:)), name: NSNotification.Name.UIContentSizeCategoryDidChange, object: nil) {%endcodeblock%}
  2. 添加系统通知响应事件 收到用于指定本类接收字体设定变化的通知后,调用preferredContentSizeChanged:方法 在NoteEditorViewController.mviewDidLoad方法之后紧接着添加以下方法: {%codeblock lang:objc%}
  • (void)preferredContentSizeChanged:(NSNotification *)notification { self.textView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; } {%endcodeblock%} {%codeblock lang:swift %} //字体变化通知时调用 func preferredContentSizeChanged(_ notification:NSNotification) { self.textView.font = UIFont.preferredFont(forTextStyle: .body) } {%endcodeblock%} 这一方法作用是根据新的字体设置来设定textView中的字体。
    Build并运行app,修改字体大小设置,Note页面就可以即时更新字体大小了。

iOS Document Interaction 编程指南

关于 Document Interaction

iOS支持在你的app中通过调用其他app来预览和显示文档。iOS还支持文件关联,允许其他app调用你的app打开文件。这些技术包括了UIKit中提供的UIDocumentInteractionController类,以及Quick Look框架。

  • ######预览文档和呈现选项菜单
    如果app需要打开自身并不支持的文件时,就需要使用UIDocumentInteractionController。一个document interaction controller通过Quick Look框架判断文档是否能被另一个app打开和预览。也就是说,app可以通过documentinteraction controller提供一些支持打开该文件方式的菜单。

具体实现需要以下步骤:

    • 需要通过其他APP打开的文件,来实例化UIDocumentInteractionController实例对象。
    • 在自己的APP UI中提供一个代表这种文件的图像标(一般显示文件名或者图标)。
    • 用户交互,如触摸这个控件,则调用documentinteractioncontroller对象。

三种交互界面: 1. 预览文件的内容。 2. 一个包含预览和打开操作的菜单。可以通过实现某些委托方法,向菜单中加入其他操作,比如复制、打印。 3. 一个菜单,仅包含“以其它方式打开”操作。

同时,documentinteractioncontroller内置了一些手势,必要时可以直接实现它们。

  • ######使用documentinteractioncontroller的场景:与文件交互的app都可以使用。

    • 需要从网络下载文件的APP:
      例如,email程序需要打开和预览邮件附件。
    • 不下载文件的APP:
      例如,APP需要支持文件共享(参考“File-Sharing Support” in iOS Technology Overview), 即可以对同步到app Documents/Shared目录下的文件使用documentinteractioncontroller

instrument之Zombie工具

Zombie:针对僵尸对象导致应用程序崩溃,即已经deallocated的对象,它们的retainCount计数器已经为0,通过正常的手段是无法在debug中跟踪和观察到的。

如果你开启了 Zombie Enabled ,则当 Zombie 问题出现时,控制台会输出 Zombie 对象的地址,且程序会在此处产生断点:

 -[CALayer retainCount]: message sent to deallocated instance <memoryaddress>

UIDevice类介绍

UIDevice.h

1
2
3
4
5
6
7
8
9
+ (UIDevice *)currentDevice; 		  // 获取当前设备

NSString    *name;               	  // e.g. "My iPhone"  
NSString    *model;              	  // e.g. @"iPhone", @"iPod touch"  
NSString    *localizedModel;     	  // localized version of model  
NSString    *systemName;     		  // e.g. @"iOS"  
NSString    *systemVersion;   	  // e.g. @"4.0"  
UIDeviceOrientation orientation;    //除非正在生成设备方向的通知,否则返回UIDeviceOrientationUnknown  
NSUUID *identifierForVendor         //可用于唯一标识该设备,同一供应商不同应用具有相同的UUID
1
2
3
4
5
6
7
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,                    // 竖向,头向上
    UIDeviceOrientationPortraitUpsideDown,  		// 竖向,头向下
    UIDeviceOrientationLandscapeLeft,         		// 横向,头向左
    UIDeviceOrientationLandscapeRight,       		// 横向,头向右
    UIDeviceOrientationFaceUp,                  	// 平放,屏幕朝下
    UIDeviceOrientationFaceDown                	 // 平放,屏幕朝下

//使用内置的宏定义的函数,根据orientation判断设备方向,返回值类型BOOL.
{%codeblock lang:java 纵向宏定义,返回YES:纵向%} #define UIDeviceOrientationIsPortrait(orientation) ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown) {%endcodeblock %} {%codeblock lang:java 横向宏定义,返回YES:横向%} #define UIDeviceOrientationIsLandscape(orientation) ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight) {%endcodeblock%}

IOS7新宠TextKit

Text Kit

Text Kit:是个庞大的framework,继承了Core Text的全部功能,构建了快速、先进的文本排版和渲染引擎,更让开发者们高兴的是,设计者把它封装在了一个面向对象的API中。并且与UIKit框架很好的集成,它让程序能够通过NSTextStorage对象存储文本排版和显示文本等主要信息,并支持排版所需要的所有特性,包括字距调整、连写、换行和对齐等。

更直观的理解,UITextViewUITextFieldUILabel等UIKit控件都已经基于Text Kit重新构建,是为UIKit框架提供高质量排版服务而扩展的一些类和协议.
例如:NSTextStorage对象,它本身是NSMutableAttributedString的子类,支持分批编辑,这就意味着在改变一个范围内的字符样式时,不用整体替换文本内容,就能完成排版效果。其中支持分页文本、文本包装、富文本编辑、交互式文本着色、文本折叠和自定义截取等特性。

IOS6之前,想实现一些丰富的文本排版,例如在textView中显示不同样式的文本,或者图片和文字混排等,就需要借助于UIWebView或者深入研究一下Core Text。后来iOS6,增加一个很棒的属性:NSAttributedString,主要用于支持UILabel、UITextField、UITextView等UIKit控件自主排版的功能。很显然,IOS7并没有满足于这一改进,同时推出一款功能更为齐全,易用的Text Kit新宠。
在iOS 6中, 用于文本的UIKit控件是基于WebKit和Core Graphics的字符串绘制方法来实现的。如下面层级体系图所示:
iOS 7的整体构架要更清晰,所有基于文本的UIKit控件(除了UIWebView)现在都可以使用Text Kit,如下图所示:

IOS7的变革

性能提高以及被遗弃的功能 新增截屏通知:UIApplicationUserDidTakeScreenshotNotification 在IOS 7

在IOS中像SnapChat一样监控screenshots

A number of Stack Overflowquestions were having issues with this, so I figured I’d explain. From reverse engineering, this is the exact method used by SnapChat, but it’s also pretty much what I’d have done myself. The process is pretty simple, and relies on a quirk of iOS: taking a screenshot cancels all touches on the screen. Because of that, anything that you

IOS7截屏问题

iOS 7截图最新变化: 不再影响用户其他操作 在 iOS 7 中,截图动作已经发生了变化,就如苹果在版本说明中描述的那样:用户截图时,有效点击不会再失效了。这

+++ title = “验证ob绘图工具结合双向链接嵌套和Hugo的兼容性” description = “ob中有很不错的插件,可以实现沉浸式编