��这个demo真的可以学到很多东西

  • github
    MGDemo地址

  • 前言:

    • 看这个简单demo你可以学到很多东西。

    涉及导航栏随着tableView滑动是否隐藏,随着tableView的滑动让TabBar隐藏,停止滑动显示TabBar。还有NavigationController的titleView动态缩放效果,还还还加了UITableView分区展开与收起。后来又加了录制视频的功能和在相册中选择视频的功能(视频功能需要真机调试)。

虽然没有详细的介绍每一个步骤是如何实现的,因为我认为自己看代码看懂了没有人讲解也可以清除功能是文明实现的才算是真正学会了,不过大家应该都看的懂,看不懂的可以联系我

强烈推荐另一篇文章

个人Demo

先看一下简单的效果:

Turning.gif

代码:

//  ViewController.m
//  turnView
//
//  Created by ming on 16/5/28.
//  Copyright © 2016年 ming. All rights reserved.


#import "ViewController.h"

#define MGSCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define MGSCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@end

@implementation ViewController
{
    UISegmentedControl *segment;
    UIView *_leftView;
    UIView *_rightnView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setMainView];
}

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

- (void)setMainView{
    UINavigationBar *navBar = [UINavigationBar appearance];
    navBar.barTintColor = [UIColor purpleColor];
    navBar.tintColor = [UIColor colorWithRed:0.8 green:0.5 blue:1 alpha:1.000];
    navBar.translucent = NO;

    NSArray *segArr=@[@"订单",@"商品"];
    //设置segment
    segment=[[UISegmentedControl alloc] initWithItems:segArr];
    segment.frame=CGRectMake(MGSCREEN_WIDTH/2-266/4, 7, 266/2, 30);
    [segment addTarget:self action:@selector(selectIndex:) forControlEvents:(UIControlEventValueChanged)];
    segment.layer.borderColor=[UIColor whiteColor].CGColor;
    segment.tintColor=[UIColor orangeColor];
    NSDictionary *dics = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:15.0f] forKey:NSFontAttributeName];
    [segment setTitleTextAttributes:dics forState:UIControlStateNormal];
    segment.selectedSegmentIndex = 0;
    [self.navigationController.navigationBar addSubview:segment];

    _leftView=[[UIView alloc] initWithFrame:(CGRectMake(0, 64, MGSCREEN_WIDTH, MGSCREEN_HEIGHT-64))];
    _leftView.backgroundColor=[UIColor redColor];
    [self.view addSubview:_leftView];

    _rightnView=[[UIView alloc] initWithFrame:(CGRectMake(0, 64, MGSCREEN_WIDTH, MGSCREEN_HEIGHT-64))];
    _rightnView.backgroundColor=[UIColor greenColor];
    [self.view addSubview:_rightnView];

    [self.view bringSubviewToFront:_leftView];
}

- (void)selectIndex:(UISegmentedControl *)segmentor{
    if(segmentor.selectedSegmentIndex==0){

        [self animationWithView:self.view WithAnimationTransition:(UIViewAnimationTransitionFlipFromLeft)];
        [self.view bringSubviewToFront:_leftView];

    }else{
        [self animationWithView:self.view WithAnimationTransition:(UIViewAnimationTransitionFlipFromRight)];
        [self.view bringSubviewToFront:_rightnView];
    }
}

- (void) animationWithView:(UIView *)view WithAnimationTransition:(UIViewAnimationTransition) transition
{
    [UIView animateWithDuration:0.5f animations:^{
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:transition forView:view cache:YES];
    }];
}

@end



升级版

给Tabbar 加了动画(拖动tableView的时候会隐藏,不拖拽会显示)
也对cell 加了动画处理(cell显示的时候会有动画效果)
导航栏的渐变效果

  • 先看一下升级的效果:
    turnView.gif
#import "ViewController.h"

#define MGSCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define MGSCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height

@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
{
    UISegmentedControl *segment;
    UITableView *_leftView;
    UITableView *_rightnView;
    UIView *_topBgView;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setMainView];
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];
    self.navigationController.navigationBar.hidden=YES;
}

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

