面经ios开发整理iOS开发

【转】常用常忘的iOS知识点搜集

2018-07-12  本文已影响46人  悄然林静

原帖地址: iOS小技巧总结,绝对有你想要的
原作者:iOS_小松哥
十分拜服!这里先手抄一份,会陆续把自己整理的知识点也加进来。

iOS开发中常遇到小的知识点,常用常忘,特此集中记录以备查阅。

1. UITableView样式设置

1.1 UITableView在Grouped样式下顶部空白
// 给tableView设置一个不可见的表头,可以防止Grouped模式下的顶部空白
UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0.1)];
self.tableView.tableHeaderView = headerV;
1.2 UITableView在plain样式下,取消组头停滞效果
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    CGFloat sectionHeaderHeight = sectionHead.height;   // 这里有个报错
    if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0)
    {
        scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
    }
    else if(scrollView.contentOffset.y>=sectionHeaderHeight)
    {
        scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
    }
}

2. 获取view所在的父控制器

- (UIViewController *)getFatherVC {
    
    UIViewController *vc = nil;
    UIResponder *next = self.nextResponder;
    
    while (next) {
        if ([next isKindOfClass:[UIViewController class]]) {
            vc = (UIViewController *)next;
            break;
        }
        next = next.nextResponder;
    }
    return vc;
}

3. 清空NSUserDefaults

//方法一
- (void)resetDefaultsOne {
    NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
}


//方法二
- (void)resetDefaultsTwo {
    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
    NSDictionary * dict = [defs dictionaryRepresentation];
    for (id key in dict){
        [defs removeObjectForKey:key];
    }
    [defs synchronize];
}

4. 打印系统所有已注册的字体名称

#pragma mark - 打印系统所有已注册的字体名称
void enumerateFonts()
{
    for(NSString *familyName in [UIFont familyNames])
   {
        NSLog(@"%@",familyName);               
        NSArray *fontNames = [UIFont fontNamesForFamilyName:familyName];       
        for(NSString *fontName in fontNames)
       {
            NSLog(@"\t|- %@",fontName);
       }
   }
}

5. 取图片中某一像素点的颜色(UIImage分类方法)

- (UIColor *)colorAtPixel:(CGPoint)point
{
    if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point))
    {
        return nil;
    }
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    int bytesPerPixel = 4;
    int bytesPerRow = bytesPerPixel * 1;
    NSUInteger bitsPerComponent = 8;
    unsigned char pixelData[4] = {0, 0, 0, 0};
    
    CGContextRef context = CGBitmapContextCreate(pixelData,
                                                 1,
                                                 1,
                                                 bitsPerComponent,
                                                 bytesPerRow,
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
    CGContextSetBlendMode(context, kCGBlendModeCopy);
    
    CGContextTranslateCTM(context, -point.x, point.y - self.size.height);
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), self.CGImage);
    CGContextRelease(context);
    
    CGFloat red   = (CGFloat)pixelData[0] / 255.0f;
    CGFloat green = (CGFloat)pixelData[1] / 255.0f;
    CGFloat blue  = (CGFloat)pixelData[2] / 255.0f;
    CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
    
    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

6. 字符串反转

第一种:
- (NSString *)reverseWordsInString:(NSString *)str
{    
    NSMutableString *newString = [[NSMutableString alloc] initWithCapacity:str.length];
    for (NSInteger i = str.length - 1; i >= 0 ; i --)
    {
        unichar ch = [str characterAtIndex:i];       
        [newString appendFormat:@"%c", ch];    
    }    
     return newString;
}

//第二种:
- (NSString*)reverseWordsInString:(NSString*)str
{    
     NSMutableString *reverString = [NSMutableString stringWithCapacity:str.length];    
     [str enumerateSubstringsInRange:NSMakeRange(0, str.length) options:NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences  usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 
          [reverString appendString:substring];                         
      }];    
     return reverString;
}

7. 禁止锁屏

// 方法一
[UIApplication sharedApplication].idleTimerDisabled = YES;

// 方法二
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

8. 模态退出透明界面

UIViewController *vc = [[UIViewController alloc] init];
UINavigationController *na = [[UINavigationController alloc] initWithRootViewController:vc];

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
     na.modalPresentationStyle = UIModalPresentationOverCurrentContext;
}
else
{
     self.modalPresentationStyle=UIModalPresentationCurrentContext;
}

[self presentViewController:na animated:YES completion:nil];

9. Xcode调试不显示内存占用

editSCheme  里面有个选项叫叫做enable zoombie Objects  取消选中

10. 显示隐藏文件

//显示
defaults write com.apple.finder AppleShowAllFiles -bool true
killall Finder

//隐藏
defaults write com.apple.finder AppleShowAllFiles -bool false
killall Finder

