一周新知识点记录(15.10.19)
一.ipad——UIPopoverController
UIPopoverController继承自NSObject,因此不具备显示能力,它是通过其中的内容控制器显示的内容的。
UIPopoverController使用四部曲:
一、创建UIPopoverController的内容控制器
二、根据内容控制器初始化UIPopoverController对象
三、设置UIPopoverController对象的尺寸
四、显示UIPopoverController对象
显示UIPopoverController对象有两种方法:
方法一:通过点击UIBarButtonItem按钮显示
- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
参数说明:
item:触发显示的UIBarButtonItem对象
arrowDirections:显示的箭头方向
animated:是否展示过渡动画
方法二:对特定区域显示
- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
参数说明:
rect:箭头指向的区域
view:rect对应的视图
arrowDirections:显示箭头的方向
animated:是否展示过渡动画
注意:
1、UIPopoverController对象的尺寸不建议写死,应当根据内容控制器的需要来。ios7以前对内容控制器(UIViewController)的contentSizeForViewInPopover设值,ios7以后对内容控制器的preferredContentSize设值。
2、UIPopoverController对象显示出来的时候,默认任何其他控件都是不能交互的,点击UIPopoverController对象区域意外的部分,对象dismiss。若想UIPopoverController对象显示的时候能和某个控件交互,可以通过设置passthroughViews属性实现。它是一个数组对象,将需要交互的控件打包成数组复制给它即可。
二.二维码生成
ios7以后系统提供了CoreImage框架中生成二维码的滤镜方法。由C语言支持的第三方库libqrencode也是不错的选择。见Demo
三.显示模态窗口时的显示方式及过渡方式
//显示方式 vc.modalPresentationStyle = UIModalPresentationFullScreen; //过渡方式 vc.modalTransitionStyle = UIModalTransitionStylePartialCurl;
对于iphone而言,只考虑过渡方式。
对于ipad而言,两者都可考虑,显示方式比较常用的是UIModalPresentationFormSheet(占据中间一小块)
四.storyboard中巧用UITableView
可以直接在storyboard中设置tableView的头视图和尾视图,拖出tableView到IB后,然后拖出视图控件到tableView作为子视图(tableView在IB中只允许有两个子视图,头视图和尾视图,两个视图是连着的,头在上尾在下)。只适用与storyboard,xib不适用,习惯用storyboard的话能够大大提升开发效率。
另外可以直接在IB中对tableView设置代理和数据源。
五.高度自适应options参数怎么设置
NSStringDrawingTruncatesLastVisibleLine:
如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果没有指定NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略。
NSStringDrawingUsesLineFragmentOrigin:
绘制文本时使用 line fragement origin 而不是 baseline origin。
NSStringDrawingUsesFontLeading:
计算行高时使用行距。(译者注:字体大小+行间距=行距)
NSStringDrawingUsesDeviceMetrics:
计算布局时使用图元字形(而不是印刷字体)。
测试发现:
只使用NSStringDrawingUsesLineFragmentOrigin时,以宽度约束为依赖,即使计算出的高度超过设定的约束高度,最终还是返回计算出的高度,也就是忽略高度的约束。
使用NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine时,如果计算的高度超过约束的高度,最终返回的高度是可容纳最大行数的文本对应高度,比如约束的高度容纳得下2行,容不下3行,则返回的Size高度是2行对应的高度。
总结用法:
计算时options参数使用
NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading
另外计算单行文本也可以直接使用sizeWithAttributes
六.导航控制器的topViewController & visibleViewController
topViewController代表当前navigation栈中最上层的VC,而visibleViewController代表当前可见的VC,它可能是topViewController,也可能是当前topViewController present出来的VC。因此UINavigationController的这两个属性通常情况下是一样,但也有可能不同。
七.自定义日历的实现
日历主界面通过collectionView搭建,难点在于获取指定月的日历结构,包括这个月开头有几天是上个月的,末尾有几天是下个月的,将这些信息通过不同的字符标识保存到数组中,例如*表示上个月的date、#表示下个月的date,中间本月用1~天数标识,就能得到指定月的日历结构。
获取到这个存有指定月日历结构的数组是关键,有了它界面的搭建就有依据了。具体见Demo
值得一提的是,每个星期的第一天是星期日。因此如果日历7天为一行的话,默认最左边是星期日。如果想改为从左到右是星期一~星期日的结构,只要设置日历对象calendar的FirstWeekday属性值为2即可,(默认为1,从星期日开始)。
八.关于字符串的高度
一字符串,字体大小15,计算好了size,显示成两行,行间距设置成3,打印计算出的高度为38.79。
打印字体大小15的font对象的各个属性以及查看
leading*2 = 35.790000
lineHeight*2 = 35.790000
capHeight*2 = 21.420000
xHeight*2 = 15.510000
ascender*2 = 28.560000
descender*2 = -7.230000
lineSpacing = 3.000000(事先设置)
从数据可以看出:
(1)计算出的高度是以两行行高(lineHeight)和一行行间距(lineSpacing)组成的。
(2)ascender是文本基线到文本顶部的距离,descender是文本底部到基线的距离(是负的),行高(lineHeight = ascender - descender)
(3)xHeight和capHeight不重要,具体可以查网上的那张字形度量图,但是那张图个人认为有问题,与实际测试打印的数据不符。leading就是lineHeight。
另外经测试发现,对于设置了行间距了文本
一行文本计算高度结果 = 文本高度+行间距
两行文本计算高度结果 = 文本高度*2+行间距
三行文本计算高度结果 = 文本高度*3+行间距*2
四行....
如果未设置行间距的文本(文本默认行间距就是0),文本高度就是行高*行数