iOS學(xué)習(xí)筆記(持續(xù)更新)

1.主線程中更新UI

之前在項(xiàng)目中的一個(gè)回調(diào)方法里面更新了UI導(dǎo)致了一個(gè)NSInternalInconsistencyException錯(cuò)誤,根據(jù)輸錯(cuò)信息大致找到錯(cuò)誤的具體情況 **Only run on the main thread! **,原因是因?yàn)樵谧泳€程中不能對(duì)UI進(jìn)行更新,如果需要更新UI必須切換到主線程中去更新。

那么在子線程中如何更新UI呢,iOS幫我們提供了一個(gè)方法叫 dispatch_async(dispatch_queue_t queue, dispatch_block_t block),可以將方法塊發(fā)送到指定的線程中執(zhí)行,dispatch_get_main_queue() 代表了主線程,這樣更新UI的代碼就可以完美執(zhí)行啦。

dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Update View");
    });

2.NSURLSession簡(jiǎn)單使用

自從iOS 9.0后Apple建議使用NSURLSession代替NSURLConnection。

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"HTTP ERROR:%@",error.localizedDescription);
        }else{
            NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
            NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"HttpResponseCode:%ld", (long)responseCode);
            NSLog(@"HttpResponseBody %@",responseString);
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            //成功處理...
        }
    }] resume];

3.設(shè)置屏幕常亮

//將空閑定時(shí)器禁用,這樣屏幕就能一直保持常亮了
[UIApplication sharedApplication].idleTimerDisabled = YES;
//設(shè)置窗口亮度大小 范圍是0.1 -1.0 一般常亮后盡量把亮度調(diào)低點(diǎn),這樣能省點(diǎn)電
[[UIScreen mainScreen] setBrightness:0.5]; 

4.使用CocoaHTTPServer來(lái)創(chuàng)建本地web服務(wù)器

因?yàn)樽约旱捻?xiàng)目需求要通過網(wǎng)頁(yè)上傳文件到APP里面去,所以通過這個(gè)東西可以把手機(jī)臨時(shí)服務(wù)器,然后通過網(wǎng)頁(yè)上傳文件的形式將文件上傳到APP。

    //主要代碼
    self.httpServer = [[HTTPServer alloc]init];
    [self.httpServer setType:@"_http._tcp."];
    [self.httpServer setPort:8080];
    NSString *webPath = [[NSBundle mainBundle] resourcePath];
    [self.httpServer setConnectionClass:[MyHTTPConnection class]];
    [self.httpServer setDocumentRoot:webPath];
    NSError *error;
    [self.httpServer start:&error];
    //然后在webPath指定的目錄下面放幾個(gè)網(wǎng)頁(yè)就可以訪問啦

5.沙盒路徑獲取

Documents:蘋果建議將程序中建立的或在程序中瀏覽到的文件數(shù)據(jù)保存在該目錄下;
Library:存儲(chǔ)程序的默認(rèn)設(shè)置或其它狀態(tài)信息;
tmp:提供一個(gè)即時(shí)創(chuàng)建臨時(shí)文件的地方。
Library 目錄:這個(gè)目錄下有兩個(gè)子目錄:Caches 和 Preferences

Preferences 目錄包含應(yīng)用程序的偏好設(shè)置文件。您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults類來(lái)取得和設(shè)置應(yīng)用程序的偏好
Caches 目錄用于存放應(yīng)用程序?qū)S玫闹С治募?,保存?yīng)用程序再次啟動(dòng)過程中需要的信息。

注意:

iTunes在與iPhone同步時(shí),備份所有的Documents和Library文件。
iPhone在重啟時(shí),會(huì)丟棄所有的tmp文件。

如果有路徑拼接使用 stringByAppendingPathComponent方法

//獲取家目錄路徑的函數(shù):
NSString *homeDir = NSHomeDirectory(); 
//Documents目錄
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//app包路徑
[[NSBundlemainBundle]bundlePath];  
//獲取tmp目錄
NSString *tempPath = NSTemporaryDirectory();
//獲取Caches目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
NSString *cachesDir = [paths objectAtIndex:0];
//獲取應(yīng)用程序程序包中資源文件路徑的方法
NSString *imagePath = [[NSBundlemainBundle]pathForResource:@"apple"ofType:@"png"];

