iOS开发-自定义重用机制给ScrollerView添加子视图

其实这个问题我很早就想过,只是没有通过去敲代码实现,昨天有人提起,我就巧了一下

不知道大家打印郭tableview:cellforrow中cell初始的次数,也就是重用池中的cell个数,这个是固定的,比如屏幕最多可以显示4个cell那么重用池个数可能为5个6个或者7左右,我就想了如果scrollview去实现,子视图也应该是有一个个数的,那么如何去实现重用池呢?我想到了数组,可变数组,我在loadview中将scrollview的可滑动区域设置为10000,然后给scrollview每隔20个距离添加一个view共10个,在for循环中将这10个view添加到数组arr中,那么接下来怎么做呢,我是这么想的,当需要添加第11个时候,将第1个从数组中提出来,改变成第11个的frame,然后改变它到数组的最后一个,是不是就有了,同样如果上拉的时候怎么显示上一个呢?将数组的最后一个提出来。改变frame,然后改变它到数组的第一个位置。话说了这么多,下面贴代码吧。

//
//  ViewController.m
//  ScollerView重用
//
//  Created by monkeyheng on 8/5/15.
//  Copyright (c) 2015 monkeyheng. All rights reserved.
//

#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView *scrollView;
// 托管重用数组
@property (nonatomic, strong) NSMutableArray *arr;
// 需要添加到头部子视图的坐标Y值
@property (nonatomic, assign) CGFloat upY;
// 需要添加到尾部子视图的坐标Y
@property (nonatomic, assign) CGFloat downY;
// 拖动时候的偏移量
@property (nonatomic, assign) CGFloat offset;

@end

@implementation ViewController

- (void)loadView {
    [super loadView];
    // 初始化一个ScrollView 宽度为屏幕宽度 可滑动区域为10000
    self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 10000);
    self.scrollView.backgroundColor = [UIColor redColor];
    self.scrollView.delegate = self;
    [self.view addSubview:self.scrollView];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 添加初始子视图到Scrollview 共10个 可以根据实际情况调控或者算法调控
    NSInteger i = 0;
    for (i = 0; i < 10; i++) {
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, i * 100 +(i - 1) * 20, 375, 100)];
        view.backgroundColor = [UIColor blueColor];
        // 添加子视图到scrollview
        [self.scrollView addSubview:view];
        // 添加view到托管的重用数组
        [self.arr addObject:view];
    }
    // 下一个view的y点是
    i++;
    self.downY = i * 100 + (i - 1) * 20;
    self.upY = -120;
    self.offset = 0;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

// 拖动开始的时候
// scrollView 开始拖动
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // 记录拖动开始的偏移量
    self.offset = scrollView.contentOffset.y;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    // 判断上下滑 是否偏移量超出屏幕
    if (scrollView.contentOffset.y < 0 || scrollView.contentOffset.y > (10000 - 667)) {
        // 超出屏幕范围不做任何操作
    } else if ((scrollView.contentOffset.y - self.offset) > 0) {
        // 开始滑动的偏移量如果大于拖动的偏移量 手指拖动屏幕上拉
        // 上滑动
        if ((self.downY - (self.scrollView.contentOffset.y + 667)) < 150) {
            // 在尾部Y坐标距离屏幕底部150的时候
            // 取出数组的第一个元素
            UIView *view = [self.arr objectAtIndex:0];
            // 将头部Y坐标变为view的Y坐标 因为view要添加到尾部
            self.upY = view.frame.origin.y;
            // 移除数组第一个元素
            [self.arr removeObjectAtIndex:0];
            // 改变view的frame
            view.frame = CGRectMake(0, self.downY - 100 - 20, 375, 100);
            // 将view重新添加到数组
            [self.arr addObject:view];
            // 改变下一个的尾部坐标的Y值
            self.downY = self.downY + 100 + 20;

        }

    } else if((scrollView.contentOffset.y - self.offset) < 0){
        // 开始滑动的偏移量如果大于拖动的偏移量 手指拖动屏幕下拉
        // 下滑动
        if ((self.scrollView.contentOffset.y - self.upY) < 270) {
            // 在头部Y坐标距离屏幕顶端270的时候--》即将添加的头部view的尾部距离屏幕头部150
            // 取出数组的最后一个元素
            UIView *view = [self.arr lastObject];
            // 将尾部Y坐标变为view的Y坐标 因为view要添加到头部部
            self.downY = view.frame.origin.y;
            // 移除数组最后一个元素
            [self.arr removeObject:view];
            // 改变view的frame
            view.frame = CGRectMake(0, self.upY, 375, 100);
            // 将view重新添加到数组的头部
            [self.arr insertObject:view atIndex:0];
            // 改变下一个的头部坐标的Y值
            self.upY = self.upY - 100 - 20;
        }
    }
}

#pragma mark 懒加载
- (UIScrollView *)scrollView {
    if (_scrollView == nil) {
        _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    }
    return _scrollView;
}

