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:添加代理
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];
}
  • 启动界面直接强转竖屏(可以自选),其他界面可以按自己要求写

iOS 笔记(持续更新)_第1张图片
屏幕快照 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];
  • 使用系统的搜索框,自定义样式,重写。

iOS 笔记(持续更新)_第2张图片
重写的样式
//重写 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
  • 根据两点坐标计算方位角

    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;
    }

你可能感兴趣的:(iOS 笔记(持续更新))