How to Prevent Infinite Scrolling with UIScrollView in iOS and Create a Fixed Height Layout with Dynamic Labels.

Understanding the Problem and Solution

The question presented involves adding a UIScrollView and two UIViews inside it, with one label placed vertically within each view. The goal is to set the height of the UIScrollView so that it appears at the bottom of the page when scrolled. However, the provided code results in an infinite scroll.

Introduction to UIScrollView

A UIScrollView is a control that allows users to interactively scroll through content that does not fit entirely within its view. This makes it ideal for applications with large amounts of data or images that need to be displayed in a continuous manner.

To achieve the desired layout, we must carefully manage the height and content size of the UIScrollView to prevent infinite scrolling.

Setting up the Views

First, let’s create our views:

UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320, 480)];
UIView *myview = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0, 320.0, 400)];
[myview setBackgroundColor:[UIColor grayColor]];

In the provided solution, myview has a fixed height of 400 pixels. This means that when we add labels to it and use the sizeToFit method, they will be automatically sized based on their content. However, this can lead to issues if the labels’ heights do not fit within the allocated space.

Handling Dynamic Label Height

To handle dynamic label height, we need to calculate the size of our labels and adjust the frame accordingly:

NSString *strText = @"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).";
float y = 0;
CGSize textViewSize = [strText sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14.0]
                                  constrainedToSize:CGSizeMake(320, FLT_MAX)
                                      lineBreakMode:NSLineBreakByWordWrapping];

[lable setText:strText];
[lable setFrame:CGRectMake(lable.frame.origin.x, lable.frame.origin.y, 320,roundf(textViewSize.height))];

We also need to calculate the size of slabel similarly:

y = lable.frame.origin.y+textViewSize.height;
CGSize slabelTextViewSize = [strText sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14.0]
                                  constrainedToSize:CGSizeMake(320, FLT_MAX)
                                      lineBreakMode:NSLineBreakByWordWrapping];

[slabel setText:strText];
[slabel setFrame:CGRectMake(slabel.frame.origin.x, y, 320,roundf(textViewSize.height))];
y = slabel.frame.origin.y+textViewSize.height;

Managing the Scrolls View Content Size

We need to set scrollview.contentSize to match our myview height plus some padding:

scrollview.contentSize = CGSizeMake(scrollview.contentSize.width, myview.frame.size.height+15);

This will ensure that when we scroll through myview, it appears at the bottom of the page as desired.

Putting It All Together

Here’s the complete code:

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
    @autoreleasepool {
        UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320, 480)];
        UIView *myview = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0, 320.0, 400)];
        [myview setBackgroundColor:[UIColor grayColor]];
        
        NSString *strText = @"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).";
        
        UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0, 320,FLT_MAX)];
        UILabel *slabel = [[UILabel alloc] initWithFrameCGRectMake(0.0, FLT_MAX, 320, FLT_MAX)];
        
        float y = 0;
        CGSize textViewSize = [strText sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14.0]
                                              constrainedToSize:CGSizeMake(320, FLT_MAX)
                                                  lineBreakMode:NSLineBreakByWordWrapping];
        [lable setText:strText];
        [lable setFrame:CGRectMake(lable.frame.origin.x, lable.frame.origin.y, 320,roundf(textViewSize.height))];
        y = lable.frame.origin.y+textViewSize.height;
        CGSize slabelTextViewSize = [strText sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14.0]
                                              constrainedToSize:CGSizeMake(320, FLT_MAX)
                                                  lineBreakMode:NSLineBreakByWordWrapping];
        [slabel setText:strText];
        [slabel setFrame:CGRectMake(slabel.frame.origin.x, y, 320,roundf(textViewSize.height))];
        y = slabel.frame.origin.y+textViewSize.height;
        
        [myview addSubview:lable];
        [myview addSubview:slabel];
        scrollview.contentSize = CGSizeMake(scrollview.contentSize.width, myview.frame.size.height+15);
        [scrollview addSubview:myview];
        [self.view addSubview:scrollview];
    }
    return 0;
}

This code creates a UIScrollView, UIView and two labels. The height of the ScrollView is set to match the height of its content plus some padding, ensuring that when scrolled through, it appears at the bottom of the page as desired.


Last modified on 2024-02-11