6.遍歷目錄

NSFileManager *myManage = [NSFileManager defaultManager];
NSString *docPath = [PathHelper getDocumentsPath];
NSDirectoryEnumerator *myDir = [myManage enumeratorAtPath:docPath];
while ((docPath = [myDir nextObject])!=nil) {
    NSLog(@"%@========",docPath);
}

7.頁(yè)面跳轉(zhuǎn)

//從下往上推一個(gè)窗口
[self presentViewController:vc animated:YES completion:nil];
//返回上一個(gè)界面
[ self dismissViewControllerAnimated: YES completion: nil ];
//navigationController彈出窗口向左滑動(dòng)彈出
[self.navigationController pushViewController:readView animated:YES];
//返回上一頁(yè)
[self.navigationController popViewControllerAnimated:YES];
//返回到根視圖
[self.navigationController popToRootViewControllerAnimated: YES ]; 

8.隱藏tabbar

hidesBottomBarWhenPushed 屬性就可以了,在要隱藏tabbar之前的頁(yè)面添加

- (void)viewDidAppear:(BOOL)animated{
    self.hidesBottomBarWhenPushed = YES;
}
- (void)viewWillDisappear:(BOOL)animated{
    self.hidesBottomBarWhenPushed = NO;
}

//新辦法 直接設(shè)置在下一個(gè)界面跳轉(zhuǎn)的時(shí)候設(shè)置下個(gè)界面
[vc setHidesBottomBarWhenPushed:YES];

9.UITableViewCell取消選中

didSelectRowAtIndexPath代理方法中添加

[tableView deselectRowAtIndexPath:indexPath animated:YES];

10.UITabelViewCell的寬度

Cell的寬度默認(rèn)是320,所以在做布局的時(shí)候在layoutSubViews方法中去重新布局Cell的寬度就正常了,這個(gè)layoutSubViews在Frame被修改的時(shí)候回調(diào)用一次,所以只有當(dāng)frame被設(shè)置正確的時(shí)候在去布局就OK啦

- (void)layoutSubviews{
    [super layoutSubviews];
    __weak typeof (self)weakSelf = self;
    [self.explanationLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(weakSelf.contentView).offset(30);
        make.left.equalTo(weakSelf.contentView).offset(20);
        make.size.mas_equalTo(CGSizeMake(CGRectGetWidth(weakSelf.contentView.frame) - 25, 20));
    }];
}

11.UIScrollView組件設(shè)置頁(yè)數(shù)

當(dāng)UIScrollView組件被設(shè)置成翻頁(yè)模式后要設(shè)置具體翻到第幾頁(yè)可以通過setContentOffset方法去設(shè)置,手動(dòng)計(jì)算偏移的坐標(biāo)

[self.scrollView setContentOffset:CGPointMake((winW* currentPage), 0)];

12.獲取當(dāng)前時(shí)間戳

[[NSDate dateWithTimeIntervalSinceNow:0]timeIntervalSince1970] * 1000;

13.修改系統(tǒng)狀態(tài)顏色


//UIBarStyleDefault or  UIBarStyleBlack 兩種樣式
[self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];

14.字符串分割

//不需要間隔分割字符串
NSMutableArray *arr = [[NSMutableArray alloc]init];
for (int index = 0; index < str.length; index++) {
    [arr addObject:[str substringWithRange:NSMakeRange(index, 1)]];
}
//根據(jù)間隔分割字符串
NSArray *arr = [@"1.2.3.4.5.6.7" componentsSeparatedByString:@"."];

15.大小寫轉(zhuǎn)換

//轉(zhuǎn)小寫
NSString *str = [@"ABCD" lowercaseString]; // abcd
//首字母大寫
NSString *str = [@"abcd" capitalizedString]; // Abcd
//轉(zhuǎn)小寫
NSString *str1 = [@"abcd" uppercaseString];// ABCD

16.UITableView滾動(dòng)到最后一行

