ios UIScrollView contentSize 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12846351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:42:30  来源:igfitidea点击:

UIScrollView contentSize not working

objective-ciosuiscrollview

提问by cannyboy

I put a UIScrollViewin my nib's view, and linked it to a an IBOutletproperty.

我将 aUIScrollView放入我的笔尖view,并将其链接到一个IBOutlet属性。

Now, when I do this in my viewDidLoadmethod, it seems to have no effect on the contentSize:

现在,当我在我的viewDidLoad方法中执行此操作时,它似乎对以下内容没有影响contentSize

self.sv.backgroundColor = [UIColor yellowColor]; // this works
CGSize size =  CGSizeMake(1000.0, 1000.0); 
[self.sv setContentSize:size]; // this does not

It behaves as if the contentSizewas the same as the frame. What's going on? This started working when I turned off AutoLayout. Why?

它的行为就好像contentSize与框架相同。这是怎么回事?当我关闭 AutoLayout 时,这开始工作。为什么?

回答by yuf

I had the same problem. Auto Layout for UIScrollViewis messed up.

我有同样的问题。自动布局UIScrollView搞砸了。

Work around: Put everything in the UIScrollViewinto another UIView, and put that UIViewas the only child of the UIScrollView. Then you can use Auto Layout.

解决方法:将所有内容UIScrollView放入另一个UIView,并将其UIView作为UIScrollView. 然后你可以使用自动布局。

If things near the end is messed up (the end of whichever direction your UIScrollViewscrolls), change the constraint at the end to have the lowest possible priority.

如果接近结尾的事情搞砸了(无论UIScrollView滚动方向的结尾),请更改结尾的约束以具有尽可能低的优先级。

回答by HDdeveloper

I tried viewWillLayoutSubviews to update scrollView's contentSize, it worked for me.

我试过 viewWillLayoutSubviews 来更新 scrollView 的 contentSize,它对我有用。

- (void)viewDidLayoutSubviews
{
  [self.bgScrollView setContentSize:CGSizeMake(320, self.view.frame.size.height* 1.5)];
}

Apple Doc

苹果文档

-(void)viewDidLayoutSubviews

Called to notify the view controller that its view has just laid out its subviews.

调用以通知视图控制器它的视图刚刚布局了它的子视图。

Discussion

讨论

When the bounds change for a view controller's view, the view adjusts the positions of its subviews and then the system calls this method. However, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted. Each subview is responsible for adjusting its own layout.

当视图控制器视图的边界发生变化时,视图会调整其子视图的位置,然后系统调用此方法。但是,调用此方法并不表示已调整视图子视图的各个布局。每个子视图负责调整自己的布局。

Your view controller can override this method to make changes after the view lays out its subviews. The default implementation of this method does nothing.

您的视图控制器可以覆盖此方法以在视图布局其子视图后进行更改。此方法的默认实现不执行任何操作。

回答by Jlam

The easiest/cleanest way is to set contentSize at viewDidAppear so you negate the effects of autolayout. This doesn't involve adding random views. However relying on load order for an implementation to work may not be the best idea.

最简单/最干净的方法是在 viewDidAppear 中设置 contentSize,这样您就可以消除自动布局的效果。这不涉及添加随机视图。然而,依赖加载顺序来实现工作可能不是最好的主意。

回答by brandonscript

A SUPER easy way to use AutoLayout with UIScrollViews inside Interface Builder:

在 Interface Builder 中使用带有 UIScrollViews 的 AutoLayout 的超级简单方法:

Step 1:Create a UIScrollView

第 1 步:创建一个UIScrollView

Step 2:Create a UIViewthat is a child of your scroll view like so:

第 2 步:创建一个UIView滚动视图的子视图,如下所示:

-UIScrollView
---UIView
-----Your other content

