即使 contentSize 大于 frame 并且在设置内容大小之前添加了子视图,滚动视图也不起作用

Posted

技术标签:

【中文标题】即使 contentSize 大于 frame 并且在设置内容大小之前添加了子视图,滚动视图也不起作用【英文标题】:scrollView doesn't work even though contentSize is larger than frame and subview is added before setting content size 【发布时间】:2014-05-30 04:35:05 【问题描述】:
    - (void)viewDidLoad


[super viewDidLoad];




self.navigationController.navigationBar.translucent = YES;
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"sprites_0001_Rectangle-1.png"]  forBarMetrics:UIBarMetricsDefault];



self.navigationController.navigationBar.translucent = YES;

UIImageView *imageView = [[UIImageView alloc]init];
UIImage *image = [UIImage imageNamed:@"sprites_0000s_0008_1st-Page.png"];
imageView.image = image;


//imageView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.backgroundColor = [UIColor clearColor];
self.view = imageView;



if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) 

     //Write the code to set up view for iPad

   else

    UIScrollView *scrollView = [[UIScrollView alloc] init];
    scrollView.backgroundColor = [UIColor clearColor];
    scrollView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.view addSubview:scrollView];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[scrollView(==240)]"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(scrollView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[scrollView(==468)]"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(scrollView)]];

    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"ParentsMock.png"]];
    imageView.translatesAutoresizingMaskIntoConstraints = NO;
    [scrollView addSubview:imageView];



    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[imageView(==1000)]|"
                                                                       options:0
                                                                       metrics:0
                                                                         views:NSDictionaryOfVariableBindings(imageView)]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView(==2000)]|"
                                                                       options:0
                                                                       metrics:0
                                                                         views:NSDictionaryOfVariableBindings(imageView)]];

    

这是我以编程方式创建UIScrollView 的尝试,但是即使我在将子视图添加到scrollView 后设置了contentSize,我也无法使scrollView 工作。

正如您在这张图片中看到的,我使用 UINavigationController 来包装 UIViewControllar 并将 UIImageView 设置为其视图。我创建了一个滚动视图并将其添加到视图顶部。然后我创建另一个 imageView1 并将其插入到滚动视图中。

请注意,整个视图控制器的视图是一个 imageView,与我插入到 scrollView 中的 imageView 不同。

【问题讨论】:

你使用自动布局,去掉initWithFrame 【参考方案1】:

你应该使用约束来设置你的内容大小,通过直接设置它。它不会滚动,因为您对滚动视图内容的左侧、顶部、右侧或底部没有约束。看我的回答here

编辑:

尝试添加这个:

    imageView.translatesAutoresizingMaskIntoConstraints = NO;
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:
                                                         @"|[imageView(==1000)]|"
                                                        options:0
                                                        metrics:0
                                               views:NSDictionaryOfVariableBindings(imageView)]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:
                                                         @"V:|[imageView(==2000)]|"
                                                        options:0
                                                        metrics:0
                                               views:NSDictionaryOfVariableBindings(imageView)]];

并删除您设置内容大小的代码。

编辑:

用这个替换你的整个代码:

        UIScrollView *scrollView = [[UIScrollView alloc] init];
        scrollView.backgroundColor = [UIColor clearColor];
        scrollView.translatesAutoresizingMaskIntoConstraints = NO;

        [self.view addSubview:scrollView];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[scrollView(==240)]"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:NSDictionaryOfVariableBindings(scrollView)]];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[scrollView(==468)]"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:NSDictionaryOfVariableBindings(scrollView)]];

        UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"ParentsMock.png"]];
        imageView.translatesAutoresizingMaskIntoConstraints = NO;
        [scrollView addSubview:imageView];



        [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[imageView(==1000)]|"
                                                                           options:0
                                                                           metrics:0
                                                                             views:NSDictionaryOfVariableBindings(imageView)]];
        [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView(==2000)]|"
                                                                           options:0
                                                                           metrics:0
                                                                             views:NSDictionaryOfVariableBindings(imageView)]];

