sauchye / iosdev_notes

iOS Dev Tips(一些零散的iOS知识tips)
19 stars 5 forks source link

Learning #4

Open sauchye opened 9 years ago

sauchye commented 9 years ago

题记:想成为一名靠谱的iOSer没那么简单吧...

iOS长期学习路线以及必备技能

学习资源

Swift 5.0

https://www.runoob.com/manual/gitbook/swift5

https://developer.apple.com/library/ios/navigation/ http://nshipster.com/ http://www.raywenderlich.com/ http://objc.io/ http://objccn.io/ (喵神@onevcat 组织) http://www.cocoachina.com/ios/ ...

RxSwift

https://www.jianshu.com/p/f61a5a988590

2015优秀博客

http://segmentfault.com/bookmark/1230000004250380

前言:纸上得来终觉浅,绝知此事要躬行。

源码

https://github.com/ 国内,涵盖一些UI效果图 http://code4app.com/ http://code.cocoachina.com/

前言:开源是一种美德,分享是一种态度。

社区、论坛、分享

话说求人不如求自己,不到万不得已,自己还是先试试,或许关键字不对... https://devforums.apple.com http://stackoverflow.com http://iphonedevsdk.com/forum http://www.developerfeed.com/profile/ios-developer 国内资源分享 http://toutiao.io/ http://www.cocoachina.com/ios/ http://blog.fir.im/fir_im_weekly151211/ http://tech.glowing.com/cn/ http://bbs.iosre.com/ https://github.com/sauchye/iosdev_notes/issues/4#issue-105941579

提高篇

https://github.com/sauchye/iosdev_notes/issues/13 ...

GitHub搜索

https://github.com/search?l=Objective-C&p=2&q=game&s=stars&type=Repositories

之前看过一篇Blog,Giter请不要鄙视SVNer,但我依然强烈建议使用、熟悉Git流程

版本管理

工欲善其身,必先利其器。

插件管理

  • Xcode插件

http://www.cocoachina.com/industry/20130918/7022.html http://blog.devtang.com/blog/2014/03/05/use-alcatraz-to-manage-xcode-plugins/

http://revealapp.com/ (免费30天)

https://github.com/robbyrussell/oh-my-zsh

来自巧大推荐的iOS/Mac OS开发博客

@tangqiaoboy https://github.com/tangqiaoboy/iOSBlogCN

前言:练就了一身本领,就等华山论剑了。

求职跳槽篇,基础补脑。


收集项目中常遇到一些UI需求

ScrollView

...

WebView 加载处理

https://github.com/Roxasora/RxWebViewController (类似微信,支付宝,UC浏览器加载) https://github.com/TransitApp/SVWebViewController https://github.com/ninjinkun/NJKWebViewProgress https://github.com/TimOliver/TOWebViewController

SDWebImage加载网络图片

https://github.com/JJSaccolo/UIActivityIndicator-for-SDWebImage (小菊花显示加载中)

网络图片加载框架

https://github.com/rs/SDWebImage https://github.com/ibireme/YYImage https://github.com/onevcat/Kingfisher (Swift)

sauchye commented 9 years ago

干货

http://bawn.github.io/ios/2014/11/24/Miscellany.html

Label各种字体显示设置

http://blog.csdn.net/tongzhitao/article/details/7861459

画虚线

- (void)strokeDashLineAddToView:(UIView *)view
                    strokeColor:(UIColor *)strokeColor{

    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    [shapeLayer setBounds:view.bounds];
    [shapeLayer setPosition:view.center];
    [shapeLayer setFillColor:[[UIColor clearColor] CGColor]];

    // strokeColor is dashLine CGColor, 1.0f is dashLine width

    [shapeLayer setStrokeColor:strokeColor.CGColor];
    [shapeLayer setLineWidth:1.0f];
    [shapeLayer setLineJoin:kCALineJoinBevel];

    // 15 is dashLine width, 5 is dashLine space
    [shapeLayer setLineDashPattern:
     [NSArray arrayWithObjects:[NSNumber numberWithInt:15],
      [NSNumber numberWithInt:5],nil]];

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, CGRectGetWidth(view.frame), 0);

    [shapeLayer setPath:path];
    CGPathRelease(path);
    [view.layer addSublayer:shapeLayer];
}