(We'll call this one contentView).

(我们将称之为contentView)。

Step 3:In the size inspector, give this view a height and width (say, 320x700).

第 3 步:在尺寸检查器中,给这个视图一个高度和宽度(比如 320x700)。

Step 4 (using AutoLayout):Create unambiguous constraints from your contentViewto its superview (the UIScrollView): connect the 4 edges (top, leading, trailing, bottom), then give it a defined width and height that you want it to scroll too.

第 4 步(使用 AutoLayout):创建从你contentView到它的超级视图(the UIScrollView)的明确约束:连接 4 个边缘(顶部、前导、尾部、底部),然后给它一个定义的宽度和高度,你也希望它滚动。

For example: If your scroll view spans the entire screen, you could give your content view a width of [device width] and a height of 600; it will then set the content size of the UIScrollViewto match.

例如:如果你的滚动视图跨越整个屏幕,你可以给你的内容视图一个 [设备宽度] 的宽度和 600 的高度;然后它将设置UIScrollView匹配的内容大小。

OR:

或者:

Step 4 (not using AutoLayout):Connect both of these new controls to your view controller using IB (ctrl+drag from each control to your view controller's .h @implementation). Let's assume each is called scrollViewand contentView, respectively. It should look like this:

第 4 步(不使用 AutoLayout):使用 IB 将这两个新控件连接到您的视图控制器(ctrl+drag 从每个控件到您的视图控制器的 .h @implementation)。让我们假设每个都分别被称为scrollViewcontentView。它应该是这样的:

@interface YourViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
@property (strong, nonatomic) IBOutlet UIView *contentView;

@end

Step 5 (not using AutoLayout):In the view controller's .h file add (actually, override) the following method:

第 5 步(不使用 AutoLayout):在视图控制器的 .h 文件中添加(实际上是覆盖)以下方法:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.scrollView.contentSize = self.contentView.frame.size;
}

回答by matt

There are two problems here. (1) viewDidLoad is too soon; you have to wait until after layout has taken place. (2) If you want to use autolayout with a scrollview that comes from a nib, then either you must use constraints to completely describe the size of the contentSize(and then you don't set the contentSizein code at all), or, if you want to set it in code, you must preventthe constraints on the scrollview's subviews from dictating the contentSize. It sounds like you would like to do the latter. To do so, you need a UIView that acts as the sole top-level subview of the scrollview, and in code you must set it to notuse autolayout, enabling its autoresizingMaskand removing its other external constraints. I show an example of how to do that, here:

这里有两个问题。(1) viewDidLoad 过快;您必须等到布局完成后。(2) 如果您想对来自笔尖的滚动视图使用自动布局,那么您要么必须使用约束来完全描述 the 的大小contentSize(然后您根本不设置contentSizein 代码),或者,如果您想要在代码中设置它,您必须防止滚动视图子视图上的约束指示contentSize. 听起来你想做后者。为此,您需要一个 UIView 作为滚动视图的唯一顶级子视图,并且在代码中您必须将其设置为使用自动布局,启用它autoresizingMask并删除其其他外部约束。我在这里展示了一个如何做到这一点的例子:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch20p573scrollViewAutoLayout/ch20p573scrollViewAutoLayout/ViewController.m

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch20p573scrollViewAutoLayout/ch20p573scrollViewAutoLayout/ViewController.m

But notice also the next example, which shows how to use constraints completely, insteadof contentSize.

但也注意到下面的例子,显示了如何完全使用约束条件,而不是contentSize

回答by Karen Hovhannisyan

Use this code. ScrollView setContentSize should be called async in main thread.

使用此代码。ScrollView setContentSize 应在主线程中异步调用。

Swift:

迅速:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    DispatchQueue.main.async {
        var contentRect = CGRect.zero

        for view in self.scrollView.subviews {
           contentRect = contentRect.union(view.frame)
        }

        self.scrollView.contentSize = contentRect.size
    }
}

Objective C:

目标 C:

 - (void)viewDidLayoutSubviews {
     [super viewDidLayoutSubviews];

     dispatch_async(dispatch_get_main_queue(), ^ {
                        CGRect contentRect = CGRectZero;

                        for(UIView *view in scrollView.subviews)
                           contentRect = CGRectUnion(contentRect,view.frame);

                           scrollView.contentSize = contentRect.size;
                       });
}

回答by imti

You can use this lines of code into your *.m file's

您可以在 *.m 文件中使用这行代码

- (void)viewDidLoad{
   [scroll setContentSize:CGSizeMake(320, 800)]   ;
   [scroll setScrollEnabled:TRUE];
   [scroll setShowsVerticalScrollIndicator:NO];
   [scroll setShowsHorizontalScrollIndicator:YES];
}    

for this you need to take an IBOutlet property of UIScrollView into your *.h file this way:

为此,您需要以这种方式将 UIScrollView 的 IBOutlet 属性放入 *.h 文件中:

IBOutlet UIScrollView *scroll;

And connect this from Storyboard.

并从 Storyboard 连接它。

Or,

或者,

You can use this method into your *.m file:

您可以在 *.m 文件中使用此方法:

-(void)viewDidLayoutSubviews 
{
  [scroll setContentSize:CGSizeMake(320, self.view.frame.size.height* 1.5)];
   // this will pick height automatically from device's height and multiply it with 1.5  
}

This both solution works for me in xcode-5, xcode-6, xcode-6.1, xcode-6.2

这两种解决方案都适用于xcode-5、xcode-6、xcode-6.1、xcode-6.2

回答by PostCodeism

Setting the contentSize in viewDidAppearis critical.

设置 contentSizeviewDidAppear至关重要。

But I also had a variation of what worked in the 3.5 inch screen, and the 4 inch screen. The 4 inch screen worked, the older one does not. Both iOS 7. Bizarre is an understatement!

但我也对 3.5 英寸屏幕和 4 英寸屏幕的工作有所不同。4 英寸的屏幕能用,老的不行。两个iOS 7。奇怪的是轻描淡写!

回答by Conor

I could never get auto layout based on constraints to work. Since my view was already a subclass UIScrollView I solved it by overriding setContentView: and ignoring auto layouts zero height setContentSize: message.

我永远无法根据工作约束获得自动布局。由于我的视图已经是 UIScrollView 的子类,因此我通过覆盖 setContentView: 并忽略自动布局零高度 setContentSize: 消息来解决它。

@interface MyView : UIScrollView {}
@end

@implementation MyView
- (void)setContentSize:(CGSize)aSize {
    if (aSize.height > 0)
        [super setContentSize:aSize];
}
@end

回答by korovyev

If you are using AutoLayouta really easy way to set the contentSizeof a UIScrollViewis just to add something like this:

如果您使用AutoLayout一种非常简单的方法来设置contentSizeaUIScrollView只是添加如下内容:

CGFloat contentWidth = YOUR_CONTENT_WIDTH;

NSLayoutConstraint *constraintWidth = 
 [NSLayoutConstraint constraintWithItem:self.scrollView 
                              attribute:NSLayoutAttributeTrailing 
                              relatedBy:NSLayoutRelationEqual 
                                 toItem:self.scrollView 
                              attribute:NSLayoutAttributeLeading 
                             multiplier:1 
                               constant:contentWidth];

[self.scrollView addConstraint:constraintWidth];