iOS菜单滚动联动内容区域功能实现

平时开发APP中关于此功能还是比较经常碰到,本实例借用三个开源的插件,并对其中一个进行修改调整实现出想要的效果;本文重点介绍修改的内容跟三个插件的运用,这三个插件还可以各自扩展到其它项目的运用;

效果图:

本实例实现的效果:顶部的滚动菜单显示出所有的类型,每个类型都对应一种展示,可以在顶部的菜单进行滚动,内容区域也会跟着改变,或者是内容区域左右滑动,则顶部的滚动菜单也会跟着更改,顶部菜单的最右边有一个展示更多菜单的效果,用于弹出一个带箭头的窗;(源代码下载)

带箭头的弹出视图插件 :https://github.com/xiekw2010/DXPopover

内容区域滑动插件:https://github.com/nicklockwood/iCarousel

及Codint.Net开源项目中的XTSegmentControl菜单滚动效果,此实例对它进行的修改

1:插件及页面的初始化

#import "ViewController.h"
#import "oldChildVewController.h"
#import "ChildViewController.h"
#import "newChildVewController.h"
#import "XTSegmentControl.h"
#import "iCarousel.h"
#import "Masonry.h"
#import "menuCollectionViewCell.h"
#import "DXPopover.h"

#define kScreen_Height [UIScreen mainScreen].bounds.size.height
#define kScreen_Width [UIScreen mainScreen].bounds.size.width
#define kMySegmentControl_Height 44.0

@interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate,iCarouselDataSource, iCarouselDelegate>
@property (strong, nonatomic) XTSegmentControl *mySegmentControl;
@property (strong, nonatomic) NSArray *titlesArray;
@property (strong, nonatomic) iCarousel *myCarousel;
@property(assign,nonatomic)NSInteger curSelectIndex;
@property (nonatomic, strong) DXPopover *popover;
@property(assign,nonatomic)CGFloat popoverWidth;
@property (strong, nonatomic) UICollectionView *myCollectionView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor=[UIColor whiteColor];

    //初始化一个popover 用于弹窗效果的展示
    self.popover = [DXPopover new];
    _popoverWidth = kScreen_Width-20;

    __weak typeof(self) weakSelf = self;
    CGRect frame=self.view.bounds;

    //内容区滚动效果插件
    self.myCarousel = ({
        iCarousel *icarousel = [[iCarousel alloc] initWithFrame:frame];
        icarousel.dataSource = self;
        icarousel.delegate = self;
        icarousel.decelerationRate = 1.0;
        icarousel.scrollSpeed = 1.0;
        icarousel.type = iCarouselTypeLinear;
        icarousel.pagingEnabled = YES;
        icarousel.clipsToBounds = YES;
        icarousel.bounceDistance = 0.2;
        [self.view addSubview:icarousel];
        [icarousel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(64, 0, 0, 0));
        }];
        icarousel;
    });

    //添加滑块
    __weak typeof(_myCarousel) weakCarousel = _myCarousel;
    self.mySegmentControl = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 20, kScreen_Width, 44) Items:self.titlesArray showRightButton:YES selectedBlock:^(NSInteger index) {
        weakSelf.curSelectIndex=index;
        weakCarousel.currentItemIndex=index;
        [weakSelf.myCollectionView reloadData];
    }];
    //当有右边键时 其响应的事件
    self.mySegmentControl.rightButtonBlock= ^(CGRect rightButtomRect)
    {
        //弹出插件的运用
        [weakSelf updateMyViewFrame];
        CGPoint startPoint =
        CGPointMake(CGRectGetMidX(rightButtomRect), CGRectGetMaxY(rightButtomRect) + 25);
        [weakSelf.popover showAtPoint:startPoint
                   popoverPostion:DXPopoverPositionDown
                  withContentView:weakSelf.myCollectionView
                           inView:weakSelf.view];
    };
    [self.view addSubview:self.mySegmentControl];

    //用于展示弹出效果里面的列表
    if (!_myCollectionView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        self.myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0,50,kScreen_Width-40, 200) collectionViewLayout:layout];
        self.myCollectionView.backgroundColor=[UIColor whiteColor];
        self.myCollectionView.showsHorizontalScrollIndicator=NO;
        self.myCollectionView.showsVerticalScrollIndicator=NO;
        [self.myCollectionView registerClass:[menuCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([menuCollectionViewCell class])];
        self.myCollectionView.dataSource = self;
        self.myCollectionView.delegate = self;
    }
}