图片处理

http://blog.csdn.net/q199109106q/article/details/8615661

判断字符串含有空格

[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0

http://blog.csdn.net/zhangao0086/article/details/7234859

状态栏随意玩

首先去 Info.plist 里面,把 UIViewControllerBasedStatusBarAppearance 设置为 NO.

然后在你想要改变状态栏颜色的任何地方,写下面这行代码

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.Default, animated: true)

或者

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
参考:

http://www.jianshu.com/p/9d6b6f790493

导航栏随便玩

添加多个ButtonItem

    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH - 80, 0, 80, 30)];
    UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:v];
    self.navigationItem.rightBarButtonItem = barItem;

玩转导航栏颜色

 // 导航相关设置 导航栏颜色设置
    [self.navigationBar setBarTintColor:kNAVIGATION_BAR_COLOR];
    //返回按钮颜色设置
    self.navigationBar.tintColor = [UIColor whiteColor];

    //navTitle字体颜色设置
    [self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
    [self.navigationBar setTranslucent:NO];

更改系统相册返回、取消按钮颜色, 遵循UINavigationControllerDelegate代理

#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
      willShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated{

    viewController.navigationController.navigationBar.tintColor = [UIColor whiteColor];
}

Controller

UINavigationController 修改某一导航控制器Item的颜色,如:访问相册时修改Cancle(默认蓝色)的颜色

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{

    viewController.navigationItem.rightBarButtonItem.tintColor = [UIColor whiteColor];
}

解决全屏设置一个NavigationController的背景图片会出现一条横线

    [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init]
                                      forBarPosition:UIBarPositionAny
                                          barMetrics:UIBarMetricsDefault];

    [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];

参考: http://my.oschina.net/ioslighter/blog/411972?p=1

保存图片,MV到相册

保存图片,MV到相册

    NSString *strPath = [[NSBundle mainBundle] pathForResource:@"11.jpg" ofType:nil];

    UIImage *image = [UIImage imageWithContentsOfFile:strPath];

    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

参看: http://blog.csdn.net/iukey/article/details/8017331 http://www.cnblogs.com/weilaikeji/archive/2013/03/10/2953206.html

生成推送pem

openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes

performSelector延时调用导致的内存泄露,在dealloc

[NSObject cancelPreviousPerformRequestsWithTarget:self];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:) object:nil]

http://blog.csdn.net/wangqiuyun/article/details/7587929

关闭tableViewCell点击效果

        cell.selectionStyle = UITableViewCellSelectionStyleNone;

比较一个时间是否在一个时间段内,如:8:20是否在9:00-10:00内

/**
 * @brief 判断当前时间是否在fromHour和toHour之间。如,fromHour=8,toHour=23时,即为判断当前时间是否在8:00-23:00之间
 */
- (BOOL)isBetweenFromHour:(NSInteger)fromHour toHour:(NSInteger)toHour
{
  NSDate *date8 = [self getCustomDateWithHour:8];
  NSDate *date23 = [self getCustomDateWithHour:23];

  NSDate *currentDate = [NSDate date];

  if ([currentDate compare:date8]==NSOrderedDescending && [currentDate compare:date23]==NSOrderedAscending)
  {
    NSLog(@"该时间在 %d:00-%d:00 之间!", fromHour, toHour);
    return YES;
  }
  return NO;
}

/**
 * @brief 生成当天的某个点(返回的是伦敦时间,可直接与当前时间[NSDate date]比较)
 * @param hour 如hour为“8”,就是上午8:00(本地时间)
 */
- (NSDate *)getCustomDateWithHour:(NSInteger)hour
{
  //获取当前时间
  NSDate *currentDate = [NSDate date];
  NSCalendar *currentCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
  NSDateComponents *currentComps = [[NSDateComponents alloc] init];

  NSInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

  currentComps = [currentCalendar components:unitFlags fromDate:currentDate];

  //设置当天的某个点
  NSDateComponents *resultComps = [[NSDateComponents alloc] init];
  [resultComps setYear:[currentComps year]];
  [resultComps setMonth:[currentComps month]];
  [resultComps setDay:[currentComps day]];
  [resultComps setHour:hour];

  NSCalendar *resultCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
  return [resultCalendar dateFromComponents:resultComps];
}

