判断手机号码是否合法最新正则表达式

– (BOOL)isMobileNumber:(NSString *)mobileNum{

    /**

     * 手机号码

     * 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188

     * 联通:130,131,132,152,155,156,185,186

     * 电信:133,1349,153,180,189,181(增加)

     */

    NSString * MOBIL = @”^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$”;

    /**

     10         * 中国移动:China Mobile

     11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,183,187,188

     12         */

    NSString * CM = @”^1(34[0-8]|(3[5-9]|5[017-9]|8[2378])\\d)\\d{7}$”;

    /**

     15         * 中国联通:China Unicom

     16         * 130,131,132,152,155,156,185,186,170,171

     17         */

    NSString * CU = @”^1(3[0-2]|5[256]|7[01]|8[56])\\d{8}$”;

    /**

     20         * 中国电信:China Telecom

     21         * 133,1349,153,180,189,181(增加)

     22         */

    NSString * CT = @”^1((33|53|8[019])[0-9]|349)\\d{7}$”;

    

    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@”SELF MATCHES %@”, MOBIL];

    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@”SELF MATCHES %@”, CM];

    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@”SELF MATCHES %@”, CU];

    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@”SELF MATCHES %@”, CT];

    

    if (([regextestmobile evaluateWithObject:mobileNum]

         || [regextestcm evaluateWithObject:mobileNum]

         || [regextestct evaluateWithObject:mobileNum]

         || [regextestcu evaluateWithObject:mobileNum])) {

        return YES;

    }

    return NO;

}

ScollerView模拟tableView重用机制

//

//  ViewController.m

//  ScollerView模拟tableView重用机制

//

//  Created by lixiang on 19/2/16.

//  Copyright (c) 2016 lixiang. All rights reserved.

//

#import “ViewController.h”

#import “LXModel.h”

#import “LXButton.h”

@interface ViewController () <UIScrollViewDelegate>

