iOS 笔记(持续更新)

文件下载或者上传后需要使用 MD5验证文件的完整性,不可简单的根据上传或下载完成后的回调来判断是否成功。

  • tabview 和 collectionView的长按抖动模式

#pragma mark - 抖动动画
#define Angle2Radian(angle) ((angle) / 180.0 * M_PI)
- (void)shakingAnimation:(UICollectionViewCell *)cell{
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    anim.keyPath = @"transform.rotation";
    
    anim.values = @[@(Angle2Radian(-2)), @(Angle2Radian(2)), @(Angle2Radian(-2))];
    anim.duration = 0.25;
    
    // 动画次数设置为最大
    anim.repeatCount = MAXFLOAT;
    // 保持动画执行完毕后的状态
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    
    [cell.layer addAnimation:anim forKey:@"shake"];
}
  • 逐行读取 txt 文件内容,将所需内容取出

#txt文件文件内容大概是这个样子的,x 和 y 的长度还不一样,但是最前面的是一样的长度,所以下面用的方式不一样
53282 X:13435840.64291;Y:3550350.6154879997
53280 X:13435846.923805503;Y:3550349.5415525
53279 X:13435853.009440003;Y:3550349.639183
53278 X:13435859.062531002;Y:3550349.5740960003

   #//获取txt 文件
    NSString *pathTxt =  [[NSBundle mainBundle] pathForResource:@"iBeaconPoint" ofType:@"txt"];
    //逐行添加到数组中
    NSArray *arr = [[NSString stringWithContentsOfFile:pathTxt] componentsSeparatedByString:@"\n"];
    //准备遍历数组
    NSEnumerator *enmu = [arr objectEnumerator];
    
    while (NSString *tmp = [enmu nextObject]) {
     //因为取出的内容为 nextObject,所以在下面判断取到的字符串长度不得=0
        if (tmp.length == 0) {
            break;
        }
        NSString *strMinor = nil;
        NSString *strX = nil;
        NSString *strY = nil;
        //截取字符串
        strMinor = [tmp substringWithRange:NSMakeRange(0,5)];
        //扫描对象
        NSScanner *scanner = [NSScanner scannerWithString:tmp];
        //用不同的特征获取数据
        [scanner scanUpToString:@"X:" intoString:nil];
        [scanner scanString:@"X:" intoString:nil];
        [scanner scanUpToString:@";" intoString:&strX];
        
        [scanner scanUpToString:@"Y:" intoString:nil];
        [scanner scanString:@"Y:" intoString:nil];
        [scanner scanUpToString:@";" intoString:&strY];
        
        
        NSLog(@"%@,%@,%@",[strX description],[strY description],[strMinor description]);
    }
  • 引用下别人的总结知识点,相当全面

http://www.jianshu.com/p/1ff9e44ccc78

  • 如何判断文件类型

这是链接,主要还是搜集文件头标示建立数据,以便在后面进行判断http://blog.csdn.net/yagerfgcs/article/details/51427085

  • Xcode注释快捷键

command+option+/      -> 快速注释(不同的位置不一样)
command+/             -> 双斜线
  • MacOS终端可以集成了MD5加密功能。输入命令:echo "待加密字符串" | md5
  • Widget 使用图片也是必不可少,然而 imageNamed: 和 imageWithContentsOfFile: 两种方式加载都不行,即使设置了文件的 target 为 Widget Extension,需要在其target 内部建立一个 .xcassets 文件即可加载图片。
  • dispatch_after 设置延时操作,是进行延时提交到操作队列,并不是先提交队列再延时。
  • 防止 app 审核不通过,在自定义目录数据存储的时候,需要在程序中给自定义的目录设置“do not backup”属性,防止数据会被 iCloud 备份,从而被拒上架。
  • 注销登录,直接回到登录界面

/**
  退出登录后需要 再获取主窗口 然后设置他的根控制器为登录界面
 */
   NavController *nav = [[NavController alloc] initWithRootViewController:[[MainLoginController alloc] init]];
   [UIApplication sharedApplication].keyWindow.rootViewController = nav;