http://blog.csdn.net/yuedong56/article/details/37600067

解决后台数据返回NSNull,导致Crash

https://github.com/nicklockwood/NullSafe

键盘遮挡问题

https://github.com/stars?utf8=%E2%9C%93&q=keyBoard https://github.com/hackiftekhar/IQKeyboardManager https://github.com/michaeltyson/TPKeyboardAvoiding ...

+ (void)IQKeyboardAutoToolbar:(BOOL)autoToolbar{

    IQKeyboardManager *manager = [IQKeyboardManager sharedManager];
    manager.enable = YES;
    manager.shouldResignOnTouchOutside = YES;
    manager.shouldToolbarUsesTextFieldTintColor = YES;
    manager.enableAutoToolbar = autoToolbar;

}

添加可变的字符串到ActionSheet

    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"title" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:nil, nil];;
    for ( NSInteger i = 0; i < installMaps.count; i ++) {

        [sheet addButtonWithTitle:installMaps[i]];

    }

    [sheet showInView:self.view];

自定义界面横竖屏

http://www.cnblogs.com/sunkaifeng/p/5191172.html

sauchye commented 9 years ago

Xcode Setting

Xcode Plugin

~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/

Fix project warning(解决项目中的warning)

Build Setting->Other Warning Flags Add:

-Wno-shorten-64-to-32
-Wno-sizeof-array-argument
-Wno-sizeof-pointer-memaccess

Xcode New Category

New(cmmand + N)->Source->Objective-C->File Type(Choose Category)

Xcode Project加速运行

工程目录->TARGETS->Build Settings->Build Options 设置Debug模式为:_DWARF_即可

sauchye commented 9 years ago

User Experience(优化用户体验)

获取用户是否开启通知

- (BOOL)isAllowedNotification {

    if (FSystemVersion >= 8.0) {
        UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
        if (setting.types != UIUserNotificationTypeNone) {
            return YES;
        }
    } else {

        UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
        if(type != UIRemoteNotificationTypeNone)
            return YES;
    }

    return NO;
}

优雅的处理iOS系统相关权限(iOS7及以上)

获取AVAudioSession录音权限

if ([[AVAudioSession sharedInstance] respondsToSelector:@selector(requestRecordPermission:)]){
   [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {

       if (granted) {
           //用户已允许,直接进行录制等,逻辑操作...

       }else {
           //用户拒绝,引导用户开启麦克风服务,直接跳转到该应用设置页面
       }
   }];

}

获取CLLocationManager定位权限
kCLAuthorizationStatusNotDetermined 用户没有做出选择
kCLAuthorizationStatusRestricted    无法使用定位服务,该状态用户无法改变
kCLAuthorizationStatusDenied        用户拒绝该应用使用定位服务或是定位服务总开关处于关闭状态

iOS 8
kCLAuthorizationStatusAuthorizedAlways  用户同意程序在可见时使用地理位置
kCLAuthorizationStatusAuthorizedWhenInUse 用户允许该程序运行时可以使用地理信息
kCLAuthorizationStatusAuthorized    用户允许该程序无论何时都可以使用地理信息

    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied  ) {
        //用户已拒绝开启定位服务,处理逻辑...
        //前往 开启定位授权
            if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {

                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" 
message:@"请在iPhone的“设置->隐私->位置”中允许访问位置信息" 
delegate:self cancelButtonTitle:nil otherButtonTitles:@"取消", @"设置", nil];
                [alertView show];
            }else{
                kTipsAlert(@"请在iPhone的“设置->隐私->位置”中允许访问位置信息");
            }

    }else{
        //用户已同意开启定位服务,处理逻辑...
    }

直接跳转到该App设置页面,就是这样。

   UIApplication *app = [UIApplication sharedApplication];
   NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
   if ([app canOpenURL:settingsURL]) {
       [app openURL:settingsURL];
   }
sauchye commented 9 years ago

iOS NSPredicate(iOS相关正则)

iOS 最新手机号码正则表达式