- (NSMutableArray *)arr {
    if (_arr == nil) {
        _arr = [[NSMutableArray alloc] init];
    }
    return _arr;
}

@end

在来两张图片

启动模拟器的时候

滑动到中间的时候

滑动到最后一个的时候

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-17 00:46:56

iOS开发-自定义重用机制给ScrollerView添加子视图的相关文章

iOS开发-自己定义重用机制给ScrollerView加入子视图

事实上这个问题我非常早就想过,仅仅是没有通过去写程序实现,昨天有人提起,我就巧了一下 不知道大家打印郭tableview:cellforrow中cell初始的次数,也就是重用池中的cell个数.这个是固定的,比方屏幕最多能够显示4个cell那么重用池个数可能为5个6个或者7左右,我就想了假设scrollview去实现,子视图也应该是有一个个数的,那么怎样去实现重用池呢? 我想到了数组,可变数组,我在loadview中将scrollview的可滑动区域设置为10000.然后给scrollview每

IOS开发—UITableView重用机制的理解

引言 对于一个UITableView而言,可能需要显示成百上千个Cell,如果每个cell都单独创建的话,会消耗很大的内存.为了避免这种情况,重用机制就诞生了. 假设某个UITableView有100个数据需要显示,即需要100个Cell,然而屏幕中最多只能一次性显示10个Cell,那么有一个办法可以不用创建100cell,而只需要创建11(10+1)个. 理解 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowA

iOS开发-自定义后台显示图片(iOS7-Background Fetch的应用)

之前在用电池医生的时候, 发现它有这样一个功能:当应用进入后台的时候, 会显示另外一张图片覆盖App Switcher显示的界面. 效果如下: 变成----> 而这样的一个功能, 对于保护用户隐私还是挺有用的. 这就涉及到了Background Fetch的使用.当然, Background Fetch有更多,更有用的功能, 详见-->iOS 7学习:多任务处理之Background Fetch 下面就介绍下后台图片切换的实现. 1.程序配置后台模式 操作如下: 2. AppDelegate.

iOS开发- 自定义遮罩视图(引导, 功能说明)源码+解析

iOS开发- 自定义遮罩视图(引导, 功能说明)源码+解析 我们平时使用App的时候, 经常在第一次使用的时候, 会有类似"新手教程"之类的东西, 来引导我们应该如何使用这个App. 但是这个"新手教程"不同于常规的引导页(引导页指第一次打开App时候, 弹出的那种介绍视图. 他是静态的, 不需要与用户交互, 可以直接一页页翻, 或者直接跳过.)所谓的"新手教程", 就是按照App的提示, 一步步跟着完成. 那这个"新手教程"

文顶顶 iOS开发UI篇—在UIImageView中添加按钮以及Tag的参数说明

ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwithtag: 提示点:在xib中如果想要通过tag参数获取对应的控件(属性),不要把tag的参数设置为0,因为xib中所有的对象默认tag都为0,设置为0取不到对象. 二.ImageView中添加按钮(1)ImageView和Button的比较 Button按钮的内部可以放置多张图片(4),而Ima

IOS开发自定义CheckBox控件

IOS本身没有系统的CheckBox组件,但是实际开发中会经常用到,所以专门写了一个CheckBox控件,直接上代码 效果图: UICheckBoxButton.h文件如下: #import #import "Common.h" @interface UICheckBoxButton : UIControl { UILabel *label; UIImageView *icon; BOOL checked; id delegate; } @property (retain, nonat

IOS开发UI基础—在UIImageView中添加按钮以及Tag的参数说明

ios开发UI基础-在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwithtag: 提示点:在xib中如果想要通过tag参数获取对应的控件(属性),不要把tag的参数设置为0,因为xib中所有的对象默认tag都为0,设置为0取不到对象. 二.ImageView中添加按钮(1)ImageView和Button的比较 Button按钮的内部可以放置多张图片(4),而Im

iOS开发自定义时间选取器

又是一年的暑假日期而至,小孩子放假,都会到在外打工的父母身边.孩子想父母,父母也思念着自己的孩子.我身边的亲戚朋友的孩子 也都来了.这个暑假又该热闹起来. 努力什么时候都不晚 我有一个表妹,今年参加完高考,对自己的成绩不是特别满意.上次我回老家,刚好她给我一起来上海.准备来上海锻炼一下. 车上我问她,准备去哪上学?她说不想上了,想打工.我没有怎么劝她,我想让她体验一下打工的生活,她就知道还是上学好. 一个高中生,出来找工作,困难可想而知.经姐姐介绍,进了一家餐厅工作.工资也不是很高.干了两天,我

iOS自定义alertView,继承自UIView,可以添加子视图,标题图片+文字

自定义alertView,继承自UIView,可以在消息区域添加子视图:addCustomerSubview 标题可以有图片+文字构成, 只支持两个按钮操作 // - 在需要alert的控制器调用 alertView show 方法 CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:@"提示" message:@"dylan_lwb_" delegate:self cancelBu