【问题标题】:iOS: UIScrollView leaving space on bottom, How can I have space on topiOS:UIScrollView 在底部留下空间,我怎样才能在顶部留出空间
【发布时间】:2017-11-23 11:47:40
【问题描述】:

我有滚动视图,其中子视图是从底部添加的,例如在墙上添加砖块(在我的情况下只有一块砖块),然后在其上添加下一个砖块,依此类推。与默认的UIScrollView ContentSize 一样,滚动将发生在顶部。我怎样才能滚动到底部。如果我向下滚动,我应该能够看到其他积木叠在一起。

正如您在下面的屏幕截图中看到的那样,开始按钮应该向下而不是向上。

非常感谢任何形式的帮助。

谢谢

示例代码:

CGFloat initialYPoint = 30;
for (OUSTLevel* currentLevel in self.course.sortedLevelsList) {

    NSArray* nibList = [[UINib nibWithNibName:@"OUSTLearningMapPlayLevelCell" bundle:nil] instantiateWithOwner:self options:nil];
    OUSTLearningMapPlayLevelCell* playLevelCell = nil;

    for (UIView* childView in nibList) {
        if ([childView isKindOfClass:[OUSTLearningMapPlayLevelCell class]]) {
            playLevelCell = (OUSTLearningMapPlayLevelCell*)childView;
            break;
        }
    }

    CGFloat cellHeight = CGRectGetHeight(playLevelCell.frame);
    CGFloat yPoint = CGRectGetHeight(self.scrollview.frame) - (cellHeight + initialYPoint);
    CGRect cellFrame = CGRectMake(0, yPoint, viewWidth, cellHeight);

    [playLevelCell setFrame:cellFrame];      
    [self.scrollview addSubview:playLevelCell];

    initialYPoint += cellHeight;

    if (!landingNodeLevelData.locked) {
        [playLevelCell.unlockedView setHidden:NO];
        [playLevelCell.lockedView setHidden:YES];

        // Frame calculation for placing pin
        CGFloat centerPoint = playLevelCell.unlockedView.frame.size.width / 4;
        pinXPoint = centerPoint + 5;
        pinYPoint = yPoint - 30;
    }
}

CGRect pinFrame = CGRectMake(pinXPoint, pinYPoint, 80, 80);

[self.pinImageView setFrame:pinFrame];
[self.scrollview addSubview:self.pinImageView];
[self.view bringSubviewToFront:self.pinImageView];
self.scrollview.contentSize = CGSizeMake(self.view.frame.size.width, initialYPoint);
self.scrollview.contentInset = UIEdgeInsetsMake(30.0, 0.0, 30.0, 0.0);
CGPoint bottomOffset = CGPointMake(0, self.scrollview.contentSize.height - self.scrollview.bounds.size.height+ 30);

编辑:我没有使用约束布局,我正在计算和设置框架。

【问题讨论】:

  • 您是在使用约束来设置滚动视图的.contentSize,还是在计算尺寸?您如何添加“砖块”?您是否需要“看到”添加的新砖块(也就是说,随着新砖块出现在顶部,其他砖块是否会向下滑动)?
  • 不,我没有使用约束,我正在计算 Frame 然后添加为子视图。是的,我想看到 0 号砖正在倒塌,1 号砖以此类推,
  • 在使用应用程序时是否添加了“砖块”?所以你从开始按钮开始......点击它并添加砖#1......做一些事情并添加砖#2......等等?还是滚动视图中的所有砖块都开始了?还有 --- 有什么理由不想使用 TableView 或 CollectionView,每次添加砖块时只需插入一行?
  • 不,所有砖块将一次性添加。是的,不使用 TableView 或 Collection 视图是有充分理由的,因为它们中的 Cell 是可重用的,在我的情况下,有一个指针至少始终指向砖块。检查最后一个屏幕截图,在砖 1 上有指针,并且该指针是可动画的,从砖到砖。如果我们使用表格视图或集合视图,我想指针动画是不可能的。
  • 听起来您只需要计算内容大小和偏移量即可正确定位元素。您有正在使用的一小段代码吗?

标签: ios objective-c uiscrollview contentsize intrinsic-content-size


【解决方案1】:

看起来你可以让事情变得更轻松一些。

如果您颠倒“砖”堆叠的顺序,您可以从自上而下而不是自下而上填充视图......这更合乎逻辑且更容易思考关于。

这是对您的 pastebin 代码的修改。它应该工作正常...我没有你的数据/类/xib视图/等,但我很确定我模拟了它,所以它可以正常运行:

// start with 30-pt "padding" at the top
CGFloat initialYPoint = 30;

// reverse the array of OUSTLevel objects so we're going from top-down instead of bottom-up
NSArray *reversed = [[self.course.sortedLevelsList reverseObjectEnumerator] allObjects];

for (OUSTLevel* currentLevel in reversed) {

    NSArray* nibList = [[UINib nibWithNibName:@"OUSTLearningMapPlayLevelCell" bundle:nil] instantiateWithOwner:self options:nil];
    OUSTLearningMapPlayLevelCell* playLevelCell = nil;

    for (UIView* childView in nibList) {
        if ([childView isKindOfClass:[OUSTLearningMapPlayLevelCell class]]) {
            playLevelCell = (OUSTLearningMapPlayLevelCell*)childView;
            break;
        }
    }

    CGFloat cellHeight = CGRectGetHeight(playLevelCell.frame);

    // we're going top-down now, so Y coordinate will be a simple increment
    CGFloat yPoint = initialYPoint;

    CGRect cellFrame = CGRectMake(0, yPoint, viewWidth, cellHeight);

    [playLevelCell setFrame:cellFrame];

    [self.scrollview addSubview:playLevelCell];

    initialYPoint += cellHeight;

    if (!landingNodeLevelData.locked) {
        [playLevelCell.unlockedView setHidden:NO];
        [playLevelCell.lockedView setHidden:YES];

        // Frame calculation for placing pin
        CGFloat centerPoint = playLevelCell.unlockedView.frame.size.width / 4;
        pinXPoint = centerPoint + 5;
        pinYPoint = yPoint - 30;
    }
}

CGRect pinFrame = CGRectMake(pinXPoint, pinYPoint, 80, 80);

[self.pinImageView setFrame:pinFrame];
[self.scrollview addSubview:self.pinImageView];
[self.view bringSubviewToFront:self.pinImageView];

// add 30-pt "padding" at the bottom
initialYPoint += 30;

// set contentSize
self.scrollview.contentSize = CGSizeMake(cellWidth, initialYPoint);

// we want to initially see the "Start Rocket" visible at the bottom of the scroll view
CGFloat yOffset = scrollview.contentSize.height - scrollview.bounds.size.height;
scrollview.contentOffset = CGPointMake(0, yOffset);

希望它有所帮助 - 如果有任何不清楚的地方,请尽管问:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多