+ (BOOL)isVaildMobileNumber:(NSString *)mobileNumber{

//    NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
//  
//    NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
// 
//    NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
//
//    NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
//
//    
//    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
//    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
//    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
//    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
//    
//    if (([regextestmobile evaluateWithObject:mobileNumber] == YES)
//        || ([regextestcm evaluateWithObject:mobileNumber] == YES)
//        || ([regextestct evaluateWithObject:mobileNumber] == YES)
//        || ([regextestcu evaluateWithObject:mobileNumber] == YES)){
//        
//        return YES;
//    }else{
//        return NO;
//    }

    NSString *regex = @"1[3|4|5|7|8|9][0-9]{9}";
    //    NSString *regex = @"^((13[0-9])|(147)|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    BOOL isMatch = [pred evaluateWithObject:mobileNumber];
    return isMatch;

}
sauchye commented 9 years ago

iPhone Device

iPhone Info (iPhone Design)

型号                       启动图尺寸         分辨率            几倍图
iPhone 4/4s                320*480           640*960            2x
iPhone 5/5s                320*568           640*1136           2x
iPhone 6/6s                375*667           750*1334           2x
iPhone 6/6s Plus           414*736          1242*2208           3x
sauchye commented 9 years ago

UI相关

UILabel 同一个label自定义显示颜色

+ (NSMutableAttributedString *)attributedString:(NSString *)string
                                    rangeToText:(NSString *)text
                                      textColor:(UIColor *)textColor{

    NSRange range = [string rangeOfString:text];
    NSMutableAttributedString *attribute = [[NSMutableAttributedString alloc] initWithString:string];
    [attribute addAttributes:@{NSForegroundColorAttributeName:textColor} range:range];

    return attribute;
}

    textLbl.attributedText = [CDManager attributedString:text
                                             rangeToText:@"ABC"
                                               textColor:[UIColor grayColor]];

UIButton:设置图片按钮,上下显示title

关键代码

        //Title Top 显示
        [b setBackgroundImage:[UIImage imageNamed:@"xxx"] forState:UIControlStateNormal];
        b.titleEdgeInsets = UIEdgeInsetsMake(b.frame.size.height + 30, 0.0, 0.0, 0.0);

UIButton图片按钮左右显示title

https://github.com/kubatru/JTImageButton

Notice

Button设置圆角后设置titleEdgeInsets后title无法显示,解决方法

      //btn.layer.masksToBounds = YES;(去掉即可)
     btn.layer.cornerRadius = btn.frame.size.height / 2;

设置图片按钮layer的颜色

        btn.layer.borderColor = [UIColor orangeColor].CGColor;
        btn.layer.borderWidth = 0.5;

UITextField

修改UITextField光标颜色

self.usernameTextField.tintColor = kNAVIGATION_BAR_COLOR;

UIView抖动效果

比如登录或注册页面,用户输入错误或者设置有误,抖动UITextField,就比较好了,再设置错误UITextFieldborderColor的颜色,我觉得就是比较完美的交互了。

- (void)shakeAnimationForView:(UIView *)view isVerticalShake:(BOOL)isVerticalShake{

    CALayer *layer = [view layer];
    CGPoint posLbl = [layer position];
    CGPoint x, y;

    if (!isVerticalShake) {

        y = CGPointMake(posLbl.x - 10, posLbl.y);
        x = CGPointMake(posLbl.x + 10, posLbl.y);
    }else{
        y = CGPointMake(posLbl.x, posLbl.y - 5);
        x = CGPointMake(posLbl.x, posLbl.y + 5);
    }

    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setTimingFunction:[CAMediaTimingFunction
                                  functionWithName:kCAMediaTimingFunctionEaseOut]];
    [animation setFromValue:[NSValue valueWithCGPoint:x]];
    [animation setToValue:[NSValue valueWithCGPoint:y]];
    [animation setAutoreverses:YES];
    [animation setDuration:0.09];
    [animation setRepeatCount:3];
    [layer addAnimation:animation forKey:nil];
}

参考 https://github.com/sauchye/SYTipsDemo/blob/master/SYTipsDemo/Controllers/Third/SYLoginViewController.m

UITableView

UITableViewStyleGrouped 样式TableView设置 每个section height

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{

    if (section == 0){
        return 15.0f;
    }
    return 20.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    //取巧的做法
    return 0.000001f;
}

