Photos app-like gap between pages in UIScrollView with pagingEnabled

后端 未结 8 1169
北恋
北恋 2020-12-04 08:52

UIScrollView in paging mode assumes the pages are located right next to each other, with no gap. However if you open a photo in the Photos app and swipe through photos, you

8条回答
  •  无人及你
    2020-12-04 09:21

    To avoid messing with UIScrollView's frame, you could subclass UIScrollView and override layoutSubviews to apply an offset to each page.

    The idea is based on the following observations:

    1. When zoomScale !=1, the offset is zero when it is at the left / right edge
    2. When zoomScale ==1, the offset is zero when it is at the visible rect centre

    Then the following code is derived:

    - (void) layoutSubviews
    {
        [super layoutSubviews];
    
        // Find a reference point to calculate the offset:
        CGRect bounds = self.bounds;
        CGFloat pageGap = 8.f;
        CGSize pageSize = bounds.size;
        CGFloat pageWidth = pageSize.width;
        CGFloat halfPageWidth = pageWidth / 2.f;
        CGFloat scale = self.zoomScale;
        CGRect visibleRect = CGRectMake(bounds.origin.x / scale, bounds.origin.y / scale, bounds.size.width / scale, bounds.size.height / scale);
        CGFloat totalWidth = [self contentSize].width / scale;
        CGFloat scrollWidth = totalWidth - visibleRect.size.width;
        CGFloat scrollX = CGRectGetMidX(visibleRect) - visibleRect.size.width / 2.f;
        CGFloat scrollPercentage = scrollX / scrollWidth;
        CGFloat referencePoint = (totalWidth - pageWidth) * scrollPercentage + halfPageWidth;
    
        // (use your own way to get all visible pages, each page is assumed to be inside a common container)
        NSArray * visiblePages = [self visiblePages];
    
        // Layout each visible page:
        for (UIView * view in visiblePages)
        {
            NSInteger pageIndex = [self pageIndexForView:view]; // (use your own way to get the page index)
    
            // make a gap between pages
            CGFloat actualPageCenter = pageWidth * pageIndex + halfPageWidth;
            CGFloat distanceFromRefPoint = actualPageCenter - referencePoint;
            CGFloat numOfPageFromRefPoint = distanceFromRefPoint / pageWidth;
            CGFloat offset = numOfPageFromRefPoint * pageGap;
            CGFloat pageLeft = actualPageCenter - halfPageWidth + offset;
    
            view.frame = CGRectMake(pageLeft, 0.f, pageSize.width, pageSize.height);
        }
    }
    

提交回复
热议问题