/
如果要跳转的视图界面已将存在导航栏,则直接
[UIApplication sharedApplication].keyWindow.rootViewController = yourViewController;
  • 多层模态视图,直接回到 root 视图,瞒天过海

    UIViewController *rootVC = self.presentingViewController;
    
    while (rootVC.presentingViewController) {
        rootVC = rootVC.presentingViewController;
    }
    
    rootVC.view.alpha = 0.0;
    [rootVC dismissViewControllerAnimated:YES completion:nil];
  • 导航栏隐藏界面push 到导航栏显示界面的过渡方案

  • 1,第一种
//当前界面隐藏
       -(void)viewWillAppear(BOOL)animated{
            [super viewWillAppear:animated];
            [self.navigationController setNavigationBarHidden:YES animated:YES];
        }
 //下个界面显示
        -(void)viewWillAppear(BOOL)animated{
            [super viewWillAppear:animated];
            [self.navigationController setNavigationBarHidden:NO animated:YES];
        }
  • 2,第二种 swift 版(其实 OC 也差不多)
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(true)
            navigationController?.setNavigationBarHidden(true, animated: true)
         }
        override func viewDidDisappear(_ animated: Bool) {
            super.viewDidDisappear(true)
            navigationController?.setNavigationBarHidden(false, animated: true)
         }
  • push 界面后自定义返回按钮,需重写滑动手势返回代理方法

1:添加代理<UIGestureRecognizerDelegate>
2:让导航栏成为代理    
//使得 nav 成为手势的代理,自定义导航 leftButtonItem 时使用,以代替系统无法在自定义时使用右划返回。
    nav.interactivePopGestureRecognizer.delegate = self;
3:开始重写代理方法
 //#pragma 以下是当自定义 leftButtonItem 时,需重写右划返回方法,响应原系统右划返回。
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (self.viewControllers.count <= 1 ) {
        return NO;
    }
    return YES;
}
//允许同时响应多个手势
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
 }
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    
    return [gestureRecognizer isKindOfClass: UIScreenEdgePanGestureRecognizer.class];
}
  • 启动界面直接强转竖屏(可以自选),其他界面可以按自己要求写

屏幕快照 2017-04-12 下午12.59.28.png
 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    //set statusbar to the desired rotation position
    
 return  UIInterfaceOrientationMaskAllButUpsideDown;;
}
  • 屏幕强制旋转

1: 有 tabbar 和导航栏的情况,在自定义 tabbarController 里面添加下面代码。如果是自定义 tabbar 控件的话,可以看到下面的自定义tabbar,中间添加了一个类似于微博的发布按钮,在旋转屏幕后本身不在中间了,可以重新设置 layout 方法。

需要在 tabbar 里面处理,添加全局旋转判断 
    BOOL __shouldAutorotate;
//再注册旋转屏幕的通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(autorotateInterface:) name:@"InterfaceOrientation" object:nil];
再添加方法,接收通知信息
-(void)autorotateInterface:(NSNotification *)notifition
{
    __shouldAutorotate = [notifition.object boolValue];
    NSLog(@"接收到的通知>> %d", __shouldAutorotate);
}
/**
 *  @return 是否支持旋转
 */
-(BOOL)shouldAutorotate{
   NSLog(@"======>> %d", __shouldAutorotate);
    return  __shouldAutorotate;
}
/**
 *  适配旋转的类型
 *  @return 类型
 */
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    if (!__shouldAutorotate) {
        return UIInterfaceOrientationMaskPortrait;
    }
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

2只有导航栏的情况

自定义一个 navigation 类,里面添加方法,在控制器里面使用导航栏的的时候生效。
/**
 *
 *  @return 是否支持旋转
 */
-(BOOL)shouldAutorotate
{
    return NO;//这个可以仿照上面的判断添加全局之类的,我的只要竖屏,不要旋转,所以就先这样
}
/**
 *  适配旋转的类型
 *
 *  @return 类型
 */
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
//旋转类型自己改,按需求来。
     return UIInterfaceOrientationMaskPortrait;    
}
  • 自定义tabbar时,中间添加一个按钮-》移花接木。

1:自定义重写 tabbar

