iOS7中UILabel高度调整注意事项

我的“记词助手”在升级到iOS7之后,一直出现UILabel错位的问题:

ios7label

我的label是用- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode 来计算的,但是似乎计算得不是很正确。

实际上UILabel的frame是红框的大小,但是在宽度不够的时候,不知道触发了什么bug,这个Label在绘制的时候文字会被挤下去。这个问题到底是什么,我也没搞清楚,但是增加UILabel的宽度后,就会显示正常。

在跟了一遍代码后发现,在iOS7下面,- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode这个函数返回的值是带小数的,设给UILabel的frame之后,UILabel的宽度就小于文字绘制需要的宽度了。就会造成上面的问题。

在官方文档里可以看到,- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode这个函数在iOS7里面已经deprecated了,取而代之的是boundingRectWithSize:options:attributes:context:这个函数。实际上这两个函数在iOS7里面的计算结果是一致的,都是带小数的。boundingRectWithSize:options:attributes:context:的文档中可以看到这么一句话:

This method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.

也就是说,计算出的size需要用ceil函数取整。

在iOS7中,正确地计算UILabel可能占有的高度需要如下的步骤:

iOS 6(及以下版本)的Navigation手势pop

iOS 7 里面的UINavigationController里面新增了一个interactiveGestureRecognizer。如果不自定义leftBarButton的话,它会自动生效,如果自定义leftBarButton的话,就要麻烦一点,自己弄一个delegate,不过需要很小心,因为我已经碰到了好几个bug related to interactiveGestureRecognizer。比如多个NavigationController一起使用的话会出现界面死锁,push没完成的适合划一下,会导致navigation bar错乱等等。

Anyway,现在讲一下怎么在iOS6上面实现这个效果。原始代码我在https://gist.github.com/siqin/7579845 找到的,不过这串代码有点问题,我改了改。

原理是障眼法——这个方法在很多控件里面都用到了——自定义UINavigationController,在它的view下方插一个UIImageView。在UINavigationController push的时候,对当前屏幕生成一个snapshot,保存到自己设定的snapshot栈里面去。那个UIImageView里面显示栈顶图片。UINavigationController本身的View增加一个pan gesture recogniser。在手指滑动的时候,把UINavigationController.view进行位移,露出后面的UIImageView,这样就出现滑动效果了。等滑到底或者滑到预设的pop阈值后松手时,在动画完成后,马上执行对navigationController.view的frame的重设,并且pop without animation。这一系列的障眼法看上去就跟真的似的。

完整代码: https://gist.github.com/hikui/8160076

iOS 7 下UITextView的bug一枚

这个问题是早上蚊子发给我的。我说iOS7发布之后蚊子找出了一大堆系统的bug,不去苹果可惜了。

描述是这样的,往一个UITextView中不断地输入文字,不断地换行,换到最底下的时候,光标就跑到TextView的frame外面去了。因为没有什么特殊的操作,可以认为是iOS7的bug。

通过stackoverflow找到了暂时的解决办法(只能说是一种很复杂的hack)

原帖:http://stackoverflow.com/questions/18966675/uitextview-in-ios7-clips-the-last-line-of-text-string

iOS-Universal-Framework使用的注意事项

iOS-Universal-Framework是一个非常好的制作iOS通用framework的模板。所谓通用指的是它会生成一个Framework包含i386和arm架构。其中i386专门用于模拟器调试。

不过呢,这个模板并不是拿来就能用的,它还依赖于你的工程设置。readme里面讲了一部分,但是有一个关键的地方作者没有讲到。导致我一开始总是只能搞出一种架构来。看了github里面的issues,发现很多人也碰到这个问题不知道怎么解决。

其实要是读一下它生成的Run Script的话,就知道是怎么回事了。看一下脚本的输出也能知道是怎么回事,可惜我一开始才疏学浅不知道从哪里看run script的脚本输出。这里提一下:

屏幕快照 2013-09-02 下午11.59.45 屏幕快照 2013-09-03 上午12.00.05

 

按照xcode 4.6,以static framework为模板新建一个的话,在它的building settings中可以看到“Build Active Architecture Only”是Yes。如果不改的话,编译脚本只会编译出一种架构来。所以需要设置成No。很惭愧我也是自己学写run script之后,知道看脚本输出了,才看到那么大一句话“ONLY_ACTIVE_PLATFORM=YES: Skipping other platform build”。

这个很关键的部分,作者并没有在readme里面提到过,所以导致很多人不知道怎么搞。