Implement paging scroll with AutoLayout

Paging scroll view

UIScrollView's pagingEnabled attribute is used to control whether a tab to scroll. In some applications will apply to this one feature, the most typical is the application icon in the list of the desktop phone. These interfaces often are relatively independent of each page function, the system also provides UIPageViewController to achieve this page scrolling function.
Implement paging scrolling UI implementations are generally the outermost layer of a UIScrollView. Then UIScrollView which is a general view of the container containerView. Vessel was added N pages view views, the horizontal tab height of the container for scrolling and scrolling the view of the same view, and the width is multiplied by the number of width of the rolling view page view, the size of the page and to scroll the view is consistent with the view, for tab width of the container for vertical scrolling and scrolling the view of the same view, and the height is the height multiplied by the number of page views scrolling the view, and the size of the page is scrolled views maintain a consistent view. Each page view in which respective entries view. The overall effect is as follows:


1432482-3a9cfcd5dcab061e.png
Page scrolling UI layout

AutoLayout implement paging rolling method

AutoLayout code to implement a rolling level UI page according to the above structure here. Here is the code constraint setting after iOS9 provide relevant API.

- (void)loadView {
    
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    if (@available(iOS 11.0, *)) {
        scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        // Fallback on earlier versions
    }
    scrollView.pagingEnabled = YES;
    scrollView.backgroundColor = [UIColor whiteColor];
    self.view = scrollView;
    
    //建立容器视图
    UIView *containerView = [UIView new];
    containerView.translatesAutoresizingMaskIntoConstraints = NO;
    [scrollView addSubview:containerView];
    
    //设置容器的四个边界和滚动视图保持一致的约束。
    [containerView.leftAnchor constraintEqualToAnchor:scrollView.leftAnchor].active = YES;
    [containerView.topAnchor constraintEqualToAnchor:scrollView.topAnchor].active = YES;
    [containerView.rightAnchor constraintEqualToAnchor:scrollView.rightAnchor].active = YES;
    [containerView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor].active = YES;
    //容器视图的高度和滚动视图保持一致。
    [containerView.heightAnchor constraintEqualToAnchor:scrollView.heightAnchor].active = YES;

    //添加页视图
    NSArray<UIColor*> *colors = @[[UIColor redColor],[UIColor greenColor], [UIColor blueColor]];
    NSMutableArray<UIView*> *pageViews = [NSMutableArray arrayWithCapacity:colors.count];
    NSLayoutXAxisAnchor *prevLeftAnchor = containerView.leftAnchor;
    for (int i = 0; i < colors.count; i++)
    {
        //建立页视图
        UIView *pageView = [UIView new];
        pageView.backgroundColor = colors[i];
        pageView.translatesAutoresizingMaskIntoConstraints = NO;
        [containerView addSubview:pageView];
        
        //页视图分别从左往右排列,第1页的左边约束是容器视图的左边,其他页的左边约束则是前面兄弟视图的右边。
        [pageView.leftAnchor constraintEqualToAnchor:prevLeftAnchor].active = YES;
        //每页的顶部约束是容器视图。
        [pageView.topAnchor constraintEqualToAnchor:containerView.topAnchor].active = YES;
        //每页的宽度约束是滚动视图
        [pageView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor].active = YES;
        //每页的高度约束是滚动视图
        [pageView.heightAnchor constraintEqualToAnchor:scrollView.heightAnchor].active = YES;
        
        prevLeftAnchor = pageView.rightAnchor;
        
        [pageViews addObject:pageView];
        
    }
    
    //关键的一步,如果需要左右滚动则将容器视图中的最右部子视图这里是B的右边边界依赖于容器视图的右边边界。
    [pageViews.lastObject.rightAnchor constraintEqualToAnchor:containerView.rightAnchor].active = YES;
    
    //这里可以为每个页视图添加不同的条目视图,具体实现大家自行添加代码吧。

}

The following are results of FIG runtime:


1432482-aab2c027bda5c701.gif
Page Scroll

MyLayout implement paging rolling method

You can also use MyLayout to achieve the ability to scroll the page layout library. MyLayout Layout Library is a powerful suite of open-source author UI layout library.
You can choose from github address: https://github.com/youngsoft/MyLinearLayout downloaded or imported from podfile in:

pod  'MyLayout'

Use MyLayout. The following is a specific code used to implement paging rolling MyLayout.

//
#import <MyLayout.h>

