一. 点击uiscrollview
的子视图,即使不产生滑动,总是会走- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
测试发现:
- 如果是代码创建的
scrollview
,在scrollview
上面添加子视图button
,点击button
,不产生滑动,并不会走scrollViewDidEndDecelerating
- 如果是
xib
创建的scrollview
,点击button
,即使不产生任何滑动,总是会走scrollViewDidEndDecelerating
,即使添加的是其他子视图uiview
,也是一样。这种情况,只需要取消scrollview.pagesnable=yes
,就可以了。是不是xib多设置了什么东西,没搞明白。
二. xib自定义的控件,用纯代码加载,报错找不到xib控件拉好的IBOutlet属性
- 报错:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIView 0x12e80adb0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key searchBtn
- xib控件File`s Owner关联的类取消,改由view关联对应的类
- xib的属性全部重新拉线(由File`s Owner改为view关联,拉线的属性不改还是会报错)
- xib控件是作为另一个xib的子视图,不是由代码加载,不用改
三. scrollview滑动卡住,也不崩溃。
- (void)layoutSubviews不要做任何frame的更新,因为scrollview滑动会一直调用- (void)layoutSubviews,里面做frame更新,又会反过来调用- (void)layoutSubviews,就会一直卡在这个方法里
四.scrollview里面添加button或者其他控件,不能点击
- 是因为scrollview加了撑开的contentview,button又加载contentview上,contentview高度或者宽度显示不下button,导致点击传递事件到了contentview就找不到下层的button了。
- 层级关系: scrollview-> contentview->button,contentview的size装载不下button。传递事件断裂
五. tablefooterview的按钮不能点击
- 很多帖子讲是
tabletooterview``的高度不够,这其实是个很明显的问题,跟
上面第四条```道理一样。 - 但其实,我有次明显设置了
footerview
的高度,也看了层级关机,没有被遮挡。后来发现,原来是设置了渐变色的原因,因为渐变色是用layer去实现的,直接把渐变色layer加在button上,会遮挡button文字显示。所以写了个分类,渐变色layer加载一个bgview上,再把bgview加在button的最底层。这样就可以实现渐变色背景的按钮。但是!!!!我们点击的响应,也直接点击在bgview上,所以button接收不到响应链。解决办法,bgView.isUserInteractionEnabled = false
/或者self.colorView.userInteractionEnabled = NO
。部分代码如下:let gradientLayer = CAGradientLayer() gradientLayer.frame = self.bounds gradientLayer.colors = array gradientLayer.locations = [0.0,1.0] gradientLayer.startPoint = CGPoint.init(x: 0, y: 0.5) gradientLayer.endPoint = CGPoint.init(x: 1, y: 0.5) let bgView = UIView(frame: self.bounds) bgView.isUserInteractionEnabled = false //不设置这句,button的点击是点击在bgview上 self.addSubview(bgView) self.sendSubviewToBack(bgView) bgView.layer.addSublayer(gradientLayer)
五. tableview.tableFooterView和tableview.tableHeaderView的高度或者宽度有问题。
- tableview.tableFooterView要初始化frame
- tableview.tableFooterView不能直接=self.footerView,解决办法,先赋值一个view,再让view addsubview,如下:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 700)];
[view addSubview:self.footerView];
tableview.tableFooterView = view
- tableview.tableHeaderView同理
六.@property (getter=isActive) BOOL active,设置yes/no,不生效
- 我遇到的情景是,做聊天气泡时,xib上拉label的left和right约束,根据内容决定label的left或者right约束的active是yes还是no,从而决定label是靠左还是右。然后有时候会出现label左右位置混乱。解决:
- 拉lable的left或者right作为属性时,是weak修饰,改为strong就可以了(个人猜测,当active=no时,约束不生效的原因,其实就是移除了该约束,然而因为是weak修饰,当再次设置该约束active=yes时,其实该约束已经不存在了,所以更改strong修饰后,再次修改active=yes,还是能生效)。
七。更改状态栏颜色问题(-(UIStatusBarStyle)preferredStatusBarStyle
不调用问题)
- 在info.plist 中 View controller-based status bar appearance 一定要改为为 YES
-
navigationcontroller
中添加:- (UIViewController *)childViewControllerForStatusBarStyle { return self.topViewController; }
- 每个
Viewcontroller
中添加:-(UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleDarkContent; }
- 需要注意,如果有导航栏
navigationcontroller
,状态栏颜色由导航栏统一管理,事实上由导航栏管理也最好。如果需要单独改变某个状态栏,就单独在那个控制器实现preferredStatusBarStyle
八。使用UINavigationController,控制器self.view距离顶部的距离,一会高,一会低。
- 场景:从控制器A,进入控制器C,C的self.view是全屏,距离顶部是0。从控制器B,进入控制器C,C的self.view距离顶部有个一导航栏的高度。这就导致控制器C写这样的布局,也会变化:
[_headerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(0);
}];
- 原因:某一个控制器
A或者B
,有设置导航栏的背景颜色,设置背景颜色时候,有设置self.navigationController.navigationBar.translucent = NO
,这个属性,会影响UINavigationController的
rootviewcontroller```的布局。 - 解决:在哪个控制器设置过
self.navigationController.navigationBar.translucent = NO
,就在这个控制器viewWillDisappear
中,设置回来(self.navigationController.navigationBar.translucent = YES)
九。两个UICollectionView嵌套,都使用MJRefresh。滑动方向冲突
- 场景:UICollectionView
(A)
和UICollectionView(B)
。A
是横向滚动,每个cell是当前控制器的view
大小。B
是纵向滚动的瀑布流布局,加载A
的cell上。
这个时候在屏幕上斜方向滑动,会产生A
和B
同时一起斜方向滑动
。按照场景需求,应该是要么纵向滚动瀑布流,要么横向滚动页面。 - 原因:后来看了
MJRefresh
源码,大概是,他给UICollectionView
加了一个滑动手势,滑动时候,把scrollview
的contentInset
还是contentOffset
来着,把它的值改变,形成继承于scrollview
的视图也跟着手势滑动的效果。- 至于为什么一个
collectionview
不会斜方向滑动,两个嵌套就会斜方向滑动,就没有深入追究了
- 至于为什么一个
- 解决:
- 要么
A
和B
,只留一个使用MJRefresh
。上拉刷新下拉加载的功能也就只能添加在A
或者B
上。 - 要么就把
A
或者B
的mj_header
和mj_footer
给移除掉,其实产生的效果等同于上面。
- 要么
十.UITableView,用masnory布局约束,发现底部往下偏移了,也就是底部有部分显示不了
- 场景:
这个情况比较特殊,不具备普遍化,自己碰到过,记下来
。因为上面第九
条原因,所以自己在自定义TableView基类的时候,会用一个方法禁止掉MJRefresh
功能:self.mj_header?.scrollView?.bounces = false self.mj_footer?.scrollView?.bounces = false self.mj_header?.scrollView?.contentInset = .zero self.mj_footer?.scrollView?.contentInset = .zero self.mj_header?.endRefreshing() self.mj_footer?.endRefreshing() self.mj_footer?.removeFromSuperview() self.mj_header?.removeFromSuperview()
然而,在不需要刷新功能的界面,为了防止出现布局混乱,调用了上面这个方法,结果就出现tableview
底部,被屏幕遮住了。而检查约束条件make.edges.equalToSuperview()
,这完全没问题。
- 原因:打开层级显示,定位
TableView
,发现这段话:
baseClass = UITableView; frame = (0 64; 375 603); clipsToBounds = YES;
contentOffset: {0, 198}; contentSize: {375, 845}; adjustedContentInset: {0, 0, -44, 0};
contentOffset: {0, 198}
,这说明tableview无缘无故往下移动了198
。这是什么原因?
- 解决:无意中,注释掉上面说的基类tableview中的禁止
MJRefresh
功能方法中的,两行代码,解决了!而且层级定位发现contentOffset: {0, 0}
就是注释了这两行代码 //self.mj_header?.scrollView?.contentInset = .zero //self.mj_footer?.scrollView?.contentInset = .zero
- 思考:为什么,
MJRefresh
中的mj_header/mj_footer
,禁止scrollView?.contentInset
,会导致UITableView的contentOffset: {0, 198}
,MJRefresh做了什么? - 探究:
- 原来
self.mj_header?.scrollView?
等于self.mj_header?.superView
等于self(tableView)
- 然而,断点打印如下:
(lldb) po self.mj_header?.scrollView?.contentInset ▿ Optional<UIEdgeInsets> ▿ some : UIEdgeInsets - top : 0.0 - left : 0.0 - bottom : 44.0 - right : 0.0
- 所以,注释掉那两行代码,就是让
tableview.contenInset
,由系统建立的距离底部的值bottom=44(正常显示)
变成bottom=0(被遮挡一部分)
,可不就是遮挡了嘛
- 原来
- 最后:至于为什么不注释那两行,
contentOffset: {0, 0}
,注释掉就变成contentOffset: {0, 198}
。有待考证
网友评论