.h 继承 tabbar 重写
@interface MYtabbar : UITabBar
.m
/** 发布按钮 */
@property (nonatomic, strong) UIButton *publishButton;
 - (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        // 添加发布按钮
        _publishButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.height, self.height)];
        [_publishButton setImage:[UIImage imageNamed:@"publish"] forState:UIControlStateNormal];
        _publishButton.backgroundColor = [UIColor greenColor];
        [_publishButton sizeToFit];
        [_publishButton addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:_publishButton];
    }
    return self;
}
/**
 * 布局子控件
 */
 - (void)layoutSubviews
{
    [super layoutSubviews];
    
    // tabBar的尺寸
    CGFloat width = self.width;
    CGFloat height = self.height;
    // 按钮索引
    int index = 0; 
    // 按钮的尺寸
    CGFloat tabBarButtonW = width / 3;
    CGFloat tabBarButtonH = height;
    CGFloat tabBarButtonY = 0;
    
    // 设置3个TabBarButton的frame
    for (UIView *tabBarButton in self.subviews) {
        if (![NSStringFromClass(tabBarButton.class) isEqualToString:@"UITabBarButton"]) continue;
        
        // 计算按钮的X值
        CGFloat tabBarButtonX = index * tabBarButtonW;
        if (index == 1) { // 给后面2个button增加一个宽度的X值
            tabBarButtonX += tabBarButtonW;
        }
        
        // 设置按钮的frame
        tabBarButton.frame = CGRectMake(tabBarButtonX, tabBarButtonY, tabBarButtonW, tabBarButtonH);
        // 增加索引
        index++;
    }
    // 设置发布按钮的位置
    self.publishButton.center = CGPointMake(width * 0.5, height * 0.5);
    self.publishButton.width = SCREEN_WIDTH/3 ;
}
//重新布局使用,横竖屏切换时需要监听并调用此方法,不然会引起布局错误。上面的 layoutSubviews 走一次。
 -(void)layoutIfNeeded{
    // 设置发布按钮的位置
    self.publishButton.center = CGPointMake(self.width * 0.5, self.height * 0.5);
    self.publishButton.width = SCREEN_WIDTH/3 ;
}

其他控制器需要重现布局时调用

在自定义 tabbar 界面初始化重写的 
[self setValue:[[MYtabbar alloc] init] forKeyPath:@"tabBar"];
    ///横竖屏切换时调用此方法
 [self.tabBarController.tabBar layoutIfNeeded];