【讨论】:

我试过还是不行。我更新了代码,请检查一下。 好的,我已经用你的代码替换了我的所有代码仍然无法正常工作,我更新了 viewDidLoad 中的代码。 我刚刚尝试了我发布的代码,它对我有用,所以你一定是做错了什么 你在使用我在那里使用的代码吗因为我刚刚更新了代码以匹配你在 viewDidLoad 中的代码。我将 UIImageView 设置为那里的视图。 self.view = imageView; 我只将我发布的代码粘贴到我的viewDidLoad 方法之一中,还没有尝试过你的整个viewDidLoad。也许你应该先尝试只留下[super viewDidLoad] 和我的代码,看看它是否有效【参考方案2】:

我成功创建 UIScrollViews 的唯一方法是使用 Autolayout。这是我所知道的最简单、最有效的方法。为此,您需要删除

initWithFrame:CGRectMake(40, 100, 240, 168)];

【讨论】:

您遇到的具体问题是什么?它根本不滚动吗? 是的,根本不滚动,感觉就像一个普通的视图。当我尝试滚动它时根本没有滚动条【参考方案3】:

替换:

NSDictionary *layoutDic = ....

与:

NSDictionary *layoutDic = NSDictionaryOfVariableBindings(scrollView);

编辑:我使用你的代码,它可以工作,我可以滚动,我在 viewDidLoad 中做

UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(40, 100, 240, 168)];

UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"purple_button.png"]];
[scrollView addSubview:imageView];
scrollView.contentSize = CGSizeMake(1000, 2000);
scrollView.backgroundColor = [UIColor clearColor];
scrollView.scrollEnabled = YES;
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *layoutDic = NSDictionaryOfVariableBindings(scrollView);
[self.view addSubview:scrollView];
NSArray *scrollViewConstraintWidth = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[scrollView(==240)]" options:0 metrics:nil views:layoutDic];
NSArray *scrollViewConstraintHeight = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[scrollView(==468)]" options:0 metrics:nil views:layoutDic];
[self.view addConstraints:scrollViewConstraintHeight];
[self.view addConstraints:scrollViewConstraintWidth];

【讨论】:

我在视图中的其他键值对呢? 我不知道你声明的键值对与否。但是当我使用自动布局时,我会像 Apple 推荐的那样使用NSDictionaryOfVariableBindings。如果你有scrollView和label NSDictionaryOfVariableBindings(scrollView,label),并设置约束。【参考方案4】:

在显示文件检查器下的属性中取消选中使用自动布局

【讨论】:

我以编程方式创建了这个视图。 只有 .h 和 .m 文件,没有 xib 文件或情节提要。 其实这个问题与自动布局有关,你必须以编程方式关闭自动布局。 其实我需要自动布局!【参考方案5】:

像这样将委托添加到自己:

 UIScrollView *scrollView = [[UIScrollView alloc]init];

scrollView.delegate=self;

 UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"ParentsMock.png"]];
 [scrollView addSubview:imageView];

【讨论】:

滚动视图内容大小必须大于滚动视图框架才能滚动【参考方案6】:

我找到了答案。看来我需要在 UIImageView 上启用 userInteraction。请记住,当我使用 UIImageView 作为视图控制器的视图时。因此 UIImageView 的 userInteractionEnabled 属性的默认值为 NO。它根本不接受任何触摸。我们需要像这样启用它

imageView.userInteractionEnabled = YES;

问题已解决。

【讨论】:

以上是关于即使 contentSize 大于 frame 并且在设置内容大小之前添加了子视图,滚动视图也不起作用的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发frame, contentSize, contentOffset, contentInset 区别联系浅析

ScrollView contentSize 大于 Bounds,但没有滚动

KVO - UIScrollView.contentSize误报?

iOS-KVO动态监听UIScrollView的contentSize(UITableViewUICollectionView)

UIScrollView - 无法向下滚动很远(即使我已将 contentsize 设置为 1000)[重复]

设置了 contentsize 的 UIScrollView 无法滚动超出帧边界