美文网首页
iOS 笔记

iOS 笔记

作者: 突刺刺 | 来源:发表于2021-02-21 15:06 被阅读0次

    一. 点击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,这个属性,会影响UINavigationControllerrootviewcontroller```的布局。
    • 解决:在哪个控制器设置过self.navigationController.navigationBar.translucent = NO,就在这个控制器viewWillDisappear中,设置回来(self.navigationController.navigationBar.translucent = YES)

    九。两个UICollectionView嵌套,都使用MJRefresh。滑动方向冲突

    • 场景:UICollectionView(A)和UICollectionView(B)A是横向滚动,每个cell是当前控制器的view大小。B是纵向滚动的瀑布流布局,加载A的cell上。
      这个时候在屏幕上斜方向滑动,会产生AB同时一起斜方向滑动。按照场景需求,应该是要么纵向滚动瀑布流,要么横向滚动页面。
    • 原因:后来看了MJRefresh源码,大概是,他给UICollectionView加了一个滑动手势,滑动时候,把scrollviewcontentInset还是contentOffset来着,把它的值改变,形成继承于scrollview的视图也跟着手势滑动的效果。
      • 至于为什么一个collectionview不会斜方向滑动,两个嵌套就会斜方向滑动,就没有深入追究了
    • 解决:
      • 要么AB,只留一个使用MJRefresh。上拉刷新下拉加载的功能也就只能添加在A或者B上。
      • 要么就把A或者Bmj_headermj_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}。有待考证

    相关文章

      网友评论

          本文标题:iOS 笔记

          本文链接:https://www.haomeiwen.com/subject/pprqfltx.html