11. 字符串按多个符号分割

NSString *str = @"abc,vfr.yyuu";
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@",."];
NSLog(@"%@", [str componentsSeparatedByCharactersInSet:set]);

12. iOS跳转到AppStore下载评分界面

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APPID"]];

13. iOS获取汉字的拼音

+ (NSString *)transform:(NSString *)chinese
{    
    //将NSString装换成NSMutableString 
    NSMutableString *pinyin = [chinese mutableCopy];    
    //将汉字转换为拼音(带音标)    
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformMandarinLatin, NO);    
    NSLog(@"%@", pinyin);    
    //去掉拼音的音标    
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformStripCombiningMarks, NO);    
    NSLog(@"%@", pinyin);    
    //返回最近结果    
    return pinyin;
 }

14. 手动设置状态栏颜色

- (void)setStatusBarBackgroundColor:(UIColor *)color
{
    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];

    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)])
    {
        statusBar.backgroundColor = color;    
    }
}
  1. 判断当前ViewController是push出来的还是present显示的
NSArray *viewcontrollers=self.navigationController.viewControllers;  

if (viewcontrollers.count > 1)
{
    if ([viewcontrollers objectAtIndex:viewcontrollers.count - 1] == self)
    {
        //push方式
       [self.navigationController popViewControllerAnimated:YES];
    }
}
else
{
    //present方式
    [self dismissViewControllerAnimated:YES completion:nil];
}

16. 获取实际使用的LaunchImage图片

- (NSString *)getLaunchImageName
{
    CGSize viewSize = self.window.bounds.size;
    // 竖屏    
    NSString *viewOrientation = @"Portrait";  
    NSString *launchImageName = nil;    
    NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
    for (NSDictionary* dict in imagesDict)
    {
        CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
        if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
        {
            launchImageName = dict[@"UILaunchImageName"];        
        }    
    }    
    return launchImageName;
}

17. iOS在当前屏幕获取第一响应

UIWindow * keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView * firstResponder = [keyWindow performSelector:@selector(firstResponder)];

18. 判断对象是否遵循了某协议

if ([self.selectedController conformsToProtocol:@protocol(RefreshPtotocol)])
{
     [self.selectedController performSelector:@selector(onTriggerRefresh)];
}

19. 判断view是不是指定视图的子视图

BOOL isView = [textView isDescendantOfView:self.view];

20. NSArray快速求总和、最大值、最小值、平均值

NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
NSLog(@"%f\n%f\n%f\n%f",sum,avg,max,min);

21. 修改UITextField中Placeholder的文字颜色

[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];

22. NSDateFormatter的格式

G: 公元时代,例如AD公元
yy: 年的后2位
yyyy: 完整年
MM: 月,显示为1-12
MMM: 月,显示为英文月份简写,如 Jan
MMMM: 月,显示为英文月份全称,如 Janualy
dd: 日,2位数表示,如02
d: 日,1-2位显示,如 2
EEE: 简写星期几,如Sun
EEEE: 全写星期几,如Sunday
aa: 上下午,AM/PM
H: 时,24小时制,0-23
K:时,12小时制,0-11
m: 分,1-2位
mm: 分,2位
s: 秒,1-2位
ss: 秒,2位
S: 毫秒

23. 获取一个类的所有子类

+ (NSArray *)getAllSubclasses {
    Class myClass = [self class];
    NSMutableArray *mySubclasses = [NSMutableArray array];
    unsigned int numOfClasses;
    Class *classes = objc_copyClassList(&numOfClasses;);
    for (unsigned int ci = 0; ci < numOfClasses; ci++) {
        Class superClass = classes[ci];

        do {
            superClass = class_getSuperclass(superClass);
        } while (superClass && superClass != myClass);

        if (superClass) {
            [mySubclasses addObject: classes[ci]];
        }
    }
    free(classes);
    return mySubclasses;
}

24. 检测iOS设备是否设置了代理,需要CFNetwork.framework

NSDictionary *proxySettings = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:@"http://www.baidu.com"]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));
NSLog(@"\n%@",proxies);

NSDictionary *settings = proxies[0];
NSLog(@"%@",[settings objectForKey:(NSString *)kCFProxyHostNameKey]);
NSLog(@"%@",[settings objectForKey:(NSString *)kCFProxyPortNumberKey]);
NSLog(@"%@",[settings objectForKey:(NSString *)kCFProxyTypeKey]);
   
if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]) {
     NSLog(@"没代理");
} else {
     NSLog(@"设置了代理");
}

25. 阿拉伯数字转中文数字