2:简单添加按钮到 tabbar,这个有点类似某直播的效果,按钮可以写的很大,但是触发范围需要重写才能改变。

    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0.0,0.0,70,70];

    //防止 button 的 image 被压缩变形
    UIImage *buttonImage = [[UIImage imageNamed:@"publish"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
    [button setImage:buttonImage forState:UIControlStateNormal];
    
    button.center = CGPointMake(SCREEN_WIDTH/2,self.tabBar.height/2);
    [button addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
    [self.tabBar addSubview:button];

3:投机取巧的方法
使用系统自身的 tabba ,添加他的viewControllers时,可以多添加一个,放在数组中间的位置。然后,使用上面的方法,直接自定义按钮添加上去,但是
// 选择指定的控制器视图显示,不可以选择到你写的那个假的抢位置控制器.

    [self setSelectedIndex:2];//不谢默认是0

创建的方法

/**
 *  Tabbar创建
 */
 - (void)createSystemTabbar{
   MapViewController *mapView = [[MapViewController alloc] init];
    DataViewController *dataView = [[DataViewController alloc] init];
    PublishViewController *publish = [[PublishViewController alloc] init];#抢位子用的
    self.viewControllers = [NSArray arrayWithObjects:
                            [self createNavWithViewController:mapView WithTitle:@"地图" image:[UIImage imageNamed:@"map_sel"] unselectImage:[UIImage imageNamed:@"map"]],

                            [self createNavWithViewController:publish WithTitle:@"" image:[UIImage imageNamed:@"publish"] unselectImage:[UIImage imageNamed:@""]],
                            
                            [self createNavWithViewController:dataView WithTitle:@"数据" image:[UIImage imageNamed:@"data_sel"] unselectImage:[UIImage imageNamed:@"data"]],
                            
                            nil];
    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0.0,0.0,SCREEN_WIDTH/3,self.tabBar.height)];
    //防止 button 的 image 被压缩变形
    UIImage *buttonImage = [[UIImage imageNamed:@"publish"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
    [button setImage:buttonImage forState:UIControlStateNormal];
    
    button.center = CGPointMake(SCREEN_WIDTH/2,self.tabBar.height/2);

    [button addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
    [self.tabBar addSubview:button];
//按钮置顶
//[self.tabBar bringSubviewToFront:button];

  //    选择指定的控制器视图显示,不可以选择1.
    [self setSelectedIndex:2];

 }
  • 计算每个月的天数

/**
 计算每个月的天数
 @param year 年份
 @param month 月份
 @return 返回天数
 */
 - (NSInteger)DaysfromYear:(NSInteger)year andMonth:(NSInteger)month
 {
    NSInteger num_year  = year;
    NSInteger num_month = month;
    
    //判断是否是闰年 整除以4、100、400 则为闰年
    BOOL isrunNian = num_year%4==0 ? (num_year%100==0? (num_year%400==0?YES:NO):YES):NO;
    switch (num_month) {
        case 1:case 3:case 5:case 7:case 8:case 10:case 12:{
            [self setdayArray:31];
            return 31;
        }
        case 4:case 6:case 9:case 11:{
            [self setdayArray:30];
            return 30;
        }
        case 2:{
            if (isrunNian) {
                [self setdayArray:29];
                return 29;
            }else{
                [self setdayArray:28];
                return 28;
            }
        }
        default:
            break;
    }
    return 0;
}
  • tabView 的 cell 重用混乱问题,两个不同的解决办法
    //指定不同的 identity 
    NSString *ident = [NSString stringWithFormat:@"InfoCell%zd%zd",indexPath.section,indexPath.row];
    InfoCell *cell = [tableView dequeueReusableCellWithIdentifier:ident];
    
    //指定位置
    InfoCell *cell = [tableView cellForRowAtIndexPath:indexPath];
  • 使用系统的搜索框,自定义样式,重写。

重写的样式
//重写 searchBar ,继承 UIsearchBar
 -(void)layoutSubviews{
    for (UIView *view in self.subviews) {
        
        for (UIView *subView in view.subviews) {
            
            if ([subView isKindOfClass:[UITextField class]]) {

                subView.frame = CGRectMake(0, 0, self.bounds.size.width,  self.bounds.size.height);
            } 
        }
    }
}
  • 线程问题,串行异步,一个子线程循环执行任务

dispatch_queue_t queueA = dispatch_queue_create("bufujquigj", DISPATCH_QUEUE_SERIAL);
    for (NSInteger i = 1; i<nn+1; i++) {
        dispatch_async(queueA, ^{   
            dispatch_async(dispatch_get_main_queue(), ^{       
               //刷新 UI
            });  
            [NSThread sleepForTimeInterval:1.0/nn]; 
            NSLog(@"jbfkjsdkjsdjf:       %ld    %@",(long)i    ,[NSThread currentThread]);    
            if (i == nn) {    
                //用来判断第几次执行,不要将这个判断放在外边。
            }
        });
    }
  • 根据两点坐标计算方位角

    double rads = 0;//角度
    double currentX = _currentLocalPoint.x;
    double nextX    = nextPoint.x;
    double currentY = _currentLocalPoint.y;
    double nextY    = nextPoint.y;
   
    rads = sin(currentX)*sin(nextX) + cos(currentX)*cos(nextX)*cos(nextY-currentY);
    rads = sqrt(1-rads*rads);
    rads = cos(currentX)*sin(nextY - currentY)/rads;
    rads = asin(rads) * 180 / M_PI;//夹角是正数,按需判断转换
  if (_currentLocalPoint.y > nextPoint.y) {
        rads = -rads;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,421评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 我想我们这样活着: 把每一瞬间的场景都当成风景, 对每一个亲近的人都竭力真诚, 把每一份温暖铭记于心, 把每一场落...
    七一骜阅读 183评论 0 1
  • 雨中没伞的孩子,只有自己努力向前奔跑! 子涵和子昂都是独生子女,所以在毕业分配时,双方的老人都想让自己的孩子回到各...
    LH来慧阅读 850评论 19 15
  • 如何让你能爱我? 我问远山, 远山画出你如隼双眸, 只是不看我。 如何让你能爱我? 我问清风, 清风传来你低沉声音...
    一帘风絮阅读 238评论 0 0