记录练手时遇到的那些小坑
注: 其实所谓的坑,大都是我个人编码问题,不过还是记一下,以免下次再犯
坑001: UITabBarController
2016年7月7日下午12:30
第一次尝试写一个有5个 tabbar 的APP时,在 AppDelegate 类的首次加载方法中新建了一个 UITabBarController 对象作为 _window 的根控制器,随后在对应的5个控制器的 viewDidLoad 中分别设置 UITabBarItem。
问题
5个 tabbar 只有第一个显示出来了,其他4个都没有显示。
原因
UITabBarController 并没有一下子全部加载所有5个视图,所以另外四个VC的 viewDidLoad 也就没被调用。
解法
新建一个 UITabBarController 的子类作为 _window 的根控制器。在该子类的 viewDidLoad 里初始化5个VC,并分别设置各自的 tableBarItem。
参见
坑002 UITabBarItem
2016年7月7日下午12:38
我希望调整某个tabBarItem图片的大小,使用了 setImageInsets: 方法:
if (index == 2)
{
    [[navigationController tabBarItem] setImageInsets:UIEdgeInsetsMake(2, 2, -6, 2)];
}
问题
选中该项后,再次点击该项时,图片被拉伸,随着点击次数的增加,图片越变越大
原因
nil
解法
设置tabBarItem的UIEdgeInsets时,要确保top和bottom之和以及left和right之和都为0:
[[navigationController tabBarItem] setImageInsets:UIEdgeInsetsMake(4, 0, -4, 0)];
参见
坑003 UIUINavigationBar
2016年7月7日下午1:54
- 设置导航栏背景色不是
setBackgroundColor而是setBarTintColor - 设置导航栏标题色不是
setTintColor而是setTitleTextAttributes 
[[navigationController navigationBar] setBarTintColor:BG_COLOR];
[[navigationController navigationBar] setTitleTextAttributes:@{NSForegroundColorAttributeName:TITLE_COLOR}];
坑004 UIViewController title
2016年7月7日下午2:21
在初始化tabBarItem时指定了title为“首页”,之后希望设置每个VC的导航栏标题,我直接在各自的viewDidLoad中设置title:
// HomeViewController
[self setTitle:@"精选"];
问题
首页对应的tabBarItem的title也被修改成了“精选”。
原因
如果VC的title不为空,则会被tabBar优先选择为标题。
解法
不需要设置VC的title,而是直接指定VC的navigationItem的title:
// HomeViewController
[[self navigationItem]  setTitle:@"精选"];
坑005 UITableViewCell 重用
2016年7月19日下午7:37
一次调试过程中忽然发现每个cell后面忽然多出来几份拷贝:

初始时是正常的 ⬆️

刷新了一次后就变成了这样 ⬆️

连续刷新几次就很可怕了 ⬆️
原因
我的cell是这样写的:
@implementation PostTableViewCell
-(void)setupWithPostItem:(PostItem *)item
{
    _postCellVC = [[PostCellViewController alloc] initWithPostItem:item];   
    [self.contentView addSubview:_postCellVC.view];
}
@end
我在tableView:cellForRowAtIndexPath:方法中得到cell后都会调用其setupWithPostItem:方法。
而当刷新或滚动tabview时,会自动重用cell,上面代码的问题就在于每当重用cell时,其setupWithPostItem:方法都会向cell中添加一个subview。
这也说明,这些被重用的cell是真的直接就拿来用了。。。
解法
在setupWithPostItem:中清除现有的subview:
-(void)setupWithPostItem:(PostItem *)item
{
    if (_postCellVC)
    {
        [_postCellVC.view removeFromSuperview];
    }
    _postCellVC = [[PostCellViewController alloc] initWithPostItem:item];
    [self.contentView addSubview:_postCellVC.view];
}
自定义UIControl如何防止当其父视图添加了手势时tracking touch总是被cancel
答案
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return NO;
}