@property (nonatomicstrongUIScrollView *scrollView;

@property (nonatomicstrongNSMutableArray *arr;// 托管重用数组

@property (nonatomicassignCGFloat upY;// 需要添加到头部子视图的坐标Y

@property (nonatomicassignCGFloat downY;// 需要添加到尾部子视图的坐标Y

@property (nonatomicassignCGFloat offset;// 拖动时候的偏移量

@property (nonatomicstrongNSMutableArray *allArray;

@property (nonatomicassignNSInteger rankRecord;//记录当前最后一个box10box中的第几个。默认值为5,滚动时+1-1,下限为5,上限是self.allArray.count

@property (nonatomicassignint screenWidth;

@property (nonatomicassignint screenHeight;

@property (nonatomicassignint boxHeight;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.screenWidth = self.view.frame.size.width;

    self.screenHeight = self.view.frame.size.height;

    self.boxHeight = self.view.frame.size.width*0.625;

    [self requestData];//请求全部的数据

}

// 请求数据

– (void)requestData {

    for (int i = 0; i < 10; i++) {

        LXModel *model = [[LXModel alloc]init];

        model.title = [NSString stringWithFormat:@”%d”,i];

        [self.allArray addObject:model];

    }

    

    // 若请求数据成功 就初始化一个ScrollView

    self.scrollView = [[UIScrollView allocinitWithFrame:CGRectMake(00self.screenWidthself.screenHeight)];

    self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width10000);

    self.scrollView.backgroundColor = [UIColor lightGrayColor];

    self.scrollView.delegate = self;

    [self.view addSubview:self.scrollView];

    

    // 若请求的数据中的数组数量大于,就启用重用

    if (self.allArray.count > 5) {

        self.rankRecord = 5;

        NSInteger i = 0;

        for (i = 0; i < 5; i++) {

            LXButton *box = [[LXButton allocinitWithFrame:CGRectMake(0, i * self.boxHeight , self.screenWidthself.boxHeight)];

            box.rank = i;

            LXModel *model = self.allArray[i];

            box.model = model;

            [self.scrollView addSubview:box];// 添加子视图到scrollview

            [self.arr addObject:box];// 添加view到托管的重用数组

        }

        // 下一个viewy点是

        i++;

        self.downY = i * self.boxHeight;

        self.upY = –self.boxHeight;

        self.offset = 0;

    }

}

– (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    self.offset = scrollView.contentOffset.y// 记录开始拖动时的偏移量

}

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

    // 判断上下滑 是否偏移量超出屏幕

    if (scrollView.contentOffset.y < 0 || scrollView.contentOffset.y > (10000 – self.screenHeight)) {

        // 超出屏幕范围不做任何操作

    else if ((scrollView.contentOffset.y – self.offset) > 0) {

        

        // 上拉屏幕

        

        if ((self.downY – (self.scrollView.contentOffset.y + self.screenHeight)) < self.boxHeight+50 && self.rankRecord < self.allArray.count) {//√

            

            LXButton *box = [self.arr objectAtIndex:0];// 取出数组的第一个元素

            self.upY = box.frame.origin.y;// 将头部Y坐标变为boxY坐标 因为box要添加到尾部

            [self.arr removeObjectAtIndex:0];// 移除数组第一个元素

            box.frame = CGRectMake(0self.downY – self.boxHeightself.screenWidthself.boxHeight);// 改变boxframe

            box.rank = box.rank+5// 改变frame的同时改变索引

            LXModel *model = self.allArray[box.rank]; // 根据索引取出模型

            box.model = model; // 赋值

            [self.arr addObject:box];// box重新添加到数组

            self.rankRecord ++;//记录当前最后一个box10box中的第几个

            self.downY = self.downY + self.boxHeight;// 改变下一个的尾部坐标的Y//////////////////////////////

            NSLog(@”上拉%f”,self.downY);

        }

        

    else if((scrollView.contentOffset.y – self.offset) < 0){

        

        // 下拉屏幕

        

        if ((self.scrollView.contentOffset.y – self.upY) < self.boxHeight+50 && self.rankRecord>5) {//!!!

            LXButton *box = [self.arr lastObject];// 取出数组的最后一个元素

            self.downY = box.frame.origin.y+self.boxHeight;// 将尾部Y坐标变为boxY坐标 因为box要添加到头部部///////////////////////////////////

            [self.arr removeObject:box];// 移除数组最后一个元素

            box.frame = CGRectMake(0self.upYself.screenWidthself.boxHeight);// 改变boxframe

            box.rank = box.rank – 5// 改变frame的同时改变索引

            LXModel *model = self.allArray[box.rank]; // 根据索引取出模型

            box.model = model; // 赋值

            

            [self.arr insertObject:box atIndex:0];// box重新添加到数组的头部

            self.upY = self.upY – self.boxHeight;// 改变下一个的头部坐标的Y

            self.rankRecord –;//记录当前最后一个box10box中的第几个

            NSLog(@”下拉%f”,self.downY);

        }

    }

}

#pragma mark 懒加载

– (NSMutableArray *)arr {

    if (_arr == nil) {

        _arr = [[NSMutableArray allocinit];

    }

    return _arr;

}

– (NSMutableArray *)allArray {

    if (_allArray == nil) {

        self.allArray = [NSMutableArray array];

    }

    return _allArray;

}

@end

 

多动画特效 列表页详情页二合一

//

//  ODCircleLeftController.m

//  oudaBuyer

//

//  Created by lixiang on 16/1/18.

//  Copyright © 2016 ouda. All rights reserved.

//

#import “ODCircleLeftController.h”

#import “ODCircleModel.h”

@interface ODCircleLeftController ()

@property (nonatomicstrongNSMutableArray *arr;

@property (nonatomicstrongUIScrollView *scrollView;

@property (nonatomicstrongUIView *topView;

@property (nonatomicstrongUIButton *backButton;

@property (nonatomicassignlong selectedTag;

@property (nonatomicstrongUIImageView *imgView;

@property (nonatomicstrongUIImageView *blurImageView;

@property (nonatomicstrongUIImageView *designerView;

@property (nonatomicassignfloat moveLength;

@end

@implementation ODCircleLeftController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    UIView *topView = [[UIView alloc]initWithFrame:CGRectMake(00kWidthOfScreenkWidthOfScreen*0.884)];

    self.topView = topView;

    topView.backgroundColor = [UIColor blackColor];

    [self.view addSubview:topView];

    

    UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(00kWidthOfScreenkWidthOfScreen*0.884)];

    self.imgView = imgView;

    [self.topView addSubview:imgView];

    self.topView.hidden = YES;

    

    UIImageView *designerView = [[UIImageView alloc]initWithFrame:CGRectMake(0kWidthOfScreen*0.884kWidthOfScreenkWidthOfScreen*0.762)];

    designerView.image = [UIImage imageNamed:@”下半部分];

    self.designerView = designerView;

    [self.view addSubview:designerView];

    

    UIButton *backButton = [[UIButton alloc]initWithFrame:CGRectMake(15153333)];

    [backButton setImage:[UIImage imageNamed:@”返回forState:UIControlStateNormal];

    [self.view addSubview:backButton];

    self.backButton = backButton;

    [backButton addTarget:self action:@selector(click2list) forControlEvents:UIControlEventTouchUpInside];

    

    [self requestData];

    [self cover];

}

– (NSMutableArray *)arr {

    if (_arr == nil) {

        self.arr = [NSMutableArray array];

    }

    return _arr;

}

– (void)requestData {

    ODCircleModel *model1 = [ODCircleModel new];

    UIImage *image1 = [UIImage imageNamed:@”testImg1″];

    model1.image = image1;

    [self.arr addObject:model1];

    

    ODCircleModel *model2 = [ODCircleModel new];

    UIImage *image2 = [UIImage imageNamed:@”testImg2″];

    model2.image = image2;

    [self.arr addObject:model2];

    

    ODCircleModel *model3 = [ODCircleModel new];

    UIImage *image3 = [UIImage imageNamed:@”testImg3″];

    model3.image = image3;

    [self.arr addObject:model3];

    

    ODCircleModel *model4 = [ODCircleModel new];

    UIImage *image4 = [UIImage imageNamed:@”testImg4″];

    model4.image = image4;

    [self.arr addObject:model4];

}

/**

 *  遮盖层

 */

– (void)cover {

    UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(00kWidthOfScreenkHeightOfScreen)];

    scrollView.showsVerticalScrollIndicator = NO;

    scrollView.backgroundColor = [UIColor whiteColor];

    [self.view addSubview:scrollView];

    self.scrollView = scrollView;

    

    for (int i = 0; i < self.arr.count; i++) {

        UIButton *button = [UIButton new];

        button.tag = i;

        [button addTarget:self action:@selector(click2Detail:) forControlEvents:UIControlEventTouchUpInside];

        ODCircleModel *model = self.arr[i];

        [button setImage:model.image forState:UIControlStateNormal];

        [button setBackgroundImage:[model.image blurBlackImageforState:UIControlStateNormal];

        button.imageView.contentMode = UIViewContentModeScaleAspectFill;

        button.frame = CGRectMake(0, (i)*kWidthOfScreen*0.625kWidthOfScreenkWidthOfScreen*0.884);

        [self.scrollView addSubview:button];

    }

    self.scrollView.contentSize = CGSizeMake(kWidthOfScreenkWidthOfScreen*0.625*self.arr.count+110);

}

/**

 *  点击进入详情页

 */

– (void)click2Detail:(UIButton *)sender {

    

    ODCircleModel *model = self.arr[sender.tag];

    self.imgView.image = [model.image blurBlackImage];

   

    [self.delegate hideNavBar:YES];

    self.selectedTag = sender.tag;

    self.scrollView.backgroundColor = [UIColor clearColor];

    for (UIButton *btn in self.scrollView.subviews) {

        if ([btn isKindOfClass:[UIButton class]]) {

            if (btn.tag == sender.tag) {

                

                ODCircleModel *model = self.arr[btn.tag];

                UIImageView *blurImageView = [[UIImageView alloc]initWithFrame:btn.frame];

                blurImageView.image = [model.image blurBlackImage];

                [self.scrollView addSubview:blurImageView];

                blurImageView.alpha = 0;

                self.blurImageView = blurImageView;

                

                CGPoint point = [btn convertPoint:btn.bounds.origin toView:self.view];

                self.designerView.x = btn.x;

                self.designerView.y = btn.y;

                [UIView animateWithDuration:0.6 animations:^{

                    btn.transform = CGAffineTransformMakeTranslation(0, -point.y);

                    self.designerView.frame = CGRectMake(0kWidthOfScreen*0.884kWidthOfScreenkWidthOfScreen*0.762);

                    self.blurImageView.transform = CGAffineTransformMakeTranslation(0, -point.y);

                    self.moveLength = point.y;

                    self.blurImageView.alpha = 1;

                }];

                

            }else if(btn.tag>sender.tag){

                [UIView animateWithDuration:0.6 animations:^{

                    CGPoint point = [btn convertPoint:btn.bounds.origin toView:self.view];

                    btn.transform = CGAffineTransformMakeTranslation(0,kHeightOfScreen – point.y);

                }];

            }else if (btn.tag<sender.tag){

                    CGPoint point = [btn convertPoint:btn.bounds.origin toView:self.view];

                    [UIView animateWithDuration:0.6 animations:^{

                    btn.transform = CGAffineTransformMakeTranslation(0, -point.y-(sender.tag-btn.tag)*kWidthOfScreen*0.625);

                }];

            }

        }

    }

    

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        self.topView.hidden = NO;

        self.scrollView.hidden = YES;

    });

}

/**

 *  点击回到列表页

 */

– (void)click2list {

    [self.delegate hideNavBar:NO];

    self.scrollView.hidden = NO;

    

    for (UIButton *btn in self.scrollView.subviews) {

        if ([btn isKindOfClass:[UIButton class]]) {

            if (btn.tag == self.selectedTag) {

                [UIView animateWithDuration:0.6 animations:^{

                    btn.transform = CGAffineTransformMakeTranslation(0,0);

                    self.blurImageView.transform = CGAffineTransformMakeTranslation(0,0);

                    self.blurImageView.alpha = 0;

                    self.designerView.y -= kHeightOfScreenself.moveLengthself.designerView.y;

                }];

                

            }else if(btn.tag > self.selectedTag){

                [UIView animateWithDuration:0.6 animations:^{

                    CGPoint point = [btn convertPoint:btn.bounds.origin toView:self.view];

                    btn.transform = CGAffineTransformMakeTranslation(0,-(kHeightOfScreen – point.y));

                }];

            }else if (btn.tag < self.selectedTag){

                CGPoint point = [btn convertPoint:btn.bounds.origin toView:self.view];

                [UIView animateWithDuration:0.6 animations:^{

                    btn.transform = CGAffineTransformMakeTranslation(0,point.y+(self.selectedTag-btn.tag)*kWidthOfScreen*0.625);

                }];

            }

        }

    }

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        self.scrollView.backgroundColor = [UIColor whiteColor];

    });

}

@end

如何快速定位代码?

1.搜索导航栏标题,目录标题等固定文字。

2.搜索可能的代码命名,图片命名,方法命名。

3.查看图片,再搜索图片名。

4.查看XIB,再查看此XIB文件属于谁。

5.查看根控制器,看控制器如何跳转。

6.通过注释代码,或者在方法第一行加return;来判断当前代码的作用。

7.截图存储,并注释此截图,作为笔记留存以待今后查阅。

控制器反向传值(不用代理)

把需要传递的信息作为成员变量写在A控制器的.h文件中。

在push或presnt一个新的控制器B的时候,将A控制器设为B控制器的成员变量。

这样就可以在B控制器中修改A控制器的属性。

 

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (nonatomic, assign) NSInteger age;

@end

@interface ViewController2 : UIViewController

@property(nonatomic,strong)ViewController * viewController;

@end

使用present实现push动画效果

//

//  HYBModalTransition.h

//  PresentDismissTransitionDemo

//

//  Created by huangyibiao on 15/12/21.

//  Copyright © 2015 huangyibiao. All rights reserved.

//

#import <Foundation/Foundation.h>

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, HYBModalTransitionType) {

  kHYBModalTransitionPresent = 1 << 1,

  kHYBModalTransitionDismiss = 1 << 2

};

@interface HYBModalTransition : NSObject <UIViewControllerAnimatedTransitioning>

/*!

*  @author 黄仪标, 15-12-21 11:12:44

*

*  指定动画类型

*

*  @param type          动画类型

*

*  @return

*/

+ (HYBModalTransition *)transitionWithType:(HYBModalTransitionType)type;

@end

//

//  HYBModalTransition.m

//  PresentDismissTransitionDemo

//

//  Created by huangyibiao on 15/12/21.

//  Copyright © 2015 huangyibiao. All rights reserved.

//

#import “HYBModalTransition.h”

@interface HYBModalTransition ()

@property (nonatomic, assign) HYBModalTransitionType type;

@property (nonatomic, assign) NSTimeInterval duration;

@end

@implementation HYBModalTransition

+ (HYBModalTransition *)transitionWithType:(HYBModalTransitionType)type

{

    HYBModalTransition *transition = [[HYBModalTransition alloc] init];

    transition.type = type;

    transition.duration = 0.35;

    return transition;

}

– (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {

    return 0.35;

}

– (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {

    switch (self.type) {

        case kHYBModalTransitionPresent: {

            [self present:transitionContext];

            break;

        }

        case kHYBModalTransitionDismiss: {

            [self dismiss:transitionContext];

            break;

        }

        default: {

            break;

        }

    }

}

– (void)present:(id<UIViewControllerContextTransitioning>)transitonContext {

    UIViewController *fromVC = [transitonContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    UIViewController *toVC = [transitonContext viewControllerForKey:UITransitionContextToViewControllerKey];

    UIView *containerView = [transitonContext containerView];

    UIView *tempView = [fromVC.view snapshotViewAfterScreenUpdates:NO];

    tempView.frame = fromVC.view.frame;

    fromVC.view.hidden = YES;

    [containerView addSubview:toVC.view];

    [containerView addSubview:tempView];

    toVC.view.frame = CGRectMake(kWidthOfScreen, 0, kWidthOfScreen, kHeightOfScreen);

    [UIView animateWithDuration:self.duration animations:^{

        toVC.view.frame = CGRectMake(0, 0, kWidthOfScreen, kHeightOfScreen);

        tempView.frame = CGRectMake(-kWidthOfScreen, 0, kWidthOfScreen, kHeightOfScreen);

        fromVC.view.frame = CGRectMake(-kWidthOfScreen, 0, kWidthOfScreen, kHeightOfScreen);

    } completion:^(BOOL finished) {

        [transitonContext completeTransition:YES];

    }];

}

– (void)dismiss:(id<UIViewControllerContextTransitioning>)transitonContext {

    UIViewController *fromVC = [transitonContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    UIViewController *toVC = [transitonContext viewControllerForKey:UITransitionContextToViewControllerKey];

    UIView *containerView = [transitonContext containerView];

    UIView *tempView = containerView.subviews.lastObject;

    [UIView animateWithDuration:self.duration animations:^{

        toVC.view.frame = CGRectMake(0, 0, kWidthOfScreen, kHeightOfScreen);

        tempView.frame = CGRectMake(0, 0, kWidthOfScreen, kHeightOfScreen);

        fromVC.view.frame = CGRectMake(kWidthOfScreen, 0, kWidthOfScreen, kHeightOfScreen);

    } completion:^(BOOL finished) {

        [transitonContext completeTransition:YES];

        [tempView removeFromSuperview];

        toVC.view.hidden = NO;

    }];

}

@end

//

//  ODDismissNavController.h

//  PresentDismissTransitionDemo

//

//  Created by lixiang on 15/12/24.

//  Copyright © 2015 huangyibiao. All rights reserved.

//

#import <UIKit/UIKit.h>

@interface ODDismissNavController : UINavigationController<UIViewControllerTransitioningDelegate>

@end

//

//  ODDismissNavController.m

//  PresentDismissTransitionDemo

//

//  Created by lixiang on 15/12/24.

//  Copyright © 2015 huangyibiao. All rights reserved.

//

#import “ODDismissNavController.h”

#import “HYBModalTransition.h”

@interface ODDismissNavController ()

@end

@implementation ODDismissNavController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.transitioningDelegate = self;

    self.modalPresentationStyle =  UIModalPresentationCustom;

}

– (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

– (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return [HYBModalTransition transitionWithType:kHYBModalTransitionPresent];

}

– (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {

    return [HYBModalTransition transitionWithType:kHYBModalTransitionDismiss];

}

@end

项目增减动画效果的实现

#import “ViewController.h”

#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)

#define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)

@interface ViewController ()

@property (nonatomicstrongNSMutableArray *userArray;

@property (nonatomicstrongNSArray *allArray;

@property (nonatomicstrongNSMutableArray *downArray;

@property (nonatomicstrongUIScrollView *scrollView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.userArray = [NSMutableArray arrayWithArray:@[@”经典案例@”京东@”淘宝@”天猫@”阿里巴巴@”唯品会@”1号店]];

    self.allArray = @[@”经典案例@”京东@”淘宝@”天猫@”阿里巴巴@”唯品会@”1号店@”苏宁易购@”聚美优品@”我想静静@”静静是谁@”我是静静];

    self.downArray = [NSMutableArray arrayWithArray:@[@”苏宁易购@”聚美优品@”我想静静@”静静是谁@”我是静静]];

    

    UIScrollView *scrollView = [[UIScrollView allocinitWithFrame:self.view.frame];

    [self.view addSubview:scrollView];

    self.scrollView = scrollView;

    self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH,300+(self.downArray.count*60));

    self.scrollView.backgroundColor = [UIColor clearColor];

    [self setUpperItems];

    [self setDownItems];

}

– (void)setUpperItems{

    CGFloat aW = SCREEN_WIDTH/310;

    CGFloat aH = aW/2.55;

    int num = 3;

    CGFloat marginX = (self.view.frame.size.width – aW * num) / (num + 1);

    CGFloat marginY = 0;

    for (int index = 0; index < self.userArray.count; index++)

    {

        UIButton * btn = [[UIButton allocinit];

        int col = index % num;

        CGFloat aX = marginX + (aW + marginX) * col;

        int row = index / num;

        CGFloat aY = 20 + marginY + (aH + marginY) * row;

        btn.frame = CGRectMake(aX, aY, aW, aH);

        [btn setTitle:self.userArray[index] forState:UIControlStateNormal];

        [btn setTitleColor:[UIColor blackColorforState:UIControlStateNormal];

        [self.scrollView addSubview:btn];

        [btn addTarget:self action:@selector(toDown:) forControlEvents:UIControlEventTouchUpInside];

    }

}

– (void)setDownItems{

    for (int index = 0; index < self.downArray.count; index++)

    {

        UIButton * btn = [[UIButton allocinit];

        btn.frame = CGRectMake(0, index*60+192SCREEN_WIDTH60);

        [btn setTitle:self.downArray[index] forState:UIControlStateNormal];

        [btn setTitleColor:[UIColor blackColorforState:UIControlStateNormal];

        [self.scrollView addSubview:btn];

        [btn addTarget:self action:@selector(toUp:) forControlEvents:UIControlEventTouchUpInside];

    }

}

– (void)toDown:(UIButton *)button{

    

    // 动画效果

    CGRect tempRect = CGRectMake(0200+self.downArray.count*60SCREEN_WIDTH60);

    [UIView animateWithDuration:0.3 animations:^{button.frame = tempRect;}];

    

    // 生成上半部分需要的新的数组

    NSString *str = [NSString stringWithString:button.titleLabel.text];

    NSMutableArray *filteredArray = [[NSMutableArray alloc]initWithObjects:str, nil];

    NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@”NOT (SELF IN %@)”,filteredArray];

    self.userArray = [NSMutableArray arrayWithArray:[self.userArray filteredArrayUsingPredicate:filterPredicate]];

    

    // 生成下半部分需要的新的数组

    [self.downArray addObject:str];

    

    // 延时执行

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        

        // 移除页面中所有的按钮

        for(UIButton *btn in [self.scrollView subviews])

        {

            [btn removeFromSuperview];

        }

        // 重载页面中所有的按钮

        [self setUpperItems];

        [self setDownItems];

    });

    

    

    self.scrollVew.contentSize = CGSizeMake(SCREEN_WIDTH300+(self.downArray.count*60));

}

– (void)toUp:(UIButton *)button{

    // 动画效果

    CGFloat aW = SCREEN_WIDTH/310;

    CGFloat aH = aW/2.55;

    int num = 3;

    CGFloat marginX = (self.view.frame.size.width – aW * num) / (num + 1);

    CGFloat marginY = 0;

    int col = (self.userArray.count) % num;

    CGFloat aX = marginX + (aW + marginX) * col;

    unsigned long row = (self.userArray.count)/num;

    CGFloat aY = 20 + marginY + (aH + marginY) * row;

    CGRect tempRect = CGRectMake(aX,aY,aW,aH);

    [UIView animateWithDuration:0.3 animations:^{button.frame = tempRect;}];

    

    // 生成上半部分需要的新的数组

    NSString *str = [NSString stringWithString:button.titleLabel.text];

    [self.userArray addObject:str];

    

    // 生成下半部分需要的新的数组

    NSMutableArray *filteredArray = [[NSMutableArray alloc]initWithObjects:str, nil];

    NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@”NOT (SELF IN %@)”,filteredArray];

    self.downArray = [NSMutableArray arrayWithArray:[self.downArray filteredArrayUsingPredicate:filterPredicate]];

    

    // 延时执行

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        

        // 移除页面中所有的按钮

        for(UIButton *btn in [self.scrollView subviews])

        {

            [btn removeFromSuperview];

        }

        // 重载页面中所有的按钮

        [self setUpperItems];

        [self setDownItems];

    });

    

    self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH,300+(self.downArray.count*60));

}

@end

屏幕向下滚动时导航栏动画特效

1

标题左右滚动和页面左右轮播的效果请参考:http://www.jianshu.com/p/b45655e23a42

标题向上滚动到屏幕之外的效果是使用代理方法完成的,具体如下:

@protocol ODHideNavBarDelegate <NSObject>

– (void)hideNavBar:(BOOL)needHide;

@end

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

    if (self.tableView.contentOffset.y > 100) {

        [self.delegate hideNavBar:YES];

    }else{

        [self.delegate hideNavBar:NO];

    }

}

– (void)hideNavBar:(BOOL)needHide{

    if (needHide == YES) {

        [UIView animateWithDuration:0.5 animations:^{

            self.titleLabel.y = –50;

            self.leaveBtn.y = –50;

            [self setUpContentViewFrame:^(UIView *contentView) {

                contentView.frame = CGRectMake(0,20, kWidthOfScreen, kHeightOfScreen);

            }];

        }];

    }

    

    if (needHide == NO) {

        [UIView animateWithDuration:0.5 animations:^{

            self.titleLabel.y = 20;

            self.leaveBtn.y = 20;

            [self setUpContentViewFrame:^(UIView *contentView) {

                contentView.frame = CGRectMake(0,64, kWidthOfScreen, kHeightOfScreen);

            }];

        }];

    }

}

Xcode7中你一定要知道的炸裂调试神技

原文链接:http://www.jianshu.com/p/70ed36cf8a98

Xcode7中苹果为我们增加了两个重要的debug相关功能。了解之后觉得非常实用,介绍给大家。

1.Address Sanitizer: 妈妈再也不用担心 EXC_BAD_ACCESS
EXC_BAD_ACCESS一直是很多开发者的噩梦,因为这个错误很不直观,出现后往往要花很长时间才能定位到错误。苹果这次带来了革命性的提升。

在项目的Scheme中Diagnostics下,选中enable address sanitizer(注意选中后Xcode会重新编译整个项目)。

225849-5d604702d59d27c7

这样设置后,如果再出现类似的错误会有更详细的错误信息提示,甚至会有内存使用情况的展示。

2.发布后的crash跟踪,轻松定位崩溃代码
在升级iOS9后,苹果会询问用户是否同意收集应用崩溃报告。这样在itunes connect的后台统计中就可以看到一些收集到的数据(通常会有相当一部分用户不同意,所以只是部分数据)。

2.1查看崩溃统计信息
在connect后台中选择app分析,进入分析页面后,tab中选择“指标”,然后在左侧的菜单中选择“崩溃”。

这样就可以看到苹果收集到的崩溃统计,一定要注意这里只是一部分的数据,举例来说如果你看到的崩溃是10次,但是可能苹果只收集了20%的用户信息。所以你可以大概估计应该是10*5=50次崩溃。

2.2在Xcode中查看具体崩溃信息
在xcode中菜单的window下选择organizer,在打开的窗口中选择Crashes,这样Xcode会开始下载相关的崩溃信息到本地中(网络环境不好时可能要等待一些时间)。

可以在左侧选择你要查看崩溃信息的发布版本

在崩溃信息这一栏苹果会按照崩溃数量排序,将崩溃数量最多的排在最前。右侧的详细信息会显示是崩溃时的调用堆栈,可以看到是哪行代码导致的崩溃。

选中要解决的崩溃后,可以在窗口右侧选择open in project。

神奇的事情发生了!!!在打开的项目中,会直接定位到崩溃的那行代码。这大大提高了调试的效率!我已经的迫不及待要和开发安卓的同事分享这份喜悦了。

注意!注意!

因为之前的项目发布时没有用xcode7打包,所以猜测符号表可能没有上传到苹果服务器,所以以前的项目可能不能直接显示是哪行代码,而是显示调用时出错的内存地址。不过下个版本你用xcode发布后就可以正常看到啦。

在解决完这个crash后可以标记为已经解决。有两个地方可以标记。

所以没有升级xcode7的同学赶紧升吧。O(∩_∩)O~

Objective-C基础笔记

001.类和对象(总结归纳)

002.创建类和对象(实例讲解)

003.设置器与访问器(实例讲解)

004.继承与实例化(总结归纳)

005.创建子类继承和重写父类方法(实例讲解)

006.初始化方法与便利构造器(实例讲解)

007.属性和点语法(实例讲解)

008.读写、原子、语义(总结归纳)

009.手动内存管理(总结归纳)

010.字符串合并、截取、转换(示例代码)

011.封装与属性可见度(总结归纳)

012.数组与字典(示例代码)

013.集合与枚举(示例代码)

014.封装基本数据类型(示例代码)