美文网首页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