如何以编程方式在UIScrollView中使用AutoLayout设置子视图?

时间:2014-02-21 12:29:36

标签: ios iphone uiscrollview autolayout nslayoutconstraint

我正在使用Autolayout以编程方式使用UiScrollview和UIPagectontrol创建应用

我已经创建 TKScroller 作为UIView的子类,我使用Some Mode和Array初始化它。

TKScroller.m

-(void)setData{

[self layoutIfNeeded];
CGRect mainFrame=self.frame;


[self layoutIfNeeded];
CGRect mainFrame=self.frame;
UIView *lastview;
NSMutableArray* manualConstraints = [NSMutableArray array];

for (int i=0; i<arrayData.count ; i++)
{
    CGRect frame;
    frame.origin.x = scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = scrollView.frame.size;

    UIView *subview = [UIView new];

    subview.backgroundColor = [self getRandomColor];
    [scrollView addSubview:subview];

    if (i==0)
    {

        NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5];
        [manualConstraints addObject:b1_top];

        NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1 constant:5];
        [manualConstraints addObject:b1_left];

        NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5];
        [manualConstraints addObject:b1_right];
        NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
        [manualConstraints addObject:b1_bottom];

        [subview layoutIfNeeded];
        [scrollView addConstraints:manualConstraints];
        lastview=subview;
    }
    else{

        NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5];
        [manualConstraints addObject:b1_top];

        NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:lastview attribute:NSLayoutAttributeLeading multiplier:1 constant:5];
        [manualConstraints addObject:b1_left];

        NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5];
        [manualConstraints addObject:b1_right];
        NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10];
        [manualConstraints addObject:b1_bottom];

        [subview layoutIfNeeded];
        [scrollView addConstraints:manualConstraints];
        lastview=subview;

    }
}

scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2);

self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = arrayData.count;

 pageControlBeingUsed = NO;
}

-(UIColor *)getRandomColor{
    int r = arc4random() % 255;
    int g = arc4random() % 255;
    int b = arc4random() % 255;
    return [UIColor colorWithRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];
}

现在我正在获取任何子视图,

但是如果我改变方向会产生不正确的结果,那么我怎样才能给出NSLayoutConstraint来查看scrollview的子视图?

修改

添加NSLayoutConstraint子视图后未显示。我只是缺少一些约束,请在动态设置约束时纠正我。

我的 Source Code is here ,请帮助我。 谢谢。抱歉语法不好。

4 个答案:

答案 0 :(得分:10)

根据我对AutoLayout的体验(我也是以编程方式使用)。您不应直接向UIScrollView添加观看次数。

您应该添加一个UIView ,只有一个,并将其添加为UIScrollView的子视图。

完成此操作后,您可以将所有子视图添加到此UIView

这里详细解释了所有内容:Apple iOS Technical Note TN2154

答案 1 :(得分:6)

Here is a SO answer已经解释了如何使用自动布局执行此操作,他已经完美地解释了,在这里有垂直文本字段,但在您的情况下,您必须设置水平视图约束。

<强>替代

而是设置约束,您可以只设置子视图的帧并在Scrollview中设置它,并且根据方向,您可以更改滚动视图的子视图的帧。

您的setData方法,如

-(void)setData{

    [self layoutIfNeeded];
    CGRect mainFrame=scrollView.frame;
    CGRect frame;
    for (int i=0; i<arrayData.count ; i++)
    {
        CGRect frame;
        frame.origin.x = scrollView.frame.size.width * i;
        frame.origin.y = 0;
        frame.size = scrollView.frame.size;

        frame.origin=CGPointMake(0, 0);
        UIView *subview = [[UIView alloc]initWithFrame:frame];
        subview.backgroundColor = [self getRandomColor];
        [scrollView addSubview:subview];
    }
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2);
}

现在您使用NSNotificationCenter,您可以在设备方向变化时收到通知,因此在此选择器方法中调用您的setData方法,

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(setData)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];

现在在setData方法中,您需要删除所有子视图,因为当设备更改方向时,它会向您的滚动视图添加新视图,因此在设置其框架之前从Scrollview中删除所有子视图,

        [scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

确保你要从你的班级中移除观察者,

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

答案 2 :(得分:5)

我知道问题已经解决了。我希望这个解决方案能帮助一些人,所以我发布了它。

下面的代码用于将scrollview添加到uiviewcontroller

  self.scrollView = UIScrollView()
    self.scrollView.backgroundColor = UIColor.greenColor()
    self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
    self.scrollView.scrollEnabled=true
    self.scrollView.pagingEnabled = true
    self.view.addSubview(self.scrollView)

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView]))

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView]))

添加了滚动视图并添加了这样的子视图/图像(这是以照片应用程序的形式显示滚动视图的完整大小的图像的示例)

var prev:UIImgeView?

        for var index = 0; index < self.images.count; ++index {
            var iview = UIImgeView()
            iview.setTranslatesAutoresizingMaskIntoConstraints(false)
            self.scrollView.addSubview(iview)
            var image = self.images.objectAtIndex(index) as UIImage
            iview.image = image
            if (index == 0){
                self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[iview(==scrollView)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView]))
                prev = iview

            }
            else{
                self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev][iview(==prev)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"prev":prev!]))
                prev = iview
            }
            self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[iview(==scrollView)]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView]))

            if (index == self.images.count-1){
                self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["prev":prev!]))

            }

        }

答案 3 :(得分:0)

如果您希望将TKScroller固定在中心并支持方向更改,您只需将以下代码放入init

即可。
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;

您可能需要检查TKScroller的所有子视图。如果您不喜欢自动调整大小,可以设置(三个中的一个)

self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;