Day 5:MMScrollPresenter,自定义滚动视图

 

MMScrollPresenter是一款很容易使用的滚动视图,支持各种自定义。视图可以设置标题和描述。在StoryBoard中使用也很方便。

MMScrollPresenter

Github地址:https://github.com/MitchellMalleo/MMScrollPresenter

Cocoapods安装:pod 'MMScrollPresenter'

Requirements :

  • ARC
  • iOS 5.0+

使用方法:

首先将MMScrollPresenter文件夹添加到自己的项目中,包括MMScrollPresenter.h/.m, MMScrollPage.h/.m, arrow/@2x.png。

UIImageView *mountainImage = [[UIImageView alloc] initWithImage:[UIImage 
    imageNamed:@"mountains.jpg"]];

[mountainImage setFrame:CGRectMake(0, 0, self.mmScrollPresenter.frame.size.width, 
    self.mmScrollPresenter.frame.size.height)];

MMScrollPage *firstPage = [[MMScrollPage alloc] init];
firstPage.titleLabel.text = @"Look a picture of mountains";
firstPage.detailLabel.text = @"I'm the detail text";
[firstPage.backgroundView addSubview:mountainImage];
firstPage.titleBackgroundColor = 
    [UIColor colorWithRed:119/255.0f green:92/255.0f blue:166/255.0f alpha:0.5];

[self.mmScrollPresenter setupViewsWithArray:@[firstPage]];

 

代码分析:

MMScrollPage是一个模型对象,继承NSObject,包括一个init初始化方法,和几个属性,例如:backgroundView、titleView、titleBackgroundColor、titleLabel、detailLabel、icon。

在init方法中,主要对所有属性进行了初始化,设置默认值等。

- (instancetype)init
{
    self = [super init];
    
    if(self)
    {
        self.titleView = [[UIView alloc] init];
        self.backgroundView = [[UIView alloc] init];
        
        self.titleLabel = [[UILabel alloc] init];
        self.titleLabel.adjustsFontSizeToFitWidth = YES;
        self.titleLabel.text = @"Default Title Text";
        self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
        self.titleLabel.textColor = [UIColor whiteColor];
        self.titleLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:16];
        self.titleLabel.numberOfLines = 2;
        
        self.detailLabel = [[UILabel alloc] init];
        self.detailLabel.adjustsFontSizeToFitWidth = YES;
        self.detailLabel.text = @"Default Detail Text";
        self.detailLabel.textColor = [UIColor whiteColor];
        self.detailLabel.lineBreakMode = NSLineBreakByWordWrapping;
        self.detailLabel.numberOfLines = 2;
        self.detailLabel.font = [UIFont systemFontOfSize:13];
        
        self.backgroundView.backgroundColor = [UIColor lightGrayColor];
        
        self.titleBackgroundColor = [UIColor blackColor];
        
        self.icon = [UIImage imageNamed:@"arrow.png"];
    }
    
    return self;
}

MMScrollPresenter是滚动视图,继承UIScrollView,并实现了UIScrollViewDelegate。

 

//添加一个Page

- (void)addMMScrollPage:(MMScrollPage *)page;

//添加一个Page数组

- (void)addMMScrollPageArray:(NSArray *)array;

//当前显示的Page索引

- (int)currentPage;

//移动并显示指定的索引。

- (void)animateToPageAtIndex:(int)index;

 

先来看addMMScrollPage方法:

- (void)addMMScrollPage:(MMScrollPage *)page
{
    if(self.pageArray == nil)
    {
        //如果pageArray为nil,则进行初始化工作
        [self setupScrollPresenter];
    }
    //将参数Page添加到pageArray中
    [self.pageArray addObject:page];
    
    //移除所有子view
    [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    for(MMScrollPage *page in self.pageArray)
    {
        //移除page.titleView的所有子view
        [[page.titleView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
    }
    //初始化titleScrollView
    [self setupViews];
}

下面这些方法中主要用于计算相关view的frame,例如titleViewFrame,iconFrame等。

[self setupFramesForPage:page atIndex:pageArrayIndex];

[self addTitleViewForPage:page atIndex:pageArrayIndex];

[self addSubviewsToPage:page];

[self addIconToPage:page];

 

层级关系:

self添加了背景图片backgroundView。

self添加了titleScrollView。

其中titleView又添加了labelScrollView。

titleScrollView又添加了titleView。

这里的层级关系比较复杂,建议大家好好理解。

MMScrollPresenter

右侧图标是添加在labelScrollView上的,同时frame中的x为-50

滑动过程中关键的代码如下:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //计算并设置当前scrollView的偏移量。
    scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, 0);
    //计算并设置titleScrollView的偏移量。
    self.titleScrollView.contentOffset = CGPointMake(scrollView.contentOffset.x * -(MMTitleViewXOffset / self.frame.size.width), scrollView.contentOffset.y);
    
    for(UIScrollView *labelScrollView in self.labelScrollViewArray)
    {
        //计算并设置所有labelScrollView的偏移量。
        labelScrollView.contentOffset = CGPointMake(scrollView.contentOffset.x * (MMTitleViewXOffset / self.frame.size.width), scrollView.contentOffset.y);
    }
}

 

可以学到的知识:

1、如何自定义ScrollView。

2、多个ScrollView的同步滚动。

 

本文来自Awnlab.com麦芒实验室,转载请注明出处,谢谢合作。