其中XTSegmentControl为顶部菜单的创建,其中showRightButton是为了扩展是否显示右边更多菜单的事件,并把事件的响应Block到页面进行实现,此事例就是响应弹出窗的效果展现,iCarousel为内容区域的滑动效果,DXPopover弹出窗的效果,UICollectionView则用于弹出窗里面的菜单列表

//popver一些属性的设置
-(void)updateMyViewFrame
{
    CGRect tableViewFrame = self.myCollectionView.frame;
    tableViewFrame.size.width = _popoverWidth;
    self.myCollectionView.frame = tableViewFrame;
    self.popover.contentInset = UIEdgeInsetsZero;
    self.popover.backgroundColor = [UIColor whiteColor];
}

#pragma mark - Getter/Setter
- (NSArray*)titlesArray
{
    if (nil == _titlesArray) {
            _titlesArray = @[@"全部", @"互动", @"开源控件", @"文档", @"代码", @"高尔夫",@"主题",@"软件",@"股票"];
    }
    return _titlesArray;
}

2插件iCarouselDataSource, iCarouselDelegate代码实现

#pragma mark iCarousel M
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{
    return [self.titlesArray count];
}

//滚动时内容视图的加载
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
    [_mySegmentControl setScrollOffset:index];
    UIViewController *childContrll=[[ChildViewController alloc]init];
    UIView *my=childContrll.view;
    switch (index) {
        case 0:
        {
            my.backgroundColor=[UIColor blackColor];
            break;
        }
        case 1:
        {
            my.backgroundColor=[UIColor redColor];
            break;
        }
        default:
            childContrll=[[newChildVewController alloc]init];
            break;
    }
    return childContrll.view;
}

//滚动时 下划线的位置更新
- (void)carouselDidScroll:(iCarousel *)carousel{
    if (_mySegmentControl) {
        [_mySegmentControl moveIndexWithProgress];
    }
}

//更新滚动其它两个控件的位置
- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{
    self.curSelectIndex=carousel.currentItemIndex;
    [self.myCollectionView reloadData];
    if (_mySegmentControl) {
        _mySegmentControl.currentIndex = carousel.currentItemIndex;
    }
}

注意:内容区域的视图加载,及其滑动所响应的事件处理,原来的XTSegmentControl对于菜单字数不同时下划线会出现一些异常,本实例对它进行修改了;

3:列表UICollectionViewDataSource, UICollectionViewDelegate功能的实现

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return self.titlesArray.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    menuCollectionViewCell *ccell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([menuCollectionViewCell class]) forIndexPath:indexPath];
    NSString *model=[self.titlesArray objectAtIndex:indexPath.row];
    ccell.curMenuModel=model;
    if (self.curSelectIndex==indexPath.row) {
        ccell.backgroundColor=[UIColor blueColor];
    }
    else
    {
        ccell.backgroundColor=[UIColor whiteColor];
    }
    return ccell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return CGSizeMake((kScreen_Width-40)/3, 40);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsZero;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
    return 5;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
    return 5;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    self.curSelectIndex=indexPath.row;
    //两个滚动的位置更新
    _myCarousel.currentItemIndex=self.curSelectIndex;
    [_mySegmentControl selectIndex:self.curSelectIndex];
    //隐藏弹出窗
    [self.popover dismiss];
}

注意:主要是在实现点击时滚动位置跟内容的区域要进行调整,并把弹出窗进行收缩的操作;

4:XTSegmentControl下划线调整

- (void)moveIndexWithProgress
{
    CGRect origionRect = [_itemFrames[_currentIndex] CGRectValue];

    CGRect origionLineRect = CGRectMake(CGRectGetMinX(origionRect) + XTSegmentControlHspace, CGRectGetHeight(origionRect) - XTSegmentControlLineHeight, CGRectGetWidth(origionRect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight);

    //增加下划线滚动的效果
    [UIView animateWithDuration:0.5 animations:^{
        _lineView.frame = origionLineRect;
    } completion:^(BOOL finished) {

    }];

}

5:扩展XTSegmentControl没有右边更多菜单的效果

    self.mySegmentControl = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 20, kScreen_Width, 44) Items:self.titlesArray showRightButton:NO selectedBlock:^(NSInteger index) {
        weakSelf.curSelectIndex=index;
        weakCarousel.currentItemIndex=index;
        [weakSelf.myCollectionView reloadData];
    }];

