编程

当前位置:永利皇宫463登录 > 编程 > 自定义UIScrollView翻页宽度,UIScrollerView自定义翻页

自定义UIScrollView翻页宽度,UIScrollerView自定义翻页

来源:http://www.makebuLuo.com 作者:永利皇宫463登录 时间:2019-09-15 08:51
  • 0 》那么些方案,也正是先在数组的末段插入原数组的率先个要素,再在第一个职位插入原数组的末尾三个因素;获得如下图效果:(注意看:第贰个向最后一个,最后向第二个巡回过渡的时候有个Bug哦)

    self.imageArray = [NSMutableArray arrayWithArray:_images]; [self.imageArray addObject:_images[0]]; [self.imageArray insertObject:_images.lastObject atIndex:0]; //发轫化时的x偏移量要向前多二个单位的_currentPageSize.width _scrollerView.contentOffset = CGPointMake(_currentPageSize.width * (self.currentPageIndex + 1), 0);

有的宏定义

#define kScreenWidth ([UIScreen mainScreen].bounds.size.width)
#define kScreenHeight ([UIScreen mainScreen].bounds.size.height)
#define kContentWidth 250
#define kContentHeight 400
#define kPadding 20

 

图片 1Bug.gif

不足

自家也不掌握别人是怎么落到实处这种ScrollView效果的,这么些方法本人也不知道是否最棒的,只是自己能想到的情势,当然有个别许相差,比方都交由小的ScrollView管理,显示的剧情要是有button,button在normall,highlighted,selected状态设置了不相同的体制,该兑现是平昔不章程展现的,因为本身只是发送了多少个平地风波过去。所以纵然你有更加好的章程,不要紧公布一下!

用到UIScrollview的翻页效果时,不时须要出示一部分左右的剧情,不过UIScrollView的PagingEnabled只能翻过整页,下边多少个大致的设置就能够兑现

图片 2快来赞作者啊.gif

BigScrollView

self.bigScrollView = ({
        UIScrollView *scroll = [[UIScrollView alloc] init];
        scroll.clipsToBounds = NO;
        scroll.showsHorizontalScrollIndicator = NO;
        [self addSubview:scroll];
        [scroll makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self).offset(UIEdgeInsetsMake(0, kPadding / 2, 0, kPadding / 2));
        }];

        UIView *content = [[UIView alloc] init];
        [scroll addSubview:content];
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(scroll);
            make.height.equalTo(scroll);
        }];

        UIView *lastView;

        for (NSInteger i=0; i<4; i++) {
            UIView *view = [[UIView alloc] init];
            view.backgroundColor = [self randomColor];
            [content addSubview:view];
            if (i == 0) {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(kPadding / 2);
                    make.top.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            } else {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(lastView.right).offset(kPadding);
                    make.top.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            }
            lastView = view;

//            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//            [btn setBackgroundColor:[UIColor lightGrayColor]];
//            [btn setTitle:@"Button" forState:UIControlStateNormal];
//            [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
//            [view addSubview:btn];
//            [btn makeConstraints:^(MASConstraintMaker *make) {
//                make.centerX.equalTo(view);
//                make.width.equalTo(100);
//                make.height.equalTo(50);
//                make.bottom.equalTo(-50);
//            }];
        }
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(lastView.right).offset(kPadding / 2);
        }];

        scroll;
    });

技术点:

WSLScrollView功效描述:那是在承继UIView的基本功上行使UIScrollerView举行了包装,帮忙循环轮播、自动轮播、自定义时间距离、图片间隔、当前页码和图片大小,选用Block重返当前页码和管理当下点击事件的二个View。

其它

面前提及大的ScrollView不参加顾客事件,那该怎么完毕呢?

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return self.smallScrollView;
}

正是那样轻便。。。全数事件都让底下的小的ScrollView去管理,达成ScrollView的代办方法,进而拉动大的ScrollView滑动

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView == self.smallScrollView) {
        [self.bigScrollView setContentOffset:scrollView.contentOffset animated:NO];
    }
}

至于滑动的就管理完了

  1. 创办贰个承接UIView的视图,并安装clipsToBounds= YES

  2. 丰富三个UIscrollView控件,将其升幅设置为自定义翻页的增进率

  3. 设置UIScrollview 的clipsToBounds= NO

  4. 管教本View的宽度大于UIScrollView的宽窄用于展现预览内容

②、接下去贯彻循环的功力:作者深信广大人也都会想到 《 4 + 0 - 1 - 2 - 3 - 4

前言

好奇心早报的片段文章页面是那样显示的,点击在那之中一个就足以进来单个的稿子实际情况页面,于是想了须臾间该怎么落实。

#define kLJItemWidth 240