详解: http://www.cnblogs.com/kenshincui/p/3931948.html


UISearchController 定制SearchBar

http://www.brighttj.com/ios/how-to-create-a-custom-search-bar-using-uisearchcontroller.html

sauchye commented 9 years ago

Tips

AFNetWorking 简单判断网络存在情况

sauchye commented 9 years ago

iOS语言国际化

1、选中工程->PROJECT->Localizations 添加需要国际化的语言

add language

2、新建Strings File,分别新建:InfoPlist和Localizable

new strings

3、选择添加的语言

localization language

4、最后就比较容易了

InfoPlist.string中存放App命名

CFBundleDisplayName = "iOS奇淫技巧”;(Chinese(Simplified))

CFBundleDisplayName = "iOSTipsDemo”;(English)

Localisable

(English)
"Home" = "Home";

"Found" = "Found";

"Me" = "Me";

Chinese(Simplified)
"Home" = "主页";

"Found" = "发现";

"Me" = "我";

可参考: https://github.com/sauchye/SYTipsDemo

获取系统语言判断

+ (NSString *)currentDeviceLanguage{

    NSArray *languages = [NSLocale preferredLanguages];
    NSString *currentLanguage = [languages objectAtIndex:0];

    return currentLanguage;
}
常用的语言判断iOS8 iOS9有差别
+ (BOOL)isZh_Hans_CN{

    //zh-Hans x86_64
    return  [[self currentDeviceLanguage] isEqualToString:@"zh-Hans-CN"] ||
                [[self currentDeviceLanguage] isEqualToString:@"zh-Hans-US"] ||
                      [[self currentDeviceLanguage] isEqualToString:@"zh-Hans"] ||
                      [[self currentDeviceLanguage] isEqualToString:@"x86_64"];
}

+ (BOOL)isEN_US{

    // en-CN
    return [[self currentDeviceLanguage] isEqualToString:@"en-CN"] ||
                [[self currentDeviceLanguage] isEqualToString:@"en-US"];
}
sauchye commented 9 years ago

ARC

http://www.jianshu.com/p/1928b54e1253 http://www.jianshu.com/p/09c5141d4531?utm_campaign=maleskine&utm_content=note&utm_medium=writer_share&utm_source=weibo#

sauchye commented 8 years ago

Tag遍历所有的按钮

  for (NSInteger i = babyGenderTag; i <= sender.tag + 1; i ++) {
        UIButton *btn = (UIButton *)[self.view viewWithTag:i];
        btn.selected = NO;
    }
   for (UIView *v in allView.subviews) {
        if ([v isKindOfClass:[UIButton class]]) {
            UIButton *btn = (UIButton *)v;
    }

数组排序

"time" 数组中字典的key,NO表示升序

     NSArray *sortDescriptors = [NSArray arrayWithObject:
                                    [NSSortDescriptor sortDescriptorWithKey:@"time"
                                                                  ascending:NO]];
        [self.data sortUsingDescriptors:sortDescriptors];
sauchye commented 8 years ago

Json转Plist相互转换

http://json2plist.sinaapp.com/

Code Review

http://mtydev.net/?p=59#comment-680 http://coolshell.cn/articles/11432.html#more-11432

一些姿势

http://toutiao.io/subjects/35291

Cell复用文字加深处理

    if (!cell) {

        cell = [[CDRemindCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cdRemindCell];
    }else{
        while ([cell.contentView.subviews lastObject] != nil) {
            [(UIView *)[cell.contentView.subviews lastObject] removeFromSuperview];
        }
    }

设置tableViewCell 的背景色

tableView.backgroundColor = [UIColor clearColor];

//cell self.backgroundColor = [UIColor clearColor];

self.contentView.backgroundColor = [UIColor clearColor];

  cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.contentView.frame];
  cell.selectedBackgroundView.backgroundColor = backgroundColor;

内存问题

imageNamedimageWithContentsOfFile的区别

http://www.cnblogs.com/pengyingh/articles/2355033.html

指定路径

NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:pathName];
    BOOL bo = [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
    NSAssert(bo,@"创建目录失败");

    NSString *result = [path stringByAppendingPathComponent:fileName];

pickerView去掉系统2条横线

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
    CGFloat width = 125.0f;
    CGFloat height = 20.0f;

    UIView * myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];

    UILabel * complateLabel = [[UILabel alloc] init];
    complateLabel.center = myView.center;
    complateLabel.bounds = CGRectMake(0, 0, width, height);
    complateLabel.textColor = [UIColor blackColor];
    complateLabel.textAlignment = NSTextAlignmentCenter;
    complateLabel.font = [UIFont systemFontOfSize:22.f];
    complateLabel.text = _startArray[component][row];
    [myView addSubview:complateLabel];

    ((UIView *)[_startPickerView.subviews objectAtIndex:1]).backgroundColor = [UIColor clearColor];
    if (IS_IOS7) {
        ((UIView *)[_startPickerView.subviews objectAtIndex:2]).backgroundColor = [UIColor clearColor];
    }
    return myView;
}