- (void)loadView {
    
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    if (@available(iOS 11.0, *)) {
        scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        // Fallback on earlier versions
    }
    scrollView.pagingEnabled = YES;
    scrollView.backgroundColor = [UIColor whiteColor];
    self.view = scrollView;
    
    
    //建立一个水平线性布局容器视图
    MyLinearLayout *containerView = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Horz];
    containerView.myVertMargin = 0;  //水平线性布局的上下边界和滚动视图保持一致,这里也会确定线性布局的高度。
    containerView.gravity = MyGravity_Vert_Fill | MyGravity_Horz_Fill;  //设置线性布局中的所有子视图均分和填充线性布局的高度和宽度。
    [scrollView addSubview:containerView];
    
    
    //添加页视图
    NSArray<UIColor*> *colors = @[[UIColor redColor],[UIColor greenColor], [UIColor blueColor]];
    NSMutableArray<UIView*> *pageViews = [NSMutableArray arrayWithCapacity:colors.count];
    for (int i = 0; i < colors.count; i++)
    {
        //建立页视图
        UIView *pageView = [UIView new];
        pageView.backgroundColor = colors[i];
        [containerView addSubview:pageView];
        
        //因为线性布局通过属性gravity的设置就可以确定子页视图的高度和宽度,再加上线性布局的特性,所以页视图不需要设置任何附加的约束。
        
        [pageViews addObject:pageView];
        
    }
    
    //关键的一步, 设置线性布局的宽度是滚动视图的倍数
    containerView.widthSize.equalTo(scrollView.widthSize).multiply(colors.count);
    
    
    //这里可以为每个页视图添加不同的条目视图,具体实现大家自行添加代码吧。

}

MyLayout achieve paging function desktop icon list

The flow layout MyLayout MyFlowLayout provided in a similar capacity and flex-box, some features even better than the latter. Flow arrangement used in some regular array of sub-view scene, such as the ability to present example icon list scrolling tab. The following is a specific implementation code.

- (void)loadView {
    
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    if (@available(iOS 11.0, *)) {
        scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        // Fallback on earlier versions
    }
    scrollView.pagingEnabled = YES;
    scrollView.backgroundColor = [UIColor whiteColor];
    self.view = scrollView;
    
    
    //建立一个垂直数量约束流式布局:每列展示3个子视图,每页展示9个子视图,整体从左往右滚动。
    MyFlowLayout *containerView = [MyFlowLayout flowLayoutWithOrientation:MyOrientation_Vert arrangedCount:3];
    containerView.pagedCount = 9; //pagedCount设置为非0时表示开始分页展示的功能,这里表示每页展示9个子视图,这个数量必须是arrangedCount的倍数。
    containerView.wrapContentWidth = YES; //设置布局视图的宽度由子视图包裹,当垂直流式布局的这个属性设置为YES,并和pagedCount搭配使用会产生分页从左到右滚动的效果。
    containerView.myVertMargin = 0; //容器视图的高度和滚动视图保持一致。
   
    containerView.subviewHSpace = 10;
    containerView.subviewVSpace = 10;  //设置子视图的水平和垂直间距。
    containerView.padding = UIEdgeInsetsMake(5, 5, 5, 5); //布局视图的内边距设置。
    [scrollView addSubview:containerView];

    
    //建立条目视图
    for (int i = 0; i < 40; i++)
    {
        UILabel *label = [UILabel new];
        label.textAlignment = NSTextAlignmentCenter;
        label.backgroundColor = [UIColor greenColor];
        label.text = [NSString stringWithFormat:@"%d",i];
        [containerView addSubview:label];
    }
    
    
    //获取流式布局的横屏size classes,并且设置设备处于横屏时,每排数量由3个变为6个,每页的数量由9个变为18个。
    MyFlowLayout *containerViewSC = [containerView fetchLayoutSizeClass:MySizeClass_Landscape copyFrom:MySizeClass_wAny | MySizeClass_hAny];
    containerViewSC.arrangedCount = 6;
    containerViewSC.pagedCount = 18;

From the above code can be seen that the ability to list icon paging rolling to achieve, mainly on the flow layout view acts as a container set some properties, do not need to set any constraint entry, but also supports horizontal and vertical screen of the next page the number of different display capabilities. Less entire function code, by contrast UICollectionView to achieve the same functionality for simplicity and much easier. Here is the effect of running:


1432482-78037c4ea8788c8e.gif
Page icon renderings

Horizontal and vertical screen switch

For the scroll view with the paging function, when there is need to support horizontal and vertical screen interface effect may switch the screen anyway when staying in the middle of two pages instead of scrolling by page appears. The reason is that whether or not the paging scrolling page scrolling, when scrolling is by adjusting the scroll view of contentOffset to achieve. ContentOffset without adjustment value corresponding views are vertical when the scroll screen switching, thus leading to a scroll position when switching the direction of the screen is abnormal. The solution is to fix the value contentOffset in the respective callback method when the screen scrolls to solve this problem. For example, we can add the following code in the protocol controller sizeclass method changes the view screen handover:

- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection
{
    [super traitCollectionDidChange:previousTraitCollection];
    
    UIScrollView *scrollView = (UIScrollView*)self.view;
    
    //根据当前的contentOffset调整到正确的contentOffset
    int pageIndex = scrollView.contentOffset.x / scrollView.frame.size.width;
    int pages = scrollView.contentSize.width / scrollView.frame.size.width;
    if (pageIndex >= pages)
        pageIndex = pages - 1;
    if (pageIndex < 0)
        pageIndex = 0;
    
    scrollView.contentOffset = CGPointMake(pageIndex * scrollView.frame.size.width, scrollView.contentOffset.y);
    
}

Guess you like

Origin blog.csdn.net/weixin_33912638/article/details/90840304