这是我最近工作中遇到的问题,做一个简单的记录。
设置导航栏透明
项目中有一个界面的导航栏是透明的,效果如下:
我首先想到的是:
1 | self.navigationController.navigationBar.barTintColor = [UIColor clearColor]; |
但是设置了没有效果,然后又是一顿Google,找到了如下的解决方案:
1 | // 设置导航栏背景图为一个透明的空图片 |
设置UIPageControl左对齐
UIPageControl默认是居中对齐的,要设置它左对齐,需要进行在布局是,根据UIPageControl点的个数,计算UIPageControl的中心点X的坐标。代码如下:
1 | - (void)layoutSubviews { |
效果如下:
设置UILabel的内边距
项目中要实现如下的一个标签(不可点击):
一种方案是直接使用UIButton来实现,因为UIButton有titleEdgeInsets属性,可以设置文字的内边距,我这里尝试使用了UILabel来实现,UILabel默认是不可以设置内边距的,但是可以通过自定义Label来实现,实现代码如下:
1 |
|
这样,LMRPaddingLabel就会有2个点的内边距,相关问题可参考:ios add left padding to uilabel
长按手势默认会触发两次
给一个View添加了一个UILongPressGestureRecognizer,长按这个View,默认会触发两次,一次是经过了minimumPressDuration长的时间,另一次是手指离开时,可以通过手势的state属性来区分,代码如下:
1 | - (void)handleLongPress:(UILongPressGestureRecognizer*)sender { |
相关问题可参考:UILongPressGestureRecognizer gets called twice when pressing down
使用RAC绑定可重用的Cell
一般来讲,我们会为每一个复杂View创建一个对应的ViewModel,然后使用RAC(ReactiveCocoa)对View与ViewModel进行绑定(Binding),View与ViewModel之间始终是一一对应的,但是在UITableview中就有问题了,由于UITableviewCell的重用机制,实际创建的Cell个数要少于对应的ViewModel的数量,这样如果还是使用RAC进行简单的数据绑定的话,就会出现重复绑定的问题。
解决方案就是在Cell发生重用后,解除Cell与之前的ViewModel的绑定,然后把Cell与新的ViewModel进行绑定。RAC中有一个方法takeUntil
可以实现在指定信号发出前,一直订阅某一信号,一旦指定信号发出,就不再订阅某一信号,就相当于接触绑定。
实例代码如下:
1 |
|
这里信号rac_prepareForReuseSignal即为Cell发生重用时发出的信号。
相关问题可参考:Example of Reactive Cocoa binding for a reusable cell.
使用NSURLSession发送同步请求
最近项目中用到了同步请求,使用NSURLConnection发送同步请求非常简单,直接调用NSURLConnection的类方法+sendSynchronousRequest:
就可以了,不过由于苹果官方不建议使用NSURLConnection,而NSURLSession又没有直接的同步请求的方法,所以就查了一下如何使用NSURLSession发送同步请求,结果如下,可以使用下面的方法发送同步请求:
1 |
|
这里使用的GCD的信号量做同步,使用时直接调用NSURLSession的这个分类的方法即可实现同步请求。
iOS7上自动布局的坑:Assertion failure in -[UITableView layoutSublayersOfLayer:]的错误
最近在开发中遇到了“Assertion failure in -[UITableView layoutSublayersOfLayer:]”错误,而且只在iOS7上出现,iOS8及以上都是正常了,于是一阵Google,发现原来这个iOS7上自动布局的一个坑,造成这个错误主要有两个原因:
- 在添加UITableviewCell的子视图时,加在了Cell上而不是加在Cell的ContentView上,并且使用自动布局来布局
- 给UITableview添加了子视图,并且使用自动布局来布局,即
[tableView addSubview:someView]
对于第一个问题比较好解决,一般Cell的子视图都是加在Cell的ContentView上的,如果有那个视图没有加在ContentView上,改过来就可以了,只不过找起来可能比较麻烦。
第二个问题就比较麻烦了,有时候我们确实需要给UITableview上加一个子视图,例如,加一个ErrorView或LoadingView等,这是如果使用自动布局设置了这个子视图与Tableview之间的约束,就会出现这个错误。解决方法就是不要使用自动布局,改用Frame的方法去设置子视图的位置,这样就不会报错了。针对iSO7专门做一下适配,如果大于iOS7可以继续使用自动布局。
因为自动布局是在iOS6上才出现的,所以iOS6,包括iOS7上的自动布局都不是很成熟,有很多坑,这就需要我们不多的总结,才能避免再次掉进坑里。
Masonry不能用来更新XIB上设置的约束
使用XIB加载的视图,如果在XIB上设置了自动布局的约束,在代码中想更新约束,是不能使用Masonry的mas_updateConstraints方法来更新约束的。解决方法就是把要更新的约束通过IBOutlet连接到代码中,然后在代码里更新这个约束,不过这个方法比较麻烦,暂时还没有找到其他更好的方法。