@implementation MyScrollview    {

    UIScrollView *scrollview;
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
          scrollview = ({
              UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(40, 0, kLJItemWidth, frame.size.height)];
              scroll.pagingEnabled = YES;
              scroll.clipsToBounds = NO;
              scroll;
          })                                                                                      ;

        [self addSubview:scrollview];
                            self.clipsToBounds = YES;
    }

    return self;
}

-(void)loadImages:(NSArray *)array{
    int index = 0;
    [scrollview.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

    for(NSString * name in array){
        UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:name]];
        iv.contentMode = UIViewContentModeScaleToFill;
        CGRect fra = iv.frame;
        fra.size.width = kLJItemWidth;
        fra.origin.x = index * kLJItemWidth;
        iv.frame = fra;

        [scrollview addSubview:iv];
        index++;
    }
    scrollview.contentSize = CGSizeMake(scrollview.frame.size.width*index, scrollview.frame.size.height);
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *view = [super hitTest:point withEvent:event];
    if ([view isEqual:self])
    {
        for (UIView *subview in scrollview.subviews)
        {
            CGPoint offset = CGPointMake(point.x - scrollview.frame.origin.x + scrollview.contentOffset.x - subview.frame.origin.x,
                    point.y - scrollview.frame.origin.y + scrollview.contentOffset.y - subview.frame.origin.y);

            if ((view = [subview hitTest:offset withEvent:event]))
            {
                return view;
            }
        }
        return scrollview;
    }
    return view;
}

@end

图片 3③效果.gif

点击事件

上边正是拍卖顾客点击单个页面了,给小的ScrollView增添单击手势,然后将点转化到大的ScrollView即达成了单击手势的检查实验,假若页面上有button,推断点是不是在button内进而管理

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(smallScrollTap:)];
        [scroll addGestureRecognizer:tap];

- (void)smallScrollTap:(UITapGestureRecognizer *)sender{
    [self.bigSubViews removeAllObjects];
    [self listSubviewsOfView:self.bigScrollView];
    CGPoint bigPoint = [sender locationInView:self.bigScrollView];
    for (UIView *view in self.bigSubViews.reverseObjectEnumerator) {
        if ([view isKindOfClass:[UIButton class]]) {
            CGPoint buttonPoint = [view convertPoint:bigPoint fromView:self.bigScrollView];
            if (CGRectContainsPoint(view.bounds, buttonPoint)) {
                [(UIButton *)view sendActionsForControlEvents:UIControlEventTouchUpInside];
            }
        }
    }
}

- (void)listSubviewsOfView:(UIView *)view {
    NSArray *subviews = [view subviews];
    if ([subviews count] == 0) return;
    for (UIView *subview in subviews) {
        [self.bigSubViews addObject:subview];
        [self listSubviewsOfView:subview];
    }
}

ok! 下面是代码,为了有助于,使用图片作为彰显的每一页

图片 4①效果.gif

思路

一齐首想的是用二个ScrollView去落到实处,后来发觉一个ScrollView达成的话最后一页会有标题,也尚未想到应用方案,于是就用七个ScrollView来落实

图片 5

荧屏快速照相 2017-02-21 深夜3.32.44.png

图片 6

荧屏快速照相 2017-02-21 上午3.32.55.png

率先张图青古铜色标识的是上面的小的ScrollView,它的法力是达成翻页效果,第二张图深紫灰标志的是上层的大的ScrollView,用来显示内容,用小的UIScrollView来拉动大的ScrollView滑动,大的ScrollView不出席客户滑动事件

5. 重写本View的hittest方法,为了保障顾客滑动UIscrollview以外的长空时也得以触发UIscrollview滑动

消除上述Bug的方案正是选用UIScrollView的多个代理方法;在上下循环过渡处,刚早先扶拖拉机拽时就在Bug的职分画上相应的视图;即《 3 + 4 + 0 - 1 - 2 - 3 - 4 + 0 + 1》,甘休拖拽之后,再改造UIScrollView的contentOffset,不推动画;

实现

假若体现4页剧情

_scrollerView.clipsToBounds = NO;//处理超过父视图部分不能点击的问题,重写UIView里的这个方法- hitTest:point withEvent:(UIEvent *)event { if ([self pointInside:point withEvent:event]) { CGPoint newPoint = [_scrollerView convertPoint:point fromView:self]; for (UIImageView * imageView in _scrollerView.subviews) { if (CGRectContainsPoint(imageView.frame, newPoint)) { CGPoint newSubViewPoint = [imageView convertPoint:point fromView:self]; return [imageView hitTest:newSubViewPoint withEvent:event]; } } } return nil;}

预览

图片 7

ScrollView.gif

直白上海市中华全国总工会的效果图,要求或感兴趣的各路大神朋友请指教:

SmallScrollView

亟待静心的是,小的ScrollView最终一页的大幅须要计算一下