效果图:

时间: 2024-07-28 23:23:20

iOS菜单滚动联动内容区域功能实现的相关文章

iOS仿京东分类菜单之UICollectionView内容

 iOS仿京东分类菜单之UICollectionView内容 在 上<iOS仿京东分类菜单实例实现>已经实现了大部分主体的功能,本文是针对右边集合列表进行修改扩展,使它达到分组的效果,本文涉及到的主要是UICollectionView的知识内容,左边列表的实现见上一篇文章,先看实现的效果图: 一:实体的创建 1.1分组实体的创建(tagID跟左边表格进行关联,roomArray是存放房间的数组,也就是单元格的集合) #import <Foundation/Foundation.h>

移动端内容区域滚动做法总结

自己的总结的一些方法,如果有什么新的好的方法希望能够交流: 1.给定位(导航栏)(底部) nav{ position:fixed; top:0rem; }; footer{ position:fixed; bottom:0rem; }; 但是这个方法会有弊端,在你给nav设置定位时,内容区域就会顶头出现,就需要给内容区域设置定位设置top值nav的高度方可. 2.使用IScroll插件. 例如: <!DOCTYPE html><html> <head> <meta

JavaScript目录菜单滚动反显组件的实现

原文:JavaScript目录菜单滚动反显组件的实现 JavaScript目录菜单滚动反显组件,有以下两个特点 每个导航菜单项(nav)对应页面一个内容区域(content) 滚动页面到特定内容区域(content)时,对应的菜单会自动切换,一般会添加一个高亮样式 这个功能可以很方便的提醒用户目前所浏览的位置,有时目录菜单还会设计为滚动时一直固定在指定位置. 以下为此类功能的应用示例: 1. 京东团购首页左侧导航菜单 2. 京东图书详细页右侧图书目录导航 3. 京东团购品牌惠楼层分类菜单 实现思

IOS UIScrollView详解 & 图片缩放功能

一 UIScrollView 简介 UIScrollView是能滚动的视图控件,可以通过滚动的方式来展示类容. 二 UIScrollView常见属性 //设置UIScrollView滚动的位置 @property(nonatomic) CGPoint contentOffset;  //设置UIScrollView内容的尺寸,滚动范围 @property(nonatomic) CGSize contentSize;  //设置UIScrollView的4周增加额外的滚动区域 @property(

点九图片的显示内容区域应作何理解

.9 ,是andriod平台的应用软件开发里的一种特殊的图片形式,文件扩展名为:.9.png;点九图片的拉伸区域不难理解,显示内容区域是怎样的,接下来本文为您一一解答,感兴趣的朋友可以了解下 点九图片的拉伸区域不难理解,显示内容区域是怎样的?.9 ,是andriod平台的应用软件开发里的一种特殊的图片形式,文件扩展名为:.9.png 智能手机中有自动横屏的功能,同一幅界面会在随着手机(或平板电脑)中的方向传感器的参数不同而改变显示的方向,在界面改变方向后,界面上的图形会因为长宽的变化而产生拉伸,

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

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

iOS 关于滚动视图contentSize、contentOffset、contentInset 的整理

iOS 关于滚动视图contentSize.contentOffset.contentInset 的整理 contentSize 是scrollview可以滚动的区域,比如frame = (0 ,0 ,320 ,480) contentSize = (320 ,960),代表你的scrollview可以上下滚动,滚动区域为frame大小的两倍. contentOffset 是scrollview当前显示区域顶点相对于frame顶点的偏移量,比如上个例子你拉到最下面,contentoffset就是

JS实现菜单滚动到一定高度后固定

在有些网页中我们会发现会有这样的现象:某个div会随着屏幕的滚动达到一定高度的时候位置就固定下来了.例如一下导航条: 那么这里就需要用到JS的逻辑方法来实现了. html <div id="space"></div> <ul id="nav"> <li><a href="#content1">美食</a></li> <li><a href=&qu

(转) IOS程序名称及内容国际化(本地化)

1.IOS程序名称国际化 1.1 新建一个Single View app模版项目,命名为Localization. 1.2 新建后,可以看到工作目录结构文件如下,单击InfoPlist.strings,查看右边的属性,在Localization栏添加语言.      1.3 添加完成后打开对应语言文件,比如English的添加 CFBundleDisplayName="China"; Chinese文件添加 CFBundleDisplayName="中国"; 运行,