常见问题(二)
1.collectionview 无法往下拉
<1> 和 UITableView 对象不同,UICollectionView 对象在单元格个数合适的时候,会自动缩短表格的contentsize.导致单元格较少的时候,无法向下滚动.
<2> 回到UICollectionView的父类UIScrollView,将UICollectionView对象的alwaysBounceVertical的属性设置为 YES 即可解决下拉问题.
2.定时器后台运行
<1> 方式一: 以背景音乐的方式开启定时器,参考http://www.cnblogs.com/zzltjnh/archive/2013/05/15/3080058.html.
<2> 方式二: 记录当前界面失去焦点时的时间[NSDate date],再次获得焦点时,记录经历的时间间隔[[NSDate date] timeIntervalSinceDate:goBackgroundDate];
<1> Info.plist中 Status bar is initially hidden 设置为 NO 不可以解决问题,同时需要把View controller-based status bar appearance设置为 NO;
<2> 但为了在闪屏页时,不显示状态栏,就得设置成 YES, 在 AppDelegate 中显示即可[[UIApplication sharedApplication] setStatusBarHidden:YES];
<3> 但问题又来了,在 iOS 8 上好像不生效,卸载 app 并重启手机安装后,状态栏变成白条了(需求是导航栏也隐藏),stackoverflow 上点赞比较多的方式是,使用UIApplication对象的setStatusBarHidden:withAnimation:即可解决.
4.改变状态栏颜色
<1> 不能把特殊的顶部视图放在当前控制器的 self.view 上,肯定不合适.
①一方面是因为当前控制器 self.view 一般被加在导航栏下面,加在其顶部肯定看不见.
②另一方面是因为,若导航栏隐藏, 当前控制器 self.view ( 如 tableview )如果需要往下滑,顶部就看不见了.
<2> 因此要加在根控制器的 view 上,不会根据当前控制器视图的改变 frame 而改变 frame.
<3> 代码如下:
1 UIWindow *keyWindow = ((AppDelegate *)[UIApplication sharedApplication].delegate).window; 2 UIViewController *vc = keyWindow.rootViewController; 3 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, vc.view.frame.size.width, 20)]; 4 view.backgroundColor = [UIColor blueColor]; 5 [vc.view addSubview:view];
5.iOS 7 横竖屏切换 [[UIScreen mainScreen] bounds].size.width 不变.
<1> 判断 iOS7 是否是横竖屏,可以使用([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait)判断代替那个方法.
6.判断日期是否是今天
1 - (BOOL)isOpenRedPacket{ 2 BOOL isOpen = YES; 3 NSDateFormatter *formater = [NSDateFormatter new]; 4 formater.dateFormat = @"YYYY/MM/dd"; 5 NSString *dateNow = [formater stringFromDate:[NSDate date]]; 6 NSString *lastDate = [[PTVConfig instance] closeRedPacketDate]; 7 if ([dateNow isEqualToString:lastDate]) { 8 isOpen = NO; 9 } 10 return isOpen; 11 }
7.view 的大小是600 * 600,而设置的是和 self.view.bounds 一样
<1> 有时,从一个控制器跳转到另一个控制器时,控制器的 view 还没创建好, frame 就是默认值,而不是屏幕的大小,因此不要以为self.view.bounds是万能的.
<2> 可以设置视图的 frame 为常量值来解决此问题.
8.当前视图销毁时,关联视图没有销毁
<1> 常规做法是,把当前视图改为关联视图的父视图,可是这样改有可能影响产品的其他需求....
<2> 换种做法,就是从解决 bug 的角度入手,不影响代码逻辑,在当前视图移除的时候,也移除其关联视图.
9.给视图添加手势,不仅响应了其自身的事件,还会响应其子视图中的按钮事件.
10.注释代码/固定参数 是一种很不错的找 bug 方法.
<1> 对于产生 bug 的可疑代码,可以先把所有的问题代码都注释掉,或者把可变的参数设置为固定的参数,直到 bug 不会出现为止.找到成就感....
<2> 然后慢慢回滚刚刚修改的代码,直到重新复现 bug 为止.
11.后台切换 tabbarcontroller 时,和手动切换tabbarcontroller的效果不一样.
<1> 很离奇的 bug, 在退出直播间时,提前切换底部 tab,结果 tab 没执行某些代码...
<2> 仔细研究,才发现在UITabBarController在 A tab页面播放全屏事件,用代码默默在后台切到 B tab页时,不会触发 B 控制器的viewdidappear 方法.很搞笑....
12.无法拖动一个 xib 视图到另一个 xib 视图中
<1> 想在 A xib 中,导入一个B view, 而且B view 是通过 B xib 加载的,通过在 A xib 中添加一个 view, 然后把改 view 的类型改为 B view 的类型,是无法加载 B xib 的.....这里调用的只是 B view 的 init 方法.
<2> 方法一:可以在 A xib 中添加一个 D view, 然后拖到 A xib 对应的视图 A view 中,然后在 A view 中的 awakefromnib 等方法中,创建 B xib 对应的view, 并添加到 A view 的子视图 D view 中.
<3> 方法二:
(1) 在一个控制器的 storyboard 中插入视图,将该视图的类改为 A 类
( 此时系统在加载 A 类的时候,就会调用 A 类的initWithCoder:方法,调用 A 类的awakeFromNib方法,但系统不知道 A 类与哪个 xib 有关联)
(2) 在 A xib 中添加一个 view, 并拖控件构造B xib, 同时将 view 的类设置为 B类,并将 A 的 file's owner 改为 A 类. 运行,发现没有任何内容.
(3) 接着在initWithCoder:方法中,loadNibNamed:owner:options:创建 A 视图,并添加到当前 A 类的对象中.就会加载 A xib 里面的内容.
(千万不要把 A xib 中的 最外层view 指向 A 类,这样会造成崩溃,正确的做法是:
①清空最外层 view 的类,将 file's owner 的类设置成 A 类...
②loadNibNamed:owner:options:第二个参数内容为self, 也就是 A 类的对象...)
(4) 运行发现 B xib 的内容没有展示,但是 B对象 的initWithCoder:方法却被执行了....若不执行第(3)步的加载 A xib,运行则会看到 B xib的内容没有显示,而且 B 类的initWithCoder:方法也没有被执行.
(5) 在 B 类的initWithCoder:方法调用loadNibNamed:owner:options:方法,创建 B xib,并添加到当前 B 类的对象中. 代码如下:
1 // A.m 2 - (instancetype)initWithCoder:(NSCoder *)aDecoder{ 3 if (self = [super initWithCoder:aDecoder]) { 4 UIView *a = [[[NSBundle mainBundle] loadNibNamed:@"A" owner:nil options:nil] firstObject]; 5 a.frame = CGRectMake(100, 100, 200, 200); 6 [self addSubview:a]; 7 } 8 return self; 9 } 10 11 // B.m 12 - (instancetype)initWithCoder:(NSCoder *)aDecoder{ 13 if (self = [super initWithCoder:aDecoder]) { 14 UIView *b = [[[NSBundle mainBundle] loadNibNamed:@"B" owner:nil options:nil] firstObject]; 15 b.frame = CGRectMake(0, 0, 100, 100); 16 [self addSubview:b]; 17 } 18 return self; 19 }