- (void)setMainView{
    _leftView=[[UITableView alloc] initWithFrame:(CGRectMake(0, 64, MGSCREEN_WIDTH, MGSCREEN_HEIGHT-64))];
    _leftView.delegate = self;
    _leftView.dataSource = self;
    _leftView.backgroundColor=[UIColor redColor];
    [self.view addSubview:_leftView];

    _rightnView=[[UITableView alloc] initWithFrame:(CGRectMake(0, 64, MGSCREEN_WIDTH, MGSCREEN_HEIGHT-64))];
    _rightnView.backgroundColor=[UIColor greenColor];
    [self.view addSubview:_rightnView];

    _topBgView=[[UIView alloc] initWithFrame:(CGRectMake(0, 0, MGSCREEN_WIDTH, 64))];
//    _topBgView.alpha = 0.0f;
    [self.view addSubview:_topBgView];

    NSArray *segArr=@[@"订单",@"商品"];
    //设置segment
    segment=[[UISegmentedControl alloc] initWithItems:segArr];
    segment.frame=CGRectMake(MGSCREEN_WIDTH/2-266/4, 25, 266/2, 30);
    [segment addTarget:self action:@selector(selectIndex:) forControlEvents:(UIControlEventValueChanged)];
    segment.layer.borderColor=[UIColor whiteColor].CGColor;
    segment.tintColor=[UIColor orangeColor];
    NSDictionary *dics = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:15.0f] forKey:NSFontAttributeName];
    [segment setTitleTextAttributes:dics forState:UIControlStateNormal];
    segment.selectedSegmentIndex = 0;
    [self.view insertSubview:segment aboveSubview:_topBgView];

    [self.view bringSubviewToFront:_leftView];
}

#pragma mark - segment的target
- (void)selectIndex:(UISegmentedControl *)segmentor{
    if(segmentor.selectedSegmentIndex==0){

        [self animationWithView:self.view WithAnimationTransition:(UIViewAnimationTransitionFlipFromLeft)];
        [self.view bringSubviewToFront:_leftView];

    }else{
        [self animationWithView:self.view WithAnimationTransition:(UIViewAnimationTransitionFlipFromRight)];
        [self.view bringSubviewToFront:_rightnView];
    }
}

#pragma mark - 翻转动画
- (void) animationWithView:(UIView *)view WithAnimationTransition:(UIViewAnimationTransition) transition
{
    [UIView animateWithDuration:0.5f animations:^{
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:transition forView:view cache:YES];
    }];
}

#pragma mark - scrollView代理
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [UIView animateWithDuration:1 animations:^{
 //  给Tabbar 加入动画       self.tabBarController.tabBar.transform = CGAffineTransformMakeTranslation(0, 49);
    }];
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    UIColor *color = [UIColor brownColor];
    CGFloat offsetY = scrollView.contentOffset.y;
    if (offsetY > 0) {
        CGFloat alpha = 1 - ((64 - offsetY) / 64);
        if (alpha>1) {
            alpha = 1;
        }
        _topBgView.backgroundColor = [color colorWithAlphaComponent:alpha];
    } else {
        _topBgView.backgroundColor = [color colorWithAlphaComponent:0];
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    [UIView animateWithDuration:1.0 delay:0.8 options:UIViewAnimationOptionOverrideInheritedCurve animations:^{
        self.tabBarController.tabBar.transform = CGAffineTransformIdentity;
    } completion:nil];
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 40;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (cell==nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"ming-%ld",indexPath.row];
    return  cell;
}

#pragma mark - 代理
/**
 *   添加cell滚动的动画
 */
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    // 防止重复添加动画
    [cell.layer removeAnimationForKey:@"ming"];
    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.y"];
    keyframeAnimation.values = @[@(-2),@(-1),@(1),@(2)];
    keyframeAnimation.duration = 0.3;
    [cell.layer addAnimation:keyframeAnimation forKey:@"ming"];
}


@end



  • 升升升升升级版

    首先加了iOS 实现NavigationController的titleView动态缩放效果,还加了UITableView分区展开与收起

  • 再看升升升升升级版的效果:
    升级版.gif

