美文网首页iOS开发文集
记一次在UIScrollView上添加xib的UIView作为U

记一次在UIScrollView上添加xib的UIView作为U

作者: 十一岁的加重 | 来源:发表于2016-11-25 16:52 被阅读12370次

    场景:

    一个storyboard里放着一个UIViewController,在其view上放了一个UIScrollView,然后里面放了很多控件,并且已经布局好了,然后点击里面的加号按钮,会添加一个一样的控件进来,如图
    
    9CA0864B-D191-4056-B5B6-2AF88E58C683.png Snip20161125_5.png

    初步想法,是改变之前storyboard中的一个约束,拉长并放入自定义的xib的view,由于单词太长,后面简称sb。

    Snip20161125_6.png Snip20161125_7.png
    /**
     原来 界面上的加号按钮事件
     */
    - (IBAction)didTapAddBtn:(UIButton *)sender {
        // 加一个AddTest到界面上
        AddTest *addView = [AddTest viewFromXib];
        [self.scrollView addSubview:addView];
        
        __block int addViewCount = 0;
        [self.scrollView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull subV, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([subV isKindOfClass:NSClassFromString(@"AddTest")]) {
                addViewCount ++;
            }
        }];
        // 第一个
        if (addViewCount == 1) {
    // 这个是之前两个控件之前的垂直约束,我们只有把这个垂直约束变大了,才能放入自定义xib,位置更合理    
    self.nextViewToAddBtnVerticalConstraint.constant = 12+12+44;
    
    // 新添加 的view的顶部跟之前有加号那个view的底部垂直间距为12
            NSLayoutConstraint *verticalToOriginAddViewBottom =
            [NSLayoutConstraint constraintWithItem:addView
                                         attribute:NSLayoutAttributeTop
                                         relatedBy:NSLayoutRelationEqual
                                            toItem:self.originAddView
                                         attribute:NSLayoutAttributeBottom
                                        multiplier:1.0
                                          constant:12];
            // 新添加 的view的顶部跟之前有加号那个view的左边一样
            NSLayoutConstraint *leading =
            [NSLayoutConstraint constraintWithItem:addView
                                         attribute:NSLayoutAttributeLeading
                                         relatedBy:NSLayoutRelationEqual
                                            toItem:self.originAddView
                                         attribute:NSLayoutAttributeLeading
                                        multiplier:1.0
                                          constant:0];
            // 新添加 的view的顶部跟之前有加号那个view的右边一样
            NSLayoutConstraint *trailing =
            [NSLayoutConstraint constraintWithItem:addView
                                         attribute:NSLayoutAttributeTrailing
                                         relatedBy:NSLayoutRelationEqual
                                            toItem:self.originAddView
                                         attribute:NSLayoutAttributeTrailing
                                        multiplier:1.0
                                          constant:0];
            
            // 新添加 的view的高度为44,之前有加号那个view也是44
            NSLayoutConstraint *heigth =
            [NSLayoutConstraint constraintWithItem:addView
                                         attribute:NSLayoutAttributeHeight
                                         relatedBy:NSLayoutRelationEqual
                                            toItem:nil
                                         attribute:NSLayoutAttributeNotAnAttribute
                                        multiplier:0.0
                                          constant:44];
    // 自身约束添加到自身上
            [addView addConstraint:heigth];
    // 非自身约束,子控件与子控件之间的相对约束,添加到大家的父控件上
            [self.scrollView addConstraints:@[verticalToOriginAddViewBottom, leading, trailing]];
    
        } else {
            // 不是第一个
        }
        
        
    }
    

    运行,点击加号,问题来了,scrollview显示不正常,添加的xib的view也不正常,宽度也不对。

    Snip20161125_8.png

    反复查看,约束正确也与,无非就是vertical leading trailing 自身高度44约束 啊,没有问题,然后不用代码加这个控件,直接在storyboard中添加这个控件。
    跟代码的约束一样。
    自身高度约束44

    Snip20161125_11.png

    然后leading trailing相同,vertical为12,也跟代码约束一样。

    Snip20161125_12.png

    奇怪同样的约束,用代码添加就不行,在IB中添加就正常,如图,在IB中添加view正常。

    Snip20161125_13.png

    那么问题来了,代码添加约束跟在IB直接托约束的区别在哪里,肯定是这个区别导致了这个不正常的问题。其实,那会儿点加号,是有打印的。如图。

    Snip20161125_14.png

    跳到UIView头文件会发现一个属性

    /* By default, the autoresizing mask on a view gives rise to constraints that fully determine 
     the view's position. This allows the auto layout system to track the frames of views whose 
     layout is controlled manually (through -setFrame:, for example).
     When you elect to position the view using auto layout by adding your own constraints, 
     you must set this property to NO. IB will do this for you.
     */
    @property(nonatomic) BOOL translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
    
    
    

    谷歌翻译

    默认情况下,视图上的自动调整掩码会产生完全确定的约束
      视图的位置。 这允许自动布局系统跟踪视图的帧
      布局是手动控制的(例如通过-setFrame:)。
      当您通过添加自己的约束选择使用自动布局定位视图时,
      您必须将此属性设置为NO。 IB会为你做这个。
    
    最后一句话, IB会为你做这个。是重点。
    

    然后, 我们给addView加上这个属性。

    
    /**
     原来 界面上的加号按钮事件
     */
    - (IBAction)didTapAddBtn:(UIButton *)sender {
        // 加一个AddTest到界面上
        AddTest *addView = [AddTest viewFromXib];
        addView.translatesAutoresizingMaskIntoConstraints = NO;// 这里加上
        [self.scrollView addSubview:addView];
    

    再次运行,正常。
    其他解决方案。

    [addView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.leading.trailing.height.equalTo(self.originAddView);
            make.top.equalTo(self.originAddView.mas_bottom).offset(12);
        }];
    

    总结:

    当把一个xib放入一个有autolayout的view上,一定要把这个xib的view的translatesAutoresizingMaskIntoConstraints设置成NO;
    

    相关文章

      网友评论

        本文标题:记一次在UIScrollView上添加xib的UIView作为U

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