IOS - Pure AutoLayout and UIScrollView not scrolling

This is my first time using UIScrollViews with a pure Autolayout approach. This is what the view hierarchy looks like

view
-scrollview
--view1
--view2
--view3

      

scrollview must contain view1 | view2 | view3 in that order.

I have set the scroll width, height, center and bottom space for the view. The created objects view1, view2 and view3 have their own width and height constraints in the updateConstraints method. Additionally, some restrictions are provided in the code. For what reason is this scrolling not scrolling from left to right? I have read literally every tutorial I can find on the internet about creating and adding subroutines to a UIScrollView programmatically with auto layout. I found some mention of providing four different constraints: leading, trailing, top and bottom for each view added as a subview to the scrollview. Are these the only NSLayoutAttributes that can be specified? How are attributes related,such as NSLayoutAttribueLeft or NSLayoutAttribueRight? I also read the documentation on the Apple website, namelyhttps://developer.apple.com/library/ios/technotes/tn2154/_index.html . I have the setup I currently have. Everything is done with code.

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.dataSource = @[ [[PCCGenericRating alloc] initWithTitle:@"Easiness"
                                                      andMessage:@"WHAT A JOKERRRR"
                                                    andVariatons:@[ @"very easy", @"easy", @"moderate", @"hard", @"very hard"]],

                         [[PCCGenericRating alloc] initWithTitle:@"Joker"
                                                      andMessage:@"WHAT A JOKERRRR"
                                                    andVariatons:@[ @"very easy", @"easy", @"moderate", @"hard", @"very hard"]],

                         [[PCCGenericRating alloc] initWithTitle:@"Difficulty"
                                                      andMessage:@"YOu are not difficult at all"
                                                    andVariatons:@[ @"very easy", @"easy", @"moderate", @"hard", @"very hard"]]
                       ];
    [self initView];
}

- (void)initView {
    CGFloat navigationBarHeight = self.navigationController.navigationBar.frame.size.height;
    CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

    CGFloat heightDifference = navigationBarHeight + statusBarHeight;

    self.scrollView = [[UIScrollView alloc] init];
    self.scrollView.delegate = self;
    [self.scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
    self.scrollView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.scrollView];


    //setup constraints
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeWidth
                                                                                    relatedBy:NSLayoutRelationEqual
                                                                                       toItem:self.view
                                                                                    attribute:NSLayoutAttributeWidth
                                                                                   multiplier:1.0f
                                                                                     constant:0.0f]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeHeight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeHeight
                                                         multiplier:1.0f
                                                           constant:-heightDifference]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeCenterX
                                                                                    relatedBy:NSLayoutRelationEqual
                                                                                       toItem:self.view
                                                                                    attribute:NSLayoutAttributeCenterX
                                                                                   multiplier:1.0f
                                                                                     constant:0.0f]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeBottom
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1.0f
                                                           constant:0.0]];

    [self.dataSource enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        PCCGenericRating *rating = (PCCGenericRating *)obj;
        PCCGenericRatingView *ratingView = [self createViewWithRating:rating];
        [self.scrollView addSubview:ratingView];

        int multiplier = (idx == 0) ? 1 : (int) (idx + 1) ;
        [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:ratingView
                                                                        attribute:NSLayoutAttributeCenterX
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:self.scrollView
                                                                        attribute:NSLayoutAttributeCenterX
                                                                       multiplier:multiplier
                                                                         constant:0.0f]];

        [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:ratingView
                                                                    attribute:NSLayoutAttributeCenterY
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:self.scrollView
                                                                    attribute:NSLayoutAttributeCenterY
                                                                   multiplier:1.0f
                                                                     constant:0.0f]];
    }];
}

- (PCCGenericRatingView *)createViewWithRating:(PCCGenericRating *)rating {
    PCCGenericRatingView *view = [PCCGenericRatingView genericRatingViewWithTitle:rating.title andMessage:rating.message];
    return view;
}

      

After printing the scrollview constraints, they look good to me:

po self.scrollView.constraints
<__NSArrayM 0x115b051f0>(
<NSLayoutConstraint:0x1145d9290 PCCGenericRatingView:0x114579880.centerX == UIScrollView:0x11458d4b0.centerX>,
<NSLayoutConstraint:0x1145d9410 PCCGenericRatingView:0x114579880.centerY == UIScrollView:0x11458d4b0.centerY>,
<NSLayoutConstraint:0x1145d9dd0 PCCGenericRatingView:0x1145d9560.centerX == 2*UIScrollView:0x11458d4b0.centerX>,
<NSLayoutConstraint:0x1145d9e40 PCCGenericRatingView:0x1145d9560.centerY == UIScrollView:0x11458d4b0.centerY>,
<NSLayoutConstraint:0x1145da6b0 PCCGenericRatingView:0x1145d9e90.centerX == 3*UIScrollView:0x11458d4b0.centerX>,
<NSLayoutConstraint:0x1145da730 PCCGenericRatingView:0x1145d9e90.centerY == UIScrollView:0x11458d4b0.centerY>
)

      

Here's a screenshot of what it looks like: simulator

It seems strange to me that the last item in the data source is the first view controller to show in the scrollview when it should be the last view. It also doesn't scroll left-right as it should.

+3


source to share


2 answers


Make sure yours top_constraint

for view1 and bottom_constraint

for view3 will match your scrolling constraints . Otherwise scrollview contentSize: {0, 0}

.



+4


source


When you are printing your constraints try printing scrollview.contentSize, it will probably be 0,0 and that is where your problem is. As far as I know, and as you mentioned in your post, you must explicitly set the subviews of the scrollview to the top-bottom left and right constraints of the scrollviews. In doing so, they automatically set the contentSize of the scroll, which will allow it to scroll. It looks like you are only setting the X and centerY center constraints which will not set the scrollviews contentSize for what you need.

Try to install them programmatically (this is pseudocode, but you get the idea):



  • view1.topConstraint = scrollView.topConstraint
  • view1.leftConstraint = scrollView.leftConstraint
  • view3.bottomConstraint = scrollView.bottomConstraint
  • view3.rightConstraint = scrollView.rightConstraint

If you set it all up correctly, your scroll will scroll correctly. Just remember to check the content, and if the content is 0.0 your limits will not be configured correctly.

+3


source







All Articles