+ (NSString *)translation:(NSString *)arebicStr {  
    NSString *str = arebicStr;
    NSArray *arabicNumArr = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"0"];
    NSArray *chineseNumArr = @[@"一",@"二",@"三",@"四",@"五",@"六",@"七",@"八",@"九",@"零"];
    NSArray *digitArr = @[@"个",@"十",@"百",@"千",@"万",@"十",@"百",@"千",@"亿",@"十",@"百",@"千",@"兆"];
    NSDictionary *numPairDic = [NSDictionary dictionaryWithObjects: chineseNumArr forKeys: arabicNumArr];

    NSMutableArray *sumArr = [NSMutableArray array];
    for (int i = 0; i < str.length; i ++) {
        NSString *subStr = [str substringWithRange:NSMakeRange(i, 1)];
        NSString *a = [dictionary objectForKey:subStr];
        NSString *b = digitArr[str.length -i-1];
        NSString *sum = [a stringByAppendingString:b];
        if ([a isEqualToString: chineseNumArr[9]]) {
            if([b isEqualToString:digitArr[4]] || [b isEqualToString:digitArr[8]]) {
                sum = b;
                if ([[sumArr lastObject] isEqualToString:chineseNumArr[9]]) {
                    [sumArr removeLastObject];
                }
            } else {
                sum = chineseNumArr[9];
            }

            if ([[sumArr lastObject] isEqualToString:sum]) {
                continue;
            }
        }

        [sumArr addObject:sum];
    }

    NSString *sumStr = [sumArr componentsJoinedByString:@""];
    NSString *chineseStr = [sumStr substringToIndex:sumStr.length-1];
    NSLog(@"%@",str);
    NSLog(@"%@",chineseStr);
    return chineseStr;
}

26. Base64编码与NSString/NSData的转换

// 方法1
- (NSString *)transformerOne {
// Create NSData object
NSData *nsdata = [@"iOS Developer Tips encoded in Base64"
  dataUsingEncoding:NSUTF8StringEncoding];
 
// Get NSString from NSData object in Base64
NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0];
 
// Print the Base64 encoded string
NSLog(@"Encoded: %@", base64Encoded);
return base64Encoded;
}

// 方法2
- (NSString *)transformerTwo {
// NSData from the Base64 encoded str
NSData *nsdataFromBase64String = [[NSData alloc]
  initWithBase64EncodedString:base64Encoded options:0];
 
// Decoded NSString from the NSData
NSString *base64Decoded = [[NSString alloc]
  initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];
NSLog(@"Decoded: %@", base64Decoded);
}

27. 取消UICollectionView的隐式动画

UICollectionView在reloadItems的时候,默认会附加一个隐式的fade动画,有时候很讨厌,尤其是当你的cell是复合cell的情况下(比如cell使用到了UIStackView)。
下面几种方法都可以帮你去除这些动画:

//方法一
[UIView performWithoutAnimation:^{
    [collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
}];

//方法二
[UIView animateWithDuration:0 animations:^{
    [collectionView performBatchUpdates:^{
        [collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
    } completion:nil];
}];

//方法三
[UIView setAnimationsEnabled:NO];
[self.trackPanel performBatchUpdates:^{
    [collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
} completion:^(BOOL finished) {
    [UIView setAnimationsEnabled:YES];
}];

28. 让Xcode的控制台支持打印LLDB格式

依次执行下述终端命令:

touch ~/.lldbinit
echo display @import UIKit >> ~/.lldbinit
echo target stop-hook add -o \"target stop-hook disable\" >> ~/.lldbinit

29. cocoaPods不更新本地仓库

// 如果不加后面的参数,默认会升级CocoaPods的spec仓库,加一个参数可以省略这一步,然后速度就会提升不少
pod install --verbose --no-repo-update 
pod update --verbose --no-repo-update

30. 读取UIImage占用内存的大小

UIImage *image = [UIImage imageNamed:@"aa"];
// 单位是Byte,记得转KB或MB
NSUInteger size  = CGImageGetHeight(image.CGImage) * CGImageGetBytesPerRow(image.CGImage);

31. 基于GCD的定时器

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(timer, ^{
    //@"倒计时结束,关闭"
    dispatch_source_cancel(timer); 
    dispatch_async(dispatch_get_main_queue(), ^{

    });
});
dispatch_resume(timer);

32. 在图片上绘制文字(UIImage分类方法)

- (UIImage *)imageWithTitle:(NSString *)title fontSize:(CGFloat)fontSize
{
    //画布大小
    CGSize size=CGSizeMake(self.size.width,self.size.height);
    //创建一个基于位图的上下文
    UIGraphicsBeginImageContextWithOptions(size,NO,0.0);//opaque:NO  scale:0.0
    
    [self drawAtPoint:CGPointMake(0.0,0.0)];
    
    //文字居中显示在画布上
    NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
    paragraphStyle.alignment=NSTextAlignmentCenter;//文字居中
    
    //计算文字所占的size,文字居中显示在画布上
    CGSize sizeText=[title boundingRectWithSize:self.size options:NSStringDrawingUsesLineFragmentOrigin
                                     attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}context:nil].size;
    CGFloat width = self.size.width;
    CGFloat height = self.size.height;
    
    CGRect rect = CGRectMake((width-sizeText.width)/2, (height-sizeText.height)/2, sizeText.width, sizeText.height);
    //绘制文字
    [title drawInRect:rect withAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:fontSize],NSForegroundColorAttributeName:[ UIColor whiteColor],NSParagraphStyleAttributeName:paragraphStyle}];
    
    //返回绘制完成的新图片
    UIImage *newImage= UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

33. 查找一个视图的所有子视图

- (NSMutableArray *)allSubViewsForView:(UIView *)view
{
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
    for (UIView *subView in view.subviews) {
        [array addObject:subView];
        if (subView.subviews.count > 0) {
            [array addObjectsFromArray:[self allSubViewsForView:subView]];
        }
    }
    return array;
}

34. 计算文件/文件夹大小

// 文件大小
- (long long)fileSizeAtPath:(NSString *)path {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if ([fileManager fileExistsAtPath:path]) {
        long long size = [fileManager attributesOfItemAtPath:path error:nil].fileSize;
        return size;
    }
    
    return 0;
}

// 文件夹大小
- (long long)folderSizeAtPath:(NSString *)path {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    long long folderSize = 0;
    
    if ([fileManager fileExistsAtPath:path]) {
        NSArray *childerFiles = [fileManager subpathsAtPath:path];
        for (NSString *fileName in childerFiles) {
            NSString *fileAbsolutePath = [path stringByAppendingPathComponent:fileName];
            if ([fileManager fileExistsAtPath:fileAbsolutePath]) {
                long long size = [fileManager attributesOfItemAtPath:fileAbsolutePath error:nil].fileSize;
                folderSize += size;
            }
        }
    }
    
    return folderSize;
}

35. 设置UIView部分圆角

button或者label的四个角有个别是圆角,可以通过设置图层蒙版(view.layer.mask)实现:

CGRect rect = view.bounds;
CGSize radio = CGSizeMake(30, 30);//圆角尺寸
UIRectCorner corner = UIRectCornerTopLeft|UIRectCornerTopRight;  // 圆角位置
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corner cornerRadii:radio];  // 绘制圆角矩形路径
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];  // 创建shapelayer
maskLayer.frame = view.bounds;
maskLayer.path = path.CGPath;  // 设置路径
view.layer.mask = maskLayer;

36. 取上整 / 下整

ceil()功 能:返回大于或者等于指定表达式的最小整数
floor()功 能:返回小于或者等于指定表达式的最大整数

floor(x),有时候也写做Floor(x),其功能是“下取整”,即取不大于x的最大整数 例如:
x=3.14,floor(x)=3
y=9.99999,floor(y)=9

与floor函数对应的是ceil函数,即上取整函数。ceil函数的作用是求不小于给定实数的最小整数。
ceil(2)=ceil(1.2)=cei(1.5)=2.00

floor函数与ceil函数的返回值均为double型

37. 计算字符串长度

计算字符串长度时,一个汉字占两个长度。

// 方法1
- (int)convertToInt:(NSString*)str {
    int strLength = 0;
    char* p = (char*)[str cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0 ; i<[strtemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding] ;i++) {
        if (*p) {
            p++;
            strLength++;
        } else {
            p++;
        }
    }

    return strLength;
}

// 方法2
- (NSUInteger)unicodeLengthOfString: (NSString *) text {
    NSUInteger asciiLength = 0;
    for (NSUInteger i = 0; i < text.length; i++) {
        unichar uc = [text characterAtIndex: I];
        asciiLength += isascii(uc) ? 1 : 2;
    }

    return asciiLength;
}

38. 用UIView显示图片

UIImage *img = [UIImage imageNamed:@"image"];
self.myView.layer.contents = (__bridge id _Nullable)(img.CGImage);
self.myView.layer.contentsRect = CGRectMake(0, 0, 0.5, 0.5);

39. 防止scrollView手势覆盖侧滑手势

[self.scrollV.panGestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];

40. 去掉导航栏返回按钮的back文字

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];

41. 检查字符串是否含有中文

+ (BOOL)checkIsChinese:(NSString *)str {
    for (int i=0; i<string.length; i++) {
        unichar ch = [str characterAtIndex:i];
        if (0x4E00 <= ch  && ch <= 0x9FA5) {
            return YES;
        }
    }
    return NO;
}