TextField限制输入长度

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

    NSMutableString *text = [textField.text mutableCopy];
    [text replaceCharactersInRange:range withString:string];

    if (textField == self.phoneTextField) {

        return  text.length <= 11;

    }else if (textField == self.codeTextField){

        return text.length <= 6;

    }else if (textField == self.usernameTextField){
        return text.length <= 6;
    }
    return YES;
}

SearchBar

    [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor whiteColor]];
    [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTitle:@"取消"];
searchBar.searchBarStyle = UISearchBarStyleMinima;
sauchye commented 8 years ago

解决无导航栏push到有导航栏bug


- (void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:animated];
}

- (void)viewWillDisappear:(BOOL)animated{

    [super viewWillDisappear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

参考: http://blog.luckymore.wang/2015/05/19/iOS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E4%BB%8EQQ%E7%9A%84%E4%B8%80%E4%B8%AABug%E5%BC%95%E5%8F%91%E7%9A%84%E5%85%B3%E4%BA%8E%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%9A%84%E6%80%9D%E8%80%83/

http://www.jianshu.com/p/e4448c24d900/comments/3851074

sauchye commented 7 years ago

UITableView UITableViewStyleGrouped 去掉段头空白

self.automaticallyAdjustsScrollViewInsets = NO;

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 0.01f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    return 10.f;
}

UITableView Cell单选

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSArray *array = [tableView visibleCells];
    for (UITableViewCell *cell in array) {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}

UITableViewHeaderFooterView 背景色

- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section {
    view.tintColor = [UIColor clearColor];
}

更新图片 UIImage *img = [info objectForKey:@"UIImagePickerControllerEditedImage"];

goto tabbarController

- (void)goToTabarController:(UIViewController *)controller{

    if ([self.view.window.rootViewController isKindOfClass:[ZDTabBarController class]]) {
        /// 已经进入主页面
        return;
    }

    ZDTabBarController *tabController = [[ZDTabBarController alloc] init];
    tabController.view.frame = self.view.window.bounds;
    [UIView transitionWithView:self.view.window
                      duration:0.01
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        self.view.window.rootViewController = tabController;
                    }
                    completion:nil];
}

check installed map

+ (NSArray *)checkInstallMapApps{
    //
    NSArray *mapSchemeArr = @[@"http://maps.apple.com/", @"iosamap://navi",@"baidumap://map/", @"comgooglemaps://"];

//    NSMutableArray *appListArr = [[NSMutableArray alloc] initWithObjects:@"苹果地图", nil];
    NSMutableArray *appListArr = [NSMutableArray new];

    for (int i = 0; i < [mapSchemeArr count]; i++) {
        if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",[mapSchemeArr objectAtIndex:i]]]]) {
            if (i == 0) {
                [appListArr addObject:@"苹果地图"];
            }else if (i == 1){
                [appListArr addObject:@"高德地图"];
            }else if (i == 2){
                [appListArr addObject:@"百度地图"];
            }else{
                [appListArr addObject:@"谷歌地图"];
            }
        }
    }
    return appListArr;
}

plist

New iPhone

