在UIScrollView的内容大小上的SizeToFit

时间:2010-10-25 20:49:55

标签: objective-c uiview uiscrollview

UIView有一个SizeToFit方法,可以使UIView适合它的所有子视图。是否有类似的东西,只返回它计算的大小,而不是修改任何视图的框架。

我在UIScrollView上有几个子视图,我想在滚动视图的contentSize上做SizeToFit,而不是它的框架。我必须在contentSize上执行此操作,因为我不想增加UIScrollView的“实际”大小,并且内容是动态和异步加载的,因此当我将子视图添加到UIScrollView时我无法手动执行此操作

9 个答案:

答案 0 :(得分:39)

目前,这是我最好的:

CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews)
    contentRect = CGRectUnion(contentRect, view.frame);
self.contentSize = contentRect.size;

答案 1 :(得分:4)

如果频繁调用您的函数,则不希望每次都迭代子视图。相反,每当添加子视图时,请执行当前contentSize和新子视图的框架的联合。

- (void)didAddSubview:(UIView *)subview {
    CGRect tmp;
    tmp.origin = CGPointZero;
    tmp.size = self.contentSize;
    tmp = CGRectUnion(tmp,subview.frame);
    self.contentSize = tmp.size;
}

答案 2 :(得分:2)

ScrollView ContentSize找到解决方案,您将能够找到子视图的大小并找到合并的内容大小以及说明子视图是水平还是垂直排列的选项。

以下是上述链接中的代码:

@interface UIScrollView(auto_size)
- (void) adjustHeightForCurrentSubviews: (int) verticalPadding;
- (void) adjustWidthForCurrentSubviews: (int) horizontalPadding;
- (void) adjustWidth: (bool) changeWidth andHeight: (bool) changeHeight withHorizontalPadding: (int) horizontalPadding andVerticalPadding: (int) verticalPadding;
@end

@implementation UIScrollView(auto_size)
- (void) adjustWidth: (bool) changeWidth andHeight: (bool) changeHeight withHorizontalPadding: (int) horizontalPadding andVerticalPadding: (int) verticalPadding {
    float contentWidth = horizontalPadding;
    float contentHeight = verticalPadding;
    for (UIView* subview in self.subviews) {
        [subview sizeToFit];
        contentWidth += subview.frame.size.width;
        contentHeight += subview.frame.size.height;
    }

    contentWidth = changeWidth ? contentWidth : self.superview.frame.size.width;
    contentHeight = changeHeight ? contentHeight : self.superview.frame.size.height;

    NSLog(@"Adjusting ScrollView size to %fx%f, verticalPadding=%d, horizontalPadding=%d", contentWidth, contentHeight, verticalPadding, horizontalPadding);
    self.contentSize = CGSizeMake(contentWidth, contentHeight);
}

- (void) adjustHeightForCurrentSubviews: (int) verticalPadding {
    [self adjustWidth:NO andHeight:YES withHorizontalPadding:0 andVerticalPadding:verticalPadding];
}

- (void) adjustWidthForCurrentSubviews: (int) horizontalPadding {
    [self adjustWidth:YES andHeight:NO withHorizontalPadding:horizontalPadding andVerticalPadding:0];
}
@end

另外,请确保查看博客页面上的评论,因为提供了替代解决方案。

-anoop

答案 3 :(得分:1)

我已经设置了一个功能来设置scrollView的内容大小试试并享受

首先写这个函数......

-(void)setContentSizeOfScrollView:(UIScrollView*)scroll
{
    CGRect rect = CGRectZero;

    for(UIView * vv in [scroll subviews])
    {
        rect = CGRectUnion(rect, vv.frame);
    }

    [scroll setContentSize:CGSizeMake(rect.size.width, rect.size.height)];
}

然后添加所有元素后,只需调用此函数并将滚动视图作为参数传递.....

[self setContentSizeOfScrollView:self.YourScrollView];

我百分百肯定它会起作用.........

答案 4 :(得分:1)

尽管William's answer非常有用,但由于滚动条也是滚动视图的子视图,因此它无法正常工作。事实证明,诀窍是在计算内容大小之前隐藏它们。这是Swift 3代码的样子:

override func viewDidLayoutSubviews() {
    scrollView.layoutSubviews()

    // disable scrollbars so they don't interfere during resizing
    scrollView.showsVerticalScrollIndicator = false
    scrollView.showsHorizontalScrollIndicator = false

    scrollView.contentSize = scrollView.subViewArea()

    // re-enable the scrollbars
    scrollView.showsVerticalScrollIndicator = true
    scrollView.showsHorizontalScrollIndicator = true
}

您还需要在项目的某处添加以下扩展程序:

extension UIScrollView {
    func subViewArea() -> CGSize {
        var rect = CGRect.zero
        for subview in subviews {
            rect = rect.union(subview.frame)
        }

        return rect.size
    }
}

答案 5 :(得分:0)

将UIView放入具有相同宽度和高度的UIScrollView中,并将所有子视图添加到IT而不是滚动视图。然后将scrollview上的clipToBounds属性设置为TRUE,并在UIView上调用sizeToFit。您还可以将UIView背景的不透明度设置为0,使其不可见,但仍显示其子视图。

答案 6 :(得分:0)

在swift 2.1中,将其添加到视图控制器:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    let aggregateView = contentView.subviews.reduce(CGRect())
        { aggRect, view in aggRect.union(view.frame) }

    scrollView.contentSize = aggregateView.size

}

答案 7 :(得分:0)

联合帧大小不足以计算内容大小。因为有时,您的子视图需要重叠,有时您在子视图之间有边距。您必须知道并计算子视图的来源。

联盟方法为A和B设计提供相同的内容高度。但是如果你知道最后一个子视图,你可以计算出正确的内容:

enter image description here

此扩展程序可以计算实际内容高度。

extension UIScrollView {

 func adjustContentHeight(bottomPadding: Int = 0) {

    var lastSub: CGRect = .zero
    self.subviews.forEach({
        let sub = $0.frame
        if(sub.maxY > lastSub.maxY) {
            lastSub = sub
        }
    })

    self.contentSize.height = lastSub.maxY + CGFloat(bottomPadding)
 }   
} 

答案 8 :(得分:-1)

Swift 2扩展程序:

用法:

scrollView.contentResize
scrollView.contentWidthResize
scrollView.contentHeightResize

extension UIScrollView {

    ///Will resize content size to fit all subviews.
    func contentResize(){

        var w = CGFloat(0)
        var h = CGFloat(0)

        for view in self.subviews{

            let fw = view.frame.origin.x + view.frame.width
            let fh = view.frame.origin.y + view.frame.height

            w = max(fw, w)
            h = max(fh, h)

        }

        contentSize = CGSize(width: w, height: h)

    }

    ///Will resize content width size to fit all subviews.
    func contentWidthResize(){

        var w = CGFloat(0)

        for view in self.subviews{

            let fw = view.frame.origin.x + view.frame.width

            w = max(fw, w)

        }

        contentSize.width = w

    }

    ///Will resize content height size to fit all subviews.
    func contentHeightResize(){

        var h = CGFloat(0)

        for view in self.subviews{

            let fh = view.frame.origin.y + view.frame.height

            h = max(fh, h)

        }

        contentSize.height = h

    }

}