UIScrollView不会滚动,直到方向更改

时间:2013-03-19 17:24:54

标签: ios objective-c uiscrollview

我有一个UIScrollView动态添加到主视图中,我用小UIView对象填充它。我将它的contentSize设置为比设备分辨率更大的值,但是在我改变设备的方向之前我无法滚动它。

如何在方向改变之前滚动它?

LATER EDIT:

我意识到问题来自我正在添加的某些子视图,更具体地来说是为这些子视图添加一些约束:

以下是我添加子视图的代码(该方法被调用大约10-20次):

-(void) addShelve:(NSInteger) index
{
FSShelf *shelf = [[FSShelf alloc] initWithFrame:CGRectMake(0, index * [FSConstants getShelfVerticalDistance], 0, 0)];
[shelves addObject:shelf];

[shelfView addSubview:shelf];
[shelf addShelfConstraints];
}

FSShelf是UIView的子类,shelfView是我的UIScrollView的子类。

以下是addShelfContraints添加的约束:

    [self.superview addConstraint:[FSUtils getWidthConstraintFor:self.superview with:self constant: -2 * ([FSConstants getShelveMargin])]];
    [self addConstraint:[FSUtils getSelfHeightConstraintFor:self constant:30]];
    [self.superview addConstraint:[FSUtils getCenterXConstraintFor:self.superview with:self constant:0]];

FSUtils类中用于添加约束的方法:

+ (NSLayoutConstraint *)getSelfHeightConstraintFor:(UIView *)view constant:(CGFloat)constant
{
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                  attribute:NSLayoutAttributeHeight
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:nil
                                                                  attribute:NSLayoutAttributeNotAnAttribute
                                                                 multiplier:1.0
                                                                   constant:constant];
    return constraint;
}

+ (NSLayoutConstraint *)getCenterXConstraintFor:(UIView *)superView with:(UIView *)subView constant:(CGFloat)constant
{
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:subView
                                                                  attribute:NSLayoutAttributeCenterX
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:superView
                                                                  attribute:NSLayoutAttributeCenterX
                                                                 multiplier:1.0
                                                                   constant:constant];

    return constraint;
}

+ (NSLayoutConstraint *)getWidthConstraintFor:(UIView *)superView with:(UIView *)subView constant:(CGFloat)constant
{
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:subView
                                                                  attribute:NSLayoutAttributeWidth
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:superView
                                                                  attribute:NSLayoutAttributeWidth
                                                                 multiplier:1.0
                                                                   constant:constant];
    return constraint;
}

你注意到这些约束有什么问题吗?

4 个答案:

答案 0 :(得分:1)

在你的单击上, 尝试像这样创建

UIScrollView * scrollview = [[UIScrollView alloc]init];
CGRect viewFrame = self.view.frame;
[scrollview setFrame:viewFrame];
[scrollview setShowsHorizontalScrollIndicator:YES];
[scrollview setShowsVerticalScrollIndicator:YES];

UIView * view = [[UIView alloc]init];
CGRect viewDoubleFrame = CGRectMake(viewFrame.origin.x,viewFrame.origin.y,viewFrame.size.width * 2,viewFrame.size.height *2);
[view setFrame:viewDoubleFrame];
[view setBackgroundColor:[UIColor darkGrayColor]];

// add your additional components here

[scrollview setContentSize:CGSizeMake(view.frame.size.width,view.frame.size.height)];
[scrollview addSubview:view];

[self.view addSubview:scrollview];

答案 1 :(得分:1)

滚动与设备分辨率没有任何关系。当您的内容大小大于scrollView框架的大小时,就会发生滚动。

通常,为了使尺寸为100 * 100的内容可以滚动,您应该有一个框架大小小于100 * 100的滚动视图。如果frame.width< contentsize.width,它将允许水平滚动。如果frame.height<同样的话。 contentsize.height,它将允许垂直滚动。

您可能选择了自动布局,或者您可能已经使用了自动调整大小标记,这可能导致您的scrollview.frame的大小大于contentsize。当您提供方向时,框架可能会完美地定位,您可以滚动。

如果您想发现确切的问题,请发布代码。

答案 2 :(得分:1)

您试图放在shelfView上的约束(我假设是您的UIScrollView)是不明智的。您正在创建零宽度和零x原点FSShelf *shelf = [[FSShelf alloc] initWithFrame:CGRectMake(0, index * [FSConstants getShelfVerticalDistance], 0, 0)];的货架子视图,然后立即尝试约束shelfView以使相同的零宽度减去某个常量(因此shelfView将需要负宽度)然后将相同的中心x作为子视图,但架子视图仍然是零宽度,并且具有零x原点!您分配给货架子视图的唯一约束是它们的高度。事实上,我觉得这里缺少一些东西。使用您发布的代码,您的货架子视图的宽度始终为零。你真的在屏幕上看到任何货架子视图吗?

无论如何,这是我的建议:尝试根据每个货架子视图向shelfView添加约束是一个失败的主张。在这种情况下,约束似乎是不可满足的,并且通常你会发现各种约束变得不可满足,除非你非常小心地确保所有的子视图总是同意他们的superview应该如何布局。

而不是所有这些,只需忘记约束代码。你要做的事情很简单。 shelfView应该有一个等于屏幕大小的框架(或应用程序框架,无论如何可能是其超视图的边界),并且架子视图应该垂直排列,它们之间有一些垂直边距和一些水平边距分开他们来自屏幕的边缘。像现在一样添加视图,但不是添加任何约束,而是调用[self.view setNeedsLayout];,然后在视图控制器中实现viewDidLayoutSubviews方法。你会想要这样的东西:

- (void)viewDidLayoutSubviews {
    const CGRect rootViewBounds = self.view.bounds;
    shelfView.frame = rootViewBounds;

    const CGFloat kHorizontalMargin = [FSConstants getShelveMargin];
    const CGFloat kVerticalDistancePerShelf = [FSConstants getShelfVerticalDistance];
    const CGFloat kShelfHeight = 30.0;
    const NSUInteger shelvesCount = [shelves count];
    for (NSUInteger j = 0; j < shelvesCount; j++) {
        UIView *shelf = [shelves objectAtIndex:j];
        shelf.frame = CGRectMake(kHorizontalMargin,
                                 j * kVerticalDistancePerShelf,
                                 CGRectGetWidth(rootViewBounds) - 2.0 * kHorizontalMargin,
                                 kShelfHeight);
    }
    shelfView.contentSize = CGSizeMake(CGRectGetWidth(rootViewBounds), (shelvesCount - 1) * kVerticalDistancePerShelf + kShelfHeight);
}

答案 3 :(得分:0)

请注意,如果您使用自动布局,仅更改内容大小是不够的。滚动视图以不同的方式布局。我在堆栈Here上找到了非常有用的这个问题。因此,请检查您是否使用自动布局并适应它或禁用它 希望这可以帮助, 安德烈

[编辑]
如果您定位设备&gt; = iOS6,为什么不使用集合视图。它们非常酷,具有令人厌恶的布局功能,感谢Peter你有一个替代iOS&gt; = 4.3。根据我的理解,他们可以满足您的要求。 github