42. 线程调度组dispatch_group

dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_enter(dispatchGroup);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    NSLog(@"第一个请求完成");
    dispatch_group_leave(dispatchGroup);
});
    
dispatch_group_enter(dispatchGroup);
    
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    NSLog(@"第二个请求完成");
    dispatch_group_leave(dispatchGroup);
});
    
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
    NSLog(@"请求完成");
});

43. UITextField每四位加一个空格的代理方法(UITestFieldDelegate)

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // 四位加一个空格
    if ([string isEqualToString:@""]) {
        // 删除字符
        if ((textField.text.length - 2) % 5 == 0) {
            textField.text = [textField.text substringToIndex:textField.text.length - 1];
        }
        return YES;
    } else {
        if (textField.text.length % 5 == 0) {
            textField.text = [NSString stringWithFormat:@"%@ ", textField.text];
        }
    }
    return YES;
}

44. 运行时Runtime获取私有属性和成员变量

需要导入头文件#import <objc/runtime.h>

// 获取私有属性 比如设置UIDatePicker的字体颜色
- (void)setTextColor {
    // 获取所有的属性,去查看有没有对应的属性
    unsigned int count = 0;
    objc_property_t *propertys = class_copyPropertyList([UIDatePicker class], &count);
    for(int i = 0;i < count;i ++) {
        //获得每一个属性
        objc_property_t property = propertys[I];
        //获得属性对应的nsstring
        NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        //输出打印看对应的属性
        NSLog(@"propertyname = %@",propertyName);
        if ([propertyName isEqualToString:@"textColor"]) {
            [datePicker setValue:[UIColor whiteColor] forKey:propertyName];
        }
    }
}
// 获得成员变量 比如修改UIAlertAction的按钮字体颜色
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([UIAlertAction class], &count);
for(int i =0;i < count;i ++) {
    Ivar ivar = ivars[I];
    NSString *ivarName = [NSString stringWithCString:ivar_getName(ivar) encoding:NSUTF8StringEncoding];
    NSLog(@"uialertion.ivarName = %@",ivarName);
    if ([ivarName isEqualToString:@"_titleTextColor"]) {
        [alertOk setValue:[UIColor blueColor] forKey:@"titleTextColor"];
        [alertCancel setValue:[UIColor purpleColor] forKey:@"titleTextColor"];
    }
}

45. 获取手机安装的应用

Class c =NSClassFromString(@"LSApplicationWorkspace");
id s = [(id)c performSelector:NSSelectorFromString(@"defaultWorkspace")];
NSArray *array = [s performSelector:NSSelectorFromString(@"allInstalledApplications")];
for (id item in array)
{
    NSLog(@"%@",[item performSelector:NSSelectorFromString(@"applicationIdentifier")]);
    NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleIdentifier")]);
    NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleVersion")]);
    NSLog(@"%@",[item performSelector:NSSelectorFromString(@"shortVersionString")]);
}

46. App跳转到系统设置

46.1 iOS8之后

如果App没有添加权限,显示的是系统设置界面
如果App有添加权限(例如通知),显示的是App的设置界面。

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
46.2 iOS8之前

在Xcode中,进入TARGETSInfoURL Types,点击按钮,在展开页给App添加URL标识,如图

给App添加URL标识 - 1 给App添加URL标识 - 2
根据上面设置的URL Schemes,跳转应用的设置页(URL标识之后可以指定一个参数,直接跳转到该App某权限相应的设置项)
// iOS8之前
// 先添加一个url type如下图,在代码中调用如下代码,即可跳转到设置页面的对应项
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"FindDemo:root=WIFI"]];
/** 设置项如下:
  About — prefs:root=General&path=About
  Accessibility — prefs:root=General&path=ACCESSIBILITY
  Airplane Mode On — prefs:root=AIRPLANE_MODE
  Auto-Lock — prefs:root=General&path=AUTOLOCK
  Brightness — prefs:root=Brightness
  Bluetooth — prefs:root=General&path=Bluetooth
  Date & Time — prefs:root=General&path=DATE_AND_TIME
  FaceTime — prefs:root=FACETIME
  General — prefs:root=General
  Keyboard — prefs:root=General&path=Keyboard
  iCloud — prefs:root=CASTLE
  iCloud Storage & Backup — prefs:root=CASTLE&path=STORAGE_AND_BACKUP
  International — prefs:root=General&path=INTERNATIONAL
  Location Services — prefs:root=LOCATION_SERVICES
  Music — prefs:root=MUSIC
  Music Equalizer — prefs:root=MUSIC&path=EQ
  Music Volume Limit — prefs:root=MUSIC&path=VolumeLimit
  Network — prefs:root=General&path=Network
  Nike + iPod — prefs:root=NIKE_PLUS_IPOD
  Notes — prefs:root=NOTES
  Notification — prefs:root=NOTIFICATI*****_ID
  Phone — prefs:root=Phone
  Photos — prefs:root=Photos
  Profile — prefs:root=General&path=ManagedConfigurationList
  Reset — prefs:root=General&path=Reset
  Safari — prefs:root=Safari
  Siri — prefs:root=General&path=Assistant
  Sounds — prefs:root=Sounds
  Software Update — prefs:root=General&path=SOFTWARE_UPDATE_LINK
  Store — prefs:root=STORE
  Twitter — prefs:root=TWITTER
  Usage — prefs:root=General&path=USAGE
  VPN — prefs:root=General&path=Network/VPN
  Wallpaper — prefs:root=Wallpaper
  Wi-Fi — prefs:root=WIFI
  */