//判断iPHoneX XS
/*-------------- isiPhone尺寸 宏定义--------------*/
#define iPhoneXBottomHeight (isiPhoneXAll?34:0)
#define iPhoneXHeadHeight (isiPhoneXAll?22:0)
#define isiPhone4 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
#define isiPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
#define isiPhone6 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(750, 1334), [[UIScreen mainScreen] currentMode].size) : NO)
#define isiPhone6p ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2208), [[UIScreen mainScreen] currentMode].size) : NO)
//判断iPHoneX XS
#define isiPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
//判断iPhoneXR
#define isiPhoneXR ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) && !UI_IS_IPAD : NO)
//判断iPhoneXs Max
#define isiPhoneXS Max ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) && !UI_IS_IPAD : NO)
///#define isiPhoneXAll (isiPhoneX || isiPhoneXR || isiPhoneXMAX) 横屏:width 竖屏:height
#define isiPhoneXAll ([UIScreen mainScreen].bounds.size.width == 414 || [UIScreen mainScreen].bounds.size.height == 896)

画对角圆角,两个圆角或圆角:

    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
    imageView.image = [Tools getAppIconImage];
    // 绘制圆角 需设置的圆角 使用"|"来组合
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                                   byRoundingCorners:UIRectCornerTopLeft| UIRectCornerBottomRight         cornerRadii:CGSizeMake(30, 30)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
    // 设置大小
    maskLayer.frame = imageView.bounds;
    maskLayer.path  = maskPath.CGPath;
    imageView.layer.mask = maskLayer;
    [self.view addSubview:imageView];
    [imageView setCenter:self.view.center];
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    imageView.image = [Tools getAppIconImage];
    // 开始对imageView进行画图
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 0.0);
    // 使用贝塞尔曲线画出一个圆形图
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip];
    [imageView drawRect:imageView.bounds];
    imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self.view addSubview:imageView];
    [imageView setCenter:self.view.center];

https://juejin.im/post/5be5390df265da61163949f6

sauchye commented 7 years ago

https://github.com/soffes/SAMKeychain

import <SAMKeychain/SAMKeychain.h>

        NSDictionary *dd = @{@"pwd":self.passwordTextField.text,
                             @"name":self.accountTextField.text,
                             @"gender":@"1",
                             @"age":@"22"};

        NSData *data = [NSJSONSerialization dataWithJSONObject:dd options:NSJSONWritingPrettyPrinted error:nil];
        //save data
        [SAMKeychain setPasswordData:data
                          forService:serviceKey
                             account:self.accountTextField.text
                               error:nil];
        //save string
        [SAMKeychain setPassword:self.passwordTextField.text
                      forService:serviceKey
                         account:self.accountTextField.text];

    // delete
    [SAMKeychain deletePasswordForService:serviceKey
                                  account:self.accountTextField.text];

        //read
        NSString *dataString = [SAMKeychain passwordForService:serviceKey account:self.accountTextField.text];
        NSDictionary *dddd = [self dictionaryWithJsonString:dataString];
sauchye commented 7 years ago

 内购

https://www.jianshu.com/p/cb1c8b4ba2c0 https://www.jianshu.com/p/86ac7d3b593a https://www.cnblogs.com/TheYouth/p/6847014.html

sauchye commented 7 years ago

spare 避免输入表情 emoji https://gist.github.com/cihancimen/4146056


- (BOOL)stringContainsEmoji:(NSString *)string {
__block BOOL returnValue = NO;
[string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
     const unichar hs = [substring characterAtIndex:0];
     // surrogate pair
     if (0xd800 <= hs && hs <= 0xdbff) {
         if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
             if (0x1d000 <= uc && uc <= 0x1f77f) {
                 returnValue = YES;
             }
         }
     } else if (substring.length > 1) {
         const unichar ls = [substring characterAtIndex:1];
         if (ls == 0x20e3) {
             returnValue = YES;
         }

     } else {
         // non surrogate
         if (0x2100 <= hs && hs <= 0x27ff) {
             returnValue = YES;
         } else if (0x2B05 <= hs && hs <= 0x2b07) {
             returnValue = YES;
         } else if (0x2934 <= hs && hs <= 0x2935) {
             returnValue = YES;
         } else if (0x3297 <= hs && hs <= 0x3299) {
             returnValue = YES;
         } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
             returnValue = YES;
         }
     }
 }];

return returnValue;

}

sauchye commented 5 years ago

spare