如何自动调整UIScrollView的大小以适合其内容

jwe*_*rre 126 iphone cocoa-touch objective-c uiscrollview ios

有没有办法UIScrollView自动调整滚动内容的高度(或宽度)?

就像是:

[scrollView setContentSize:(CGSizeMake(320, content.height))];
Run Code Online (Sandbox Code Playgroud)

lev*_*han 301

我遇到的最好的方法是更新UIScrollView基于其包含的子视图的内容大小:

Objective-C的

CGRect contentRect = CGRectZero;

for (UIView *view in self.scrollView.subviews) {
    contentRect = CGRectUnion(contentRect, view.frame);
}
self.scrollView.contentSize = contentRect.size;
Run Code Online (Sandbox Code Playgroud)

迅速

let contentRect: CGRect = scrollView.subviews.reduce(into: .zero) { rect, view in
    rect = rect.union(view.frame)
}
scrollView.contentSize = contentRect.size
Run Code Online (Sandbox Code Playgroud)

  • 我在`viewDidLayoutSubviews`中运行这个,所以自动布局会完成,在iOS7中它运行良好,但由于某种原因测试iOS6的自动布局没有完成工作,所以我有一些错误的高度值,所以我切换到`viewDidAppear `现在工作正常..只是指出也许有人需要这个.谢谢 (7认同)
  • 启用滚动指示器时请小心!SDK会自动为每个人创建一个UIImageView.您必须考虑到它,否则您的内容大小将是错误的.(参见http://stackoverflow.com/questions/5388703/strange-uiimageview-in-uiscrollview) (5认同)

eme*_*gro 75

UIScrollView不会自动知道其内容的高度.您必须自己计算高度和宽度

用类似的东西做

CGFloat scrollViewHeight = 0.0f;
for (UIView* view in scrollView.subviews)
{
   scrollViewHeight += view.frame.size.height;
}

[scrollView setContentSize:(CGSizeMake(320, scrollViewHeight))];
Run Code Online (Sandbox Code Playgroud)

但这只有在视图低于另一个视图时才有效.如果您有一个彼此相邻的视图,如果您不想将滚动条的内容设置为大于实际值,则只需添加一个视图的高度.

  • 或者只是:`int y = CGRectGetMaxY(((UIView*)[_ scrollView.subviews lastObject]).frame); [_scrollView setContentSize:(CGSizeMake(CGRectGetWidth(_scrollView.frame),y))];` (21认同)

Ada*_*ite 40

解决方案如果您使用自动布局:

  • 设置translatesAutoresizingMaskIntoConstraintsNO涉及的所有视图.

  • 使用滚动视图外部的约束来定位和调整滚动视图的大小.

  • 使用约束在滚动视图中布置子视图,确保约束绑定到滚动视图的所有四个边缘,并且不依赖滚动视图来获取它们的大小.

资料来源:https: //developer.apple.com/library/ios/technotes/tn2154/_index.html

  • Imho这是世界上真正的解决方案,其中一切都发生在汽车布局上.关于其他解决方案:你在计算每个视图的高度和有时宽度时是否认真? (7认同)
  • 当您希望滚动视图的高度基于其内容高度时,这不起作用。(例如,在屏幕中心的弹出窗口,您不想滚动到一定数量的内容)。 (4认同)

ric*_*chy 35

我把它添加到Espuz和JCC的答案中.它使用子视图的y位置,不包括滚动条.编辑使用可见的最低子视图的底部.

+ (CGFloat) bottomOfLowestContent:(UIView*) view
{
    CGFloat lowestPoint = 0.0;

    BOOL restoreHorizontal = NO;
    BOOL restoreVertical = NO;

    if ([view respondsToSelector:@selector(setShowsHorizontalScrollIndicator:)] && [view respondsToSelector:@selector(setShowsVerticalScrollIndicator:)])
    {
        if ([(UIScrollView*)view showsHorizontalScrollIndicator])
        {
            restoreHorizontal = YES;
            [(UIScrollView*)view setShowsHorizontalScrollIndicator:NO];
        }
        if ([(UIScrollView*)view showsVerticalScrollIndicator])
        {
            restoreVertical = YES;
            [(UIScrollView*)view setShowsVerticalScrollIndicator:NO];
        }
    }
    for (UIView *subView in view.subviews)
    {
        if (!subView.hidden)
        {
            CGFloat maxY = CGRectGetMaxY(subView.frame);
            if (maxY > lowestPoint)
            {
                lowestPoint = maxY;
            }
        }
    }
    if ([view respondsToSelector:@selector(setShowsHorizontalScrollIndicator:)] && [view respondsToSelector:@selector(setShowsVerticalScrollIndicator:)])
    {
        if (restoreHorizontal)
        {
            [(UIScrollView*)view setShowsHorizontalScrollIndicator:YES];
        }
        if (restoreVertical)
        {
            [(UIScrollView*)view setShowsVerticalScrollIndicator:YES];
        }
    }

    return lowestPoint;
}
Run Code Online (Sandbox Code Playgroud)

  • 我很惊讶像这样的方法不属于班级. (2认同)

Jos*_*osh 13

对于懒得转换它的人来说,这是swift中接受的答案:)

var contentRect = CGRectZero
for view in self.scrollView.subviews {
    contentRect = CGRectUnion(contentRect, view.frame)
}
self.scrollView.contentSize = contentRect.size
Run Code Online (Sandbox Code Playgroud)


fre*_*dnd 8

这是@ leviatan答案的Swift 3改编:

延期

import UIKit


extension UIScrollView {

    func resizeScrollViewContentSize() {

        var contentRect = CGRect.zero

        for view in self.subviews {

            contentRect = contentRect.union(view.frame)

        }

        self.contentSize = contentRect.size

    }

}
Run Code Online (Sandbox Code Playgroud)

用法

scrollView.resizeScrollViewContentSize()
Run Code Online (Sandbox Code Playgroud)

非常好用!


gok*_*urt 6

扩展后将有助于Swift.

extension UIScrollView{
    func setContentViewSize(offset:CGFloat = 0.0) {
        // dont show scroll indicators
        showsHorizontalScrollIndicator = false
        showsVerticalScrollIndicator = false

        var maxHeight : CGFloat = 0
        for view in subviews {
            if view.isHidden {
                continue
            }
            let newHeight = view.frame.origin.y + view.frame.height
            if newHeight > maxHeight {
                maxHeight = newHeight
            }
        }
        // set content size
        contentSize = CGSize(width: contentSize.width, height: maxHeight + offset)
        // show scroll indicators
        showsHorizontalScrollIndicator = true
        showsVerticalScrollIndicator = true
    }
}
Run Code Online (Sandbox Code Playgroud)

逻辑与给定答案相同.但是,它忽略了隐藏的视图,UIScrollView并在滚动指示器设置隐藏后执行计算.

此外,还有一个可选的函数参数,您可以通过将参数传递给函数来添加偏移值.


小智 5

来自@leviathan的优秀和最佳解决方案.只需使用FP(函数式编程)方法转换为swift.

self.scrollView.contentSize = self.scrollView.subviews.reduce(CGRect(), { 
  CGRectUnion($0, $1.frame) 
}.size
Run Code Online (Sandbox Code Playgroud)