47. 暂时屏蔽触发事件

// 这里设置的失效时间是2s
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [[UIApplication sharedApplication] endIgnoringInteractionEvents]
});

48. 暂停 / 继续动画

// 暂停动画
- (void)pauseLayer:(CALayer *)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

// 继续动画
- (void)resumeLayer:(CALayer *)layer
{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

49. 填充规则(fillRule)

填充规则

50. 格式化数字

通过NSNumberFormatter,可以设置NSNumber输出的格式。

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSString *string = [formatter stringFromNumber:[NSNumber numberWithInt:123456789]];
NSLog(@"Formatted number string:%@",string);

// 输出结果为:[1223:403] Formatted number string:123,456,789

其中,NSNumberFormatter类有个枚举属性numberStyle,设置不同的枚举值,可以输出不同的数字格式:

typedef NS_ENUM(NSUInteger, NSNumberFormatterStyle) {
    NSNumberFormatterNoStyle = kCFNumberFormatterNoStyle,
    NSNumberFormatterDecimalStyle = kCFNumberFormatterDecimalStyle,
    NSNumberFormatterCurrencyStyle = kCFNumberFormatterCurrencyStyle,
    NSNumberFormatterPercentStyle = kCFNumberFormatterPercentStyle,
    NSNumberFormatterScientificStyle = kCFNumberFormatterScientificStyle,
    NSNumberFormatterSpellOutStyle = kCFNumberFormatterSpellOutStyle
};
// 各个枚举对应输出数字格式效果
// 其中第三项和最后一项的输出会根据系统设置的语言区域的不同而不同。
[1243:403] Formatted number string:123456789
[1243:403] Formatted number string:123,456,789
[1243:403] Formatted number string:¥123,456,789.00
[1243:403] Formatted number string:-539,222,988%
[1243:403] Formatted number string:1.23456789E8
[1243:403] Formatted number string:一亿二千三百四十五万六千七百八十九

51. 如何获取WebView中所有图片的地址?

在网页加载完成时,通过js获取图片和添加点击的识别方式

// UIWebView
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    // 这里是js,主要目的实现对url的获取
    static  NSString * const jsGetImages =
    @"function getImages(){\
    var objs = document.getElementsByTagName(\"img\");\
    var imgScr = '';\
    for(var i=0;i<objs.length;i++){\
    imgScr = imgScr + objs[i].src + '+';\
    };\
    return imgScr;\
    };";
  
    // 注入js方法
    [webView stringByEvaluatingJavaScriptFromString:jsGetImages];
    NSString *urlResult = [webView stringByEvaluatingJavaScriptFromString:@"getImages()"];
    NSArray *urlArray = [NSMutableArray arrayWithArray:[urlResult componentsSeparatedByString:@"+"]];
    // urlResurlt 就是获取到得所有图片的url的拼接;mUrlArray就是所有Url的数组
}
// WKWebView
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    static  NSString * const jsGetImages =
    @"function getImages(){\
    var objs = document.getElementsByTagName(\"img\");\
    var imgScr = '';\
    for(var i=0;i<objs.length;i++){\
    imgScr = imgScr + objs[i].src + '+';\
    };\
    return imgScr;\
    };";
    
    [webView evaluateJavaScript:jsGetImages completionHandler:nil];
    [webView evaluateJavaScript:@"getImages()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        NSLog(@"%@",result);
    }];
}

52. 获取webView的高度

CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];

53. 将navigationBar设置为全透明