self.smallScrollView = ({
        UIScrollView *scroll = [[UIScrollView alloc] init];
        scroll.delegate = self;
        scroll.showsHorizontalScrollIndicator = NO;
        scroll.pagingEnabled = YES;
        [self addSubview:scroll];
        [scroll makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self).offset(UIEdgeInsetsMake(0, kPadding / 2, 0, kScreenWidth - kPadding - kContentWidth - kPadding / 2));
        }];

        UIView *content = [[UIView alloc] init];
        [scroll addSubview:content];
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(scroll);
            make.height.equalTo(scroll);
        }];

        UIView *lastView;

        for (NSInteger i=0; i<4; i++) {
            UIView *view = [[UIView alloc] init];
            [content addSubview:view];
            if (i == 0) {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(kPadding / 2);
                    make.top.bottom.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            } else if (i == 3) {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(lastView.right).offset(kPadding);
                    make.top.bottom.equalTo(content);
                    make.width.equalTo(kContentWidth - (kScreenWidth - kPadding * 2 - kContentWidth));
                    make.height.equalTo(kContentHeight);
                }];
            } else {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(lastView.right).offset(kPadding);
                    make.top.bottom.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            }
            lastView = view;
        }
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(lastView.right).offset(kPadding / 2);
        }];

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(smallScrollTap:)];
        [scroll addGestureRecognizer:tap];

        scroll;
    });

然后设置大家屡见不鲜会忽略UIScrollerView的四个属性clipsToBounds为NO,私下认可是Yes,你拜访到_scrollerView另外部分周围的图纸,可是你会意识那部分周围的图样不会响应在它上面包车型地铁另外触摸事件,因为那有些子视图高出了它的父视图,可以用响应链机制化解这一个难题:

①、首先像往常一样写一个主干的UIScrollerView,会获得下图:

 _scrollerView = [[UIScrollView alloc] init]; _scrollerView.frame = CGRectMake((SELF_WIDTH - _currentPageSize.width) / 2, 0, _currentPageSize.width, _currentPageSize.height); _scrollerView.delegate = self; _scrollerView.pagingEnabled = YES; _scrollerView.showsHorizontalScrollIndicator = NO; [self addSubview:_scrollerView];
- statrScroll:second{ if (_timer == nil && _isTimer) { _timer = [NSTimer scheduledTimerWithTimeInterval:second target:self selector:@selector(autoNextPage) userInfo:nil repeats:YES]; }}- autoNextPage{ [_scrollerView setContentOffset:CGPointMake( _currentPageSize.width * (_currentPageIndex + 1 + 1), 0) animated:YES]; if (_currentPageIndex + 2 == self.imageArray.count - 1) { //是为了解决自动滑动到最后一页再从头开始的连贯性问题 [_scrollerView addSubview:self.firstView]; }}- scrollViewDidScroll:(UIScrollView *)scrollView{ CGFloat index = scrollView.contentOffset.x/_currentPageSize.width; if (index == 0 ) { _currentPageIndex = self.imageArray.count - 1- 2; }else if(index < 1){ }else if(index == self.imageArray.count - 1 || index == 1){ _currentPageIndex = 0; //是为了解决自动滑动到最后一页再从头开始的连贯性问题 [_scrollerView setContentOffset:CGPointMake( _currentPageSize.width , 0) animated:NO]; }else if(index == ceil{ _currentPageIndex = index - 1 ; } if (self.scrollEndBlock != nil) { self.scrollEndBlock(_currentPageIndex); }}
//开始拖拽时执行- scrollViewWillBeginDragging:(UIScrollView *)scrollView{ //开始拖拽时停止计时器 [self.timer invalidate]; self.timer = nil; // 3 + 4 + 0 - 1 - 2 - 3 - 4 + 0 + 1 NSInteger index = scrollView.contentOffset.x/_currentPageSize.width; //是为了解决循环滚动的连贯性问题 if (index == 1) { [self.scrollerView addSubview:self.lastView]; } if (index == self.imageArray.count - 2) { [self.scrollerView addSubview:self.firstView]; }}//结束拖拽时执行- scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ NSInteger index = scrollView.contentOffset.x/_currentPageSize.width; //停止拖拽时打开计时器 if  { [self statrScroll:_second]; } //是为了解决循环滚动的连贯性问题 if (index == 0) { scrollView.contentOffset = CGPointMake(_currentPageSize.width * (self.imageArray.count - 2) , 0); } if (index == self.imageArray.count - 1) { scrollView.contentOffset = CGPointMake(_currentPageSize.width , 0); }}

图片 8总效果.gif

③落到实处机械漏刻自动循环轮播效能,供给化解的标题就是全进度过渡的时候,如下图所示:化解的思绪和上述邻近,首要代码已表明→WSLScrollView

图片 9基本UIScrollerView.png

图片 10组织暗中提示图.png

本文由永利皇宫463登录发布于编程,转载请注明出处:自定义UIScrollView翻页宽度,UIScrollerView自定义翻页

关键词:

上一篇:享用SDK分享技能内容施行与与原理分析

下一篇:没有了