if (self.chatTableView.contentSize.height > self.chatTableView.frame.size.height)
{
    CGPoint offset = CGPointMake(0, self.chatTableView.contentSize.height - self.chatTableView.frame.size.height);
    [self.chatTableView setContentOffset:offset animated:YES];
}

17.時(shí)間處理

//實(shí)例化一個(gè)NSDateFormatter對(duì)象
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//設(shè)定時(shí)間格式,這里可以設(shè)置成自己需要的格式
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
//用[NSDate date]可以獲取系統(tǒng)當(dāng)前時(shí)間
NSString *currentDateStr = [dateFormatter stringFromDate:[NSDate date]];

18.跳轉(zhuǎn)到系統(tǒng)WiFi設(shè)置界面

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=WIFI"]];

19.JSON去掉換行

-(NSString*)ObjectTojsonString:(id)object{
    NSString *jsonString = [[NSString alloc]init];
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:&error];
    if (! jsonData) {
        NSLog(@"error: %@", error);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    NSRange range = {0,jsonString.length};
    [mutStr replaceOccurrencesOfString:@" "withString:@""options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    [mutStr replaceOccurrencesOfString:@"\n"withString:@""options:NSLiteralSearch range:range2];
    return mutStr;
}

20.電話號(hào)碼驗(yàn)證

//驗(yàn)證電話號(hào)碼
NSString *regex = @"^[1][0-9]{10}$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL isValid = [predicate evaluateWithObject:phone];

21. Nonnull區(qū)域設(shè)置

如果需要每個(gè)屬性或每個(gè)方法都去指定nonnull和nullable,是一件非常繁瑣的事。
蘋果為了減輕我們的工作量,專門提供了兩個(gè)宏:
NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。
在這兩個(gè)宏之間的代碼,所有簡(jiǎn)單指針對(duì)象都被假定為nonnull,因此我們只需要去指定那些nullable的指針。
如下代碼所示:
NS_ASSUME_NONNULL_BEGIN
@interface TestNullabilityClass () 
 
@property (nonatomic, copy) NSArray * items; 
- (id)itemWithName:(nullable NSString *)name; 
 
@end 
NS_ASSUME_NONNULL_END

22.FOUNDATION_EXPORT宏

.h文件
FOUNDATION_EXPORT  NSString *const kMyConstantString;

.m文件是這樣定義的
NSString *const kMyConstantString = @"hello world";

另一種就是常用的#define 方法定義常量了
#define kMyConstantString @"Hello"

那么他們有什么區(qū)別呢?
使用FOUNDATION_EXPORT方法在檢測(cè)字符串的值是否相等的時(shí)候效率更快.
可以直接使用(myString == MyFirstConstant)來(lái)比較, 而define則使用的是([myString isEqualToString:MyFirstContant])
哪個(gè)效率更高,顯而易見了

第一種是直接比較指針地址
第二種則是一一比較字符串的每一個(gè)字符是否相等.


2.3 AssertMacros.h文件

當(dāng)條件返回false時(shí),執(zhí)行標(biāo)記以后的代碼

    NSString *msg = nil;
//如果msg等于nil的時(shí)候直接跳轉(zhuǎn)到_out,test不會(huì)輸出,goto跳轉(zhuǎn)
    __Require_Quiet(msg != nil, _out);
    NSLog(@"test");
_out:
    NSLog(@"out");

//__Require_Quiet 到_out之間的代碼不會(huì)執(zhí)行

2.4 獲取本地文件屬性

獲取本地文件屬性
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:error] 

2.5 根據(jù)文件后綴獲取文件類型(同一類型標(biāo)識(shí)符)

#import <MobileCoreServices/MobileCoreServices.h>
static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
    NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
    NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
    if (!contentType) {
        return @"application/octet-stream";
    } else {
        return contentType;
    }
}

2.6 簡(jiǎn)單動(dòng)態(tài)圖片

UIImage *image0 = [UIImage imageNamed:@"SenderVoiceNodePlaying001"];
UIImage *image1 = [UIImage imageNamed:@"SenderVoiceNodePlaying002"];
UIImage *image2 = [UIImage imageNamed:@"SenderVoiceNodePlaying003"];
self.imageView.image = [UIImage animatedImageWithImages:@[image0,image1,image2] duration:1.5];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容