// 方法1
// 导航栏纯透明
[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
// 去掉导航栏底部的黑线
self.navigationBar.shadowImage = [UIImage new];
// 方法2
[[self.navigationBar subviews] objectAtIndex:0].alpha = 0;

54. 将tabBar设置为全透明

[self.tabBar setBackgroundImage:[UIImage new]];
self.tabBar.shadowImage = [UIImage new];

55. navigationBar根据滑动距离设置渐变透明度

// 方法1
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // 滑动多少就完全显示
    CGFloat offsetToShow = 200.0;
    
    // 根据滑动距离改变透明度
    CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
    [[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = alpha;
}
// 方法2
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offsetToShow = 200.0;
    CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
    
    [self.navigationController.navigationBar setShadowImage:[UIImage new]];
    [self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:[[UIColor orangeColor]colorWithAlphaComponent:alpha]] forBarMetrics:UIBarMetricsDefault];
}

// 生成一张纯色的图片
- (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return theImage;
}

56. iOS开发中用到的路径

// 模拟器的位置:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs 

// 文档安装位置:
/Applications/Xcode.app/Contents/Developer/Documentation/DocSets

// 插件保存路径:
~/Library/ApplicationSupport/Developer/Shared/Xcode/Plug-ins

// 自定义代码段的保存路径
// PS:如果找不到CodeSnippets文件夹,可以自己新建一个CodeSnippets文件夹。
~/Library/Developer/Xcode/UserData/CodeSnippets/ 

// 描述文件路径
~/Library/MobileDevice/Provisioning Profiles

57. navigationItem的BarButtonItem紧靠屏幕左边/右边

一般情况下,item会和屏幕边缘保持一段距离,如图:


图 1 默认效果

两种解决办法:

UIImage *img = [[UIImage imageNamed:@"icon_cog"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//宽度为负数的固定间距的系统item
UIBarButtonItem *rightNegativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
[rightNegativeSpacer setWidth:-15];

UIBarButtonItem *rightBtnItem1 = [[UIBarButtonItem alloc]initWithImage:img style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonItemClicked:)];
UIBarButtonItem *rightBtnItem2 = [[UIBarButtonItem alloc]initWithImage:img style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonItemClicked:)];
self.navigationItem.rightBarButtonItems = @[rightNegativeSpacer,rightBtnItem1,rightBtnItem2];
图2 自定义效果

58. NSString进行URL编码/解码

NSString *string = @"http://abc.com?aaa=你好&bbb=tttee";

//编码 打印:http://abc.com?aaa=%E4%BD%A0%E5%A5%BD&bbb=tttee
string = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

//解码 打印:http://abc.com?aaa=你好&bbb=tttee
string = [string stringByRemovingPercentEncoding];

59. UIWebView设置User-Agent

// 设置
NSDictionary *dic = @{@"UserAgent":@"your UserAgent"};
[[NSUserDefaults standardUserDefaults] registerDefaults:dic];
// 获取
NSString *agent = [self.WebView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];

60. 获取硬盘总容量、可用容量

NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *attributes = [fileManager attributesOfFileSystemForPath:NSHomeDirectory() error:nil];

NSLog(@"容量%.2fG",[attributes[NSFileSystemSize] doubleValue] / (powf(1024, 3)));
NSLog(@"可用%.2fG",[attributes[NSFileSystemFreeSize] doubleValue] / powf(1024, 3));

61. 获取UIColor的RGBA值

UIColor *color = [UIColor colorWithRed:0.2 green:0.3 blue:0.9 alpha:1.0];
const CGFloat *components = CGColorGetComponents(color.CGColor);
NSLog(@"Red: %.1f", components[0]);
NSLog(@"Green: %.1f", components[1]);
NSLog(@"Blue: %.1f", components[2]);
NSLog(@"Alpha: %.1f", components[3]);

62. 修改UITextField的placeholder字体的颜色、大小

runtime的应用场景之一

[self.textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[self.textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];

63. AFN移除JSON中的NSNull

AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
response.removesKeysWithNullValues = YES;

64. UIWebView里面的图片自适应屏幕

实现webView的代理方法,添加下述代码:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    // JS注入
    NSString *js = @"function imgAutoFit() { \
    var imgs = document.getElementsByTagName('img'); \
    for (var i = 0; i < imgs.length; ++i) { \
    var img = imgs[i]; \
    img.style.maxWidth = %f; \
    } \
    }";
    
    js = [NSString stringWithFormat:js, [UIScreen mainScreen].bounds.size.width - 20];
    
    [webView stringByEvaluatingJavaScriptFromString:js];
    [webView stringByEvaluatingJavaScriptFromString:@"imgAutoFit()"];
}

65. UILabel显示html

NSString *htmlString = @"Some html string";
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];

UILabel *label = [[UILabel alloc] initWithFrame:self.view.bounds];
label.attributedText = attrStr;
[self.view addSubview:label];

66. 模拟器切换语言

依次进入XodeProductSchemeEdit SchemeRunApplication Language&Region,这里选择想要的语言,重启模拟器生效。

按提示操作

67. 汉字转拼音

NSString *chineseText = @"啦啦啦德玛西亚";
if (chineseText.length > 0) {
    NSMutableString *ms = [[NSMutableString alloc] initWithString:chineseText];
        
    // 带声标
    if (CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformMandarinLatin, NO)) {
        NSLog(@"pinyin: %@", ms);
    }
        
    // 不带声标
    if (CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformStripDiacritics, NO)) {
        NSLog(@"pinyin: %@", ms);
    }
        
    NSString *name = [NSString stringWithString:ms];
    NSLog(@"%@",name);
}

68. NS_REQUIRES_SUPER

要求子类重写父类的方法必须先调用super,子类重写这个方法就会自动警告提示要调用这个super方法。

- (void)prepare NS_REQUIRES_SUPER;

69. webView长按保存图片

// 给webView加一个长按手势,在手势的响应方法里添加下述代码
NSString *imgURL = [NSString stringWithFormat:@"dwocument.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];

70. 文字转语音播放

记得导入头文件#import <AVFoundation/AVFoundation.h>

#import <AVFoundation/AVFoundation.h>
@property (nonatomic, strong) AVSpeechSynthesizer *av;

//开始或暂停
- (void)start:(UIButton *)sender
{
    if (sender.selected) {
        if (self.av.isPaused) {
            [self.av continueSpeaking];
            sender.selected = !sender.selected;
        } else {
            AVSpeechUtterance*utterance = [[AVSpeechUtterance alloc]initWithString:@"大渣好 我系渣渣辉"];
            utterance.rate=0.5;// 设置语速,范围0-1,注意0最慢,1最快;AVSpeechUtteranceMinimumSpeechRate最慢,AVSpeechUtteranceMaximumSpeechRate最快
            utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-GB"];//设置发音,这是中文普通话;
            
            self.av = [[AVSpeechSynthesizer alloc] init];
            self.av.delegate = self;
            [self.av speakUtterance:utterance];
            
            sender.selected = !sender.selected;
        }
    } else {
        //[av stopSpeakingAtBoundary:AVSpeechBoundaryWord];//感觉效果一样,对应代理>>>取消
        [self.av pauseSpeakingAtBoundary:AVSpeechBoundaryWord];//暂停
        sender.selected = !sender.selected;
    }
}


@protocol AVSpeechSynthesizerDelegate <NSObject>

@optional
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance;
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance;
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance;
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance;
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance;

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance;

@end

71. Mac在Dock上添加空白的格子

执行下述两条终端命令:

defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="spacer-tile";}'
killall Dock

72. Mac改变截屏图片的类型

Mac截屏图片默认是PNG格式,如果想要改成其他格式,需要运行下述两条终端命令:

// 下面的jpg可以替换成其他格式
defaults write com.apple.screencapture type jpg
killall SystemUIServer

73. 数字转字节单位

NSString *folderSizeStr = [NSByteCountFormatter stringFromByteCount:12334 countStyle:NSByteCountFormatterCountStyleBinary];
NSLog(@"%@",folderSizeStr);

74. 检查是否使用了idfa

执行下述终端命令(注意语句结尾的dot不要忘):

// 注意,最后还有个 .
grep -r advertisingIdentifier .

75. 查看App启动耗时

依次点击XcoeEdit schemeRunAuguments,添加环境变量DYLD_PRINT_STATISTICS,值设为1。
启动app,控制台打印信息如下:

查看App启动耗时

76. 获取图片的类型

- (NSString *)contentTypeForImageData:(NSData *)data
{
    uint8_t c;
    [data getBytes:&c length:1];
    switch (c)
    {
        case 0xFF:
            return @"jpeg";
        case 0x89:
            return @"png";
        case 0x47:
            return @"gif";
        case 0x49:
        case 0x4D:
            return @"tiff";
        case 0x52:
            if ([data length] < 12) {
                return nil;
            }
            NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
            if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
                return @"webp";
            }
            return nil;
    }
    return nil;
}

什么鬼东西

使用UIInterpolatingMotionEffect可以使页面随着设备在空间的移动而发生微移。具体的效果可以查看IOS7系统的解锁界面

UIInterpolatingMotionEffect *interpolationHorizontal = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
    interpolationHorizontal.minimumRelativeValue = @(-20);
    interpolationHorizontal.maximumRelativeValue = @(20);
    
    UIInterpolatingMotionEffect *interpolationVertical = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
    interpolationVertical.minimumRelativeValue = @(-20);
    interpolationVertical.maximumRelativeValue = @(20);
    
    [self.view addMotionEffect:interpolationHorizontal];
    [self.view addMotionEffect:interpolationVertical];
上一篇下一篇

猜你喜欢

热点阅读