#import "MGTableController.h"
#import "UIView+Extension.h"
#import "MGHeadView.h"
#import "TableViewHead.h"

#import "MGSectionModel.h"
#import "MGCellModel.h"

@interface MGTableController ()

/** 顶部的ImageView */
@property (nonatomic,strong) UIImageView *topImageView;

/** 头部数据源 */
@property (nonatomic,strong) NSMutableArray *sectionDataSources;

/** cell数据源不用设置,因为已经在头部设置了数据源 */
//@property (nonatomic,strong) NSArray *dataSources;

@end


@implementation MGTableController

#pragma mark- 循环利用标识符
static NSString *const headViewIdentifier = @"headViewIdentifier";
static NSString *const CellIdentfier = @"CellIdentfier";

#pragma mark-  lazy
// 设置数据源
- (NSMutableArray *)sectionDataSources{
    if (!_sectionDataSources)
    {
        _sectionDataSources = [NSMutableArray array];
        for (NSUInteger i = 0; i < 10; ++i) {
            MGSectionModel *sectionModel = [[MGSectionModel alloc] init];
            sectionModel.isExpanded = NO;
            sectionModel.sectionTitle = [NSString stringWithFormat:@"section: %ld", i];
            NSMutableArray *itemArray = [[NSMutableArray alloc] init];
            for (NSUInteger j = 0; j < 10; ++j)
            {
                MGCellModel *cellModel = [[MGCellModel alloc] init];
                cellModel.title = [NSString stringWithFormat:@"MG明明就是你:section=%ld, row=%ld", i, j];
                [itemArray addObject:cellModel];
            }
            sectionModel.cellModels = itemArray;

            [_sectionDataSources addObject:sectionModel];
        }
    }
    return _sectionDataSources;
}


- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建头部的imageView
    [self setUpScaleHeaderView];

    [self setUpNav];

    [self setUpTableViewHead];

    // 注册headView
    [self.tableView registerClass:[MGHeadView class] forHeaderFooterViewReuseIdentifier:headViewIdentifier];
    // 注册 cell
    [self.tableView registerClass:[UITableViewCell class]
           forCellReuseIdentifier:CellIdentfier];
}

#pragma mark- -setUpTableViewHead
- (void)setUpTableViewHead{
    TableViewHead *head = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([TableViewHead class]) owner:nil options:nil].lastObject;
    head.frame = CGRectMake(0, 0, MGScreen_W, 170);

    self.tableView.tableHeaderView = head;
}

#pragma mark- -createScaleHeaderView
- (void)setUpScaleHeaderView {

    UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
    topView.backgroundColor = [UIColor clearColor];
    _topImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
    _topImageView.layer.anchorPoint = CGPointMake(0.5, 0);
    _topImageView.backgroundColor = [UIColor whiteColor];
    _topImageView.layer.cornerRadius = _topImageView.bounds.size.width/2;
    _topImageView.layer.masksToBounds = YES;
    _topImageView.image = [UIImage imageNamed:@"12"];
    [topView addSubview:_topImageView];
    self.navigationItem.titleView = topView;
}

#pragma mark - TableViewDatasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.sectionDataSources.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // 取得每一组的头部模型
    MGSectionModel *sectionModel = self.sectionDataSources[section];

    //                                      展开既有数据,未展开则没有数据
    return sectionModel.isExpanded ? sectionModel.cellModels.count : 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentfier];

    // 先去的sectionModel,再获取cellModel
    MGSectionModel *sectionModel = self.sectionDataSources[indexPath.section];
    MGCellModel *cellModel = sectionModel.cellModels[indexPath.row];
    cell.textLabel.text = cellModel.title;


    return cell;
}

#pragma mark - TableViewDelegate
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    MGHeadView *sectionHeadView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headViewIdentifier];

    MGSectionModel *sectionModel = self.sectionDataSources[section];
    sectionHeadView.model = sectionModel;

    sectionHeadView.expandCallback = ^(BOOL isExpanded){
        [tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
    };

    return sectionHeadView;
}

// 返回每一个cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44;
}

// 返回每一组的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 44;
}

#pragma mark - UIScrollViewDelegate
//MARK:-滑动代理
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    CGFloat contentSet = scrollView.contentOffset.y + self.tableView.contentInset.top;

    if (contentSet >= 0 && contentSet <= 30) {
        _topImageView.transform = CGAffineTransformMakeScale(1 - contentSet/64, 1-contentSet/64);
        _topImageView.y = 0;
    } else if (contentSet > 30) {
        _topImageView.transform = CGAffineTransformMakeScale(0.5, 0.5);
        _topImageView.y = 0;
    } else if (contentSet < 0 ) {
        _topImageView.transform = CGAffineTransformMakeScale(1, 1);
        _topImageView.y = 0;
    }
}
  • 后来

    • 录制视频和相册中选择视频,可以取得视频中某一帧的图片,需要真机调试。
  • 再后来补充

    • tableView 的一些常用知识点,还有搜索框的使用
      MGDemo.gif

MGDemo.gif

  • 后来又整合了UICollectionView的使用
    我们根据手势状态调用一些新的collection view方法:
  • beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath)?开始在特定的索引路径上对cell(单元)进行Interactive Movement(交互式移动工作)。
  • updateInteractiveMovementTargetPosition(targetPosition: CGPoint)?在手势作用期间更新交互移动的目标位置。】
  • endInteractiveMovement()?在完成手势动作后,结束交互式移动
  • cancelInteractiveMovement()?取消Interactive Movement。

实现下面这两个方法

“`
//#pragma mark - UICollectionViewDelegate

pragma mark - UICollectionViewDelegate

//返回YES允许其item移动
- (BOOL)collectionView:(UICollectionView )collectionView canMoveItemAtIndexPath:(NSIndexPath )indexPath{
return YES;
}

  • (void)collectionView:(UICollectionView )collectionView moveItemAtIndexPath:(NSIndexPath )sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
    // 取出源item数据
    id objc = [self.shops objectAtIndex:sourceIndexPath.item];
    //从资源数组中移除该数据
    [self.shops removeObject:objc];
    //将数据插入到资源数组中的目标位置上
    [self.shops insertObject:objc atIndex:destinationIndexPath.item];
    }

pragma mark - longPress手势

  • (void)handleLongGesture:(UILongPressGestureRecognizer *)lpGesture{
    switch(lpGesture.state) {
    case UIGestureRecognizerStateBegan:
    {
    NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:[lpGesture locationInView:lpGesture.view]];
    [self.collectionView beginInteractiveMovementForItemAtIndexPath:selectedIndexPath];
    break;
    }
    case UIGestureRecognizerStateChanged:
    {
    [self.collectionView updateInteractiveMovementTargetPosition:[lpGesture locationInView:self.collectionView]];
    break;
    }
    case UIGestureRecognizerStateEnded:
    {
    [self.collectionView endInteractiveMovement];
    }
    default:
    [self.collectionView cancelInteractiveMovement];
    }
    }“`

MGDemo3.gif

  • 后面的就不多说了,放个动态图,有兴趣的可以自己去下载代码来看一下

44.gif

  • 附:
    • #####解决了在MGCollectionController中发现一处崩溃的地方。 长按cells间空白的地方,拖动程序就会崩溃的问题

      /** 在MGCollectionController中发现一处崩溃的地方。 长按cells间空白的地方,拖动程序就会崩溃
      *
      * 解法1: case UIGestureRecognizerStateBegan:
      {}方法中加上下面的代码
      */
      // 当移动空白处时,indexPath是空的,移除nil的index时就会崩溃。直接返回
      if (selectedIndexPath == nil){
      return;
      }
      /** 在MGCollectionController中发现一处崩溃的地方。 长按cells间空白的地方,拖动程序就会崩溃
      *
      <ul><li>解法2:注释掉给self.collectionView添加的手势方法
      */
      // 把长按手势添加到cell上,而不是self.collectionView
      // 创建长按手势
      UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongGesture:)];
      [cell addGestureRecognizer:longPressGesture];

觉得不错给个赞,Thanks

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值