-1.改變一個(gè)label上不同的顏色
NSRange range = [self.vip_label.text rangeOfString:@"/"];
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:self.vip_label.text];
[attString addAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithHexString:@"#03a2fd"]} range:NSMakeRange(0, range.location)];
1.獲取WebView 的高度
- (void)webViewDidFinishLoad:(UIWebView *)webView? {
CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
CGRect frame = webView.frame;
webView.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, height);
}
2.View設(shè)置圖片.有兩種方法可以實(shí)現(xiàn)該功能;
第一種方法是把圖片裝換成背景顏色,然后在加給圖片的背景顏色就好了
UIColor *bgColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"bgImg.png"];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[myView setBackGroundColor:bgColor];
第二種方法如下
UIImage *image = [UIImage imageNamed:@"yourPicName@2x.png"];
yourView.layer.contents = (__bridge id)image.CGImage;
// 設(shè)置顯示的圖片范圍
yourView.layer.contentsCenter = CGRectMake(0.25,0.25,0.5,0.5);//四個(gè)值在0-1之間,對(duì)應(yīng)的為x,y,width,height。
3.搜索調(diào)cancel修改標(biāo)題
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchController.searchBar.showsCancelButton = YES;
UIButton *canceLBtn = [searchController.searchBar valueForKey:@"cancelButton"];
[canceLBtn setTitle:@"取消" forState:UIControlStateNormal];
[canceLBtn setTitleColor:[UIColor colorWithRed:14.0/255.0 green:180.0/255.0 blue:0.0/255.0 alpha:1.00] forState:UIControlStateNormal];
searchBar.showsCancelButton = YES;
return YES;
}
4.滑動(dòng)時(shí)隱藏navgationBar
navigationController.hidesBarsOnSwipe = Yes;
5.禁止運(yùn)行時(shí),自動(dòng)鎖屏的問(wèn)題
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
6.修改占位符顏色和大小
textField.placeholder = @"請(qǐng)輸入用戶名";
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
7.禁止復(fù)制黏貼
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if ([UIMenuController sharedMenuController]) {
[UIMenuController sharedMenuController].menuVisible = NO;
}
return NO;
}
8.簡(jiǎn)易實(shí)用實(shí)現(xiàn)導(dǎo)航欄透明方法
//? ? 導(dǎo)航欄變?yōu)橥该?br>
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:0];
//? ? 讓黑線消失的方法
self.navigationController.navigationBar.shadowImage=[UIImage new];
9.簡(jiǎn)單實(shí)現(xiàn)忽略靜音開(kāi)關(guān)
播放視頻時(shí),實(shí)際使用中,我們是否開(kāi)啟了靜音開(kāi)關(guān),都會(huì)有外放的聲音,兩行代碼簡(jiǎn)單實(shí)現(xiàn)。
viewdidload中加入下面代碼就能簡(jiǎn)單解決
//忽略靜音開(kāi)關(guān)
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
9.iOS 的沙盒目錄結(jié)構(gòu)是怎樣的? App Bundle 里面都有什么?
1.沙盒結(jié)構(gòu)
Application:存放程序源文件,上架前經(jīng)過(guò)數(shù)字簽名,上架后不可修改
Documents:常用目錄,iCloud備份目錄,存放數(shù)據(jù),這里不能存緩存文件,否則上架不被通過(guò)
Library
Caches:存放體積大又不需要備份的數(shù)據(jù),SDWebImage緩存路徑就是這個(gè)
Preference:設(shè)置目錄,iCloud會(huì)備份設(shè)置信息
tmp:存放臨時(shí)文件,不會(huì)被備份,而且這個(gè)文件下的數(shù)據(jù)有可能隨時(shí)被清除的可能
10.iOS 7的多任務(wù)添加了哪兩個(gè)新的 API? 各自的使用場(chǎng)景是什么?
1.后臺(tái)獲?。˙ackground Fetch):后臺(tái)獲取使用場(chǎng)景是用戶打開(kāi)應(yīng)用之前就使app有機(jī)會(huì)執(zhí)行代碼來(lái)獲取數(shù)據(jù),刷新UI。這樣在用戶打開(kāi)應(yīng)用的時(shí)候,最新的內(nèi)容將已然呈現(xiàn)在用戶眼前,而省去了所有的加載過(guò)程。
2.推送喚醒(Remote Notifications):使用場(chǎng)景是使設(shè)備在接收到遠(yuǎn)端推送后讓系統(tǒng)喚醒設(shè)備和我們的后臺(tái)應(yīng)用,并先執(zhí)行一段代碼來(lái)準(zhǔn)備數(shù)據(jù)和UI,然后再提示用戶有推送。這時(shí)用戶如果解鎖設(shè)備進(jìn)入應(yīng)用后將不會(huì)再有任何加載過(guò)程,新的內(nèi)容將直接得到呈現(xiàn)。
11.Push Notification 是如何工作的?
推送通知分為兩種,一個(gè)是本地推送,一個(gè)是遠(yuǎn)程推送
本地推送:不需要聯(lián)網(wǎng)也可以推送,是開(kāi)發(fā)人員在APP內(nèi)設(shè)定特定的時(shí)間來(lái)提醒用戶干什么
遠(yuǎn)程推送:需要聯(lián)網(wǎng),用戶的設(shè)備會(huì)于蘋果APNS服務(wù)器形成一個(gè)長(zhǎng)連接,用戶設(shè)備會(huì)發(fā)送uuid和Bundle idenidentifier給蘋果服務(wù)器,蘋果服務(wù)器會(huì)加密生成一個(gè)deviceToken給用戶設(shè)備,然后設(shè)備會(huì)將deviceToken發(fā)送給APP的服務(wù)器,服務(wù)器會(huì)將deviceToken存進(jìn)他們的數(shù)據(jù)庫(kù),這時(shí)候如果有人發(fā)送消息給我,服務(wù)器端就會(huì)去查詢我的deviceToken,然后將deviceToken和要發(fā)送的信息發(fā)送給蘋果服務(wù)器,蘋果服務(wù)器通過(guò)deviceToken找到我的設(shè)備并將消息推送到我的設(shè)備上,這里還有個(gè)情況是如果APP在線,那么APP服務(wù)器會(huì)于APP產(chǎn)生一個(gè)長(zhǎng)連接,這時(shí)候APPF服務(wù)器會(huì)直接通過(guò)deviceToken將消息推送到設(shè)備上
12.為什么scrollview滾動(dòng)的時(shí)候會(huì)導(dǎo)致NSTimer失靈
定時(shí)器里面有個(gè)runoop mode,一般T定時(shí)器是運(yùn)行在defaultmode上但是如果滑動(dòng)了這個(gè)頁(yè)面,主線程runloop會(huì)轉(zhuǎn)到UITrackingRunLoopMode中,這時(shí)候就不能處理定時(shí)器了,造成定時(shí)器失效,原因就是runroop mode選錯(cuò)了,解決辦法有2個(gè),一個(gè)是更改mode為NSRunLoopCommonModes(無(wú)論runloop運(yùn)行在哪個(gè)mode,都能運(yùn)行),還有種辦法是切換到主線程來(lái)更新UI界面的刷新
13.你會(huì)如何存儲(chǔ)用戶的一些敏感信息,如登錄的 token
使用keychain來(lái)存儲(chǔ),也就是鑰匙串,使用keychain需要導(dǎo)入Security框架
自定義一個(gè)keychain的類
#import@implementationYCKKeyChain+ (NSMutableDictionary*)getKeychainQuery:(NSString*)service {return[NSMutableDictionarydictionaryWithObjectsAndKeys:? ? ? ? ? ? (__bridge_transferid)kSecClassGenericPassword,(__bridge_transferid)kSecClass,? ? ? ? ? ? service, (__bridge_transferid)kSecAttrService,? ? ? ? ? ? service, (__bridge_transferid)kSecAttrAccount,? ? ? ? ? ? (__bridge_transferid)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transferid)kSecAttrAccessible,nil];}+ (void)save:(NSString*)service data:(id)data {// 獲得搜索字典NSMutableDictionary*keychainQuery = [selfgetKeychainQuery:service];// 添加新的刪除舊的SecItemDelete((__bridge_retainedCFDictionaryRef)keychainQuery);// 添加新的對(duì)象到字符串[keychainQuery setObject:[NSKeyedArchiverarchivedDataWithRootObject:data] forKey:(__bridge_transferid)kSecValueData];// 查詢鑰匙串SecItemAdd((__bridge_retainedCFDictionaryRef)keychainQuery,NULL);}+ (id)load:(NSString*)service {idret =nil;NSMutableDictionary*keychainQuery = [selfgetKeychainQuery:service];// 配置搜索設(shè)置[keychainQuery setObject:(id)kCFBooleanTrueforKey:(__bridge_transferid)kSecReturnData];? ? [keychainQuery setObject:(__bridge_transferid)kSecMatchLimitOne forKey:(__bridge_transferid)kSecMatchLimit];CFDataRefkeyData =NULL;if(SecItemCopyMatching((__bridge_retainedCFDictionaryRef)keychainQuery, (CFTypeRef*)&keyData) == noErr) {@try{? ? ? ? ? ? ret = [NSKeyedUnarchiverunarchiveObjectWithData:(__bridge_transferNSData*)keyData];? ? ? ? }@catch(NSException*e) {NSLog(@"Unarchive of %@ failed: %@", service, e);? ? ? ? }@finally{? ? ? ? }? ? }returnret;}+ (void)delete:(NSString*)service {NSMutableDictionary*keychainQuery = [selfgetKeychainQuery:service];? ? SecItemDelete((__bridge_retainedCFDictionaryRef)keychainQuery);}
在別的類實(shí)現(xiàn)存儲(chǔ),加載,刪除敏感信息方法
// 用來(lái)標(biāo)識(shí)這個(gè)鑰匙串staticNSString*constKEY_IN_KEYCHAIN =@"com.yck.app.allinfo";// 用來(lái)標(biāo)識(shí)密碼staticNSString*constKEY_PASSWORD =@"com.yck.app.password";+ (void)savePassWord:(NSString*)password{NSMutableDictionary*passwordDict = [NSMutableDictionarydictionary];? ? [passwordDict setObject:password forKey:KEY_PASSWORD];? ? [YCKKeyChain save:KEY_IN_KEYCHAIN data:passwordDict];}+ (id)readPassWord{NSMutableDictionary*passwordDict = (NSMutableDictionary*)[YCKKeyChain load:KEY_IN_KEYCHAIN];return[passwordDict objectForKey:KEY_PASSWORD];}+ (void)deletePassWord{? ? [YCKKeyChain delete:KEY_IN_KEYCHAIN];}
14.關(guān)于block引用的問(wèn)題
1.如果要在block中直接使用外部強(qiáng)指針會(huì)發(fā)生錯(cuò)誤,使用以下代碼在block外部實(shí)現(xiàn)可以解決
__weaktypeof(self) weakSelf =self;
2.但是如果在block內(nèi)部使用延時(shí)操作還使用弱指針的話會(huì)取不到該弱指針,需要在block內(nèi)部再將弱指針強(qiáng)引用一下
__strongtypeof(self) strongSelf = weakSelf;
15.使用 NSUserDefaults 時(shí),如何處理布爾的默認(rèn)值?(比如返回 NO,不知道是真的 NO 還是沒(méi)有設(shè)置過(guò))
if([[NSUserDefaults standardUserDefaults]objectForKey:ID] == nil){NSLog(@"沒(méi)有設(shè)置");? ? }
16.開(kāi)發(fā)常用的工具有哪些?
通過(guò)這個(gè)問(wèn)題面試官也可以大概知道你是什么水平的,如果你只能講什么xcode,cocoapods或者xcode自帶的一些工具的話面試官也許就會(huì)把你定位于初級(jí)
參考答案:
1.友盟統(tǒng)計(jì)
2.青花瓷:這個(gè)軟件還是蠻不錯(cuò)的,可以用來(lái)過(guò)濾網(wǎng)絡(luò)請(qǐng)求,模擬低速網(wǎng)路,還可以修改網(wǎng)絡(luò)請(qǐng)求內(nèi)容這些
3.Reveal:調(diào)試頁(yè)面不錯(cuò),還有用來(lái)學(xué)習(xí)別人的demo時(shí)候可以拿來(lái)看UI層次結(jié)構(gòu),還可以用來(lái)標(biāo)記可以設(shè)為透明的控件,用來(lái)優(yōu)化性能
17.單例的缺點(diǎn)也就是會(huì)一直占著這塊內(nèi)存,不會(huì)被釋放
18.問(wèn)題[◇◇◇]:談?wù)凬SNotification 和 KVO 的使用場(chǎng)景?
兩者都是觀察者模式,不同的是,KVO是被觀察者直接發(fā)送消息給觀察者,是對(duì)象間的交互,而通知?jiǎng)t是觀察者和被觀察者通過(guò)通知中心對(duì)象之間進(jìn)行交互,即消息由被觀察者發(fā)送到通知中心對(duì)象,再由中心對(duì)象發(fā)給觀察者,兩者之間并不進(jìn)行直接的交互
19.
問(wèn)題[※※※※]:如何用GCD同步若干個(gè)異步調(diào)用?(如根據(jù)若干個(gè)url異步加載多張圖片,然后在都下載完成后合成一張整圖)
使用Dispatch Group追加block到Global Group Queue,這些block如果全部執(zhí)行完畢,就會(huì)執(zhí)行Main Dispatch Queue中的結(jié)束處理的block
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*加載圖片1 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片2 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片3 */ });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并圖片
});
20.問(wèn)題[○○○○]:UITableViewCell上有個(gè)UILabel,顯示NSTimer實(shí)現(xiàn)的秒表時(shí)間,手指滾動(dòng)cell過(guò)程中,label是否刷新,為什么?
這是否刷新取決于timer加入到Run Loop中的Mode是什么。Mode主要是用來(lái)指定事件在運(yùn)行循環(huán)中的優(yōu)先級(jí)的,分為:
NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默認(rèn),空閑狀態(tài)
UITrackingRunLoopMode:ScrollView滑動(dòng)時(shí)會(huì)切換到該Mode
UIInitializationRunLoopMode:run loop啟動(dòng)時(shí),會(huì)切換到該Mode
NSRunLoopCommonModes(kCFRunLoopCommonModes):
蘋果公開(kāi)提供的Mode有兩個(gè):
NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
NSRunLoopCommonModes(kCFRunLoopCommonModes)
在編程中:如果我們把一個(gè)NSTimer對(duì)象以NSDefaultRunLoopMode添加到主運(yùn)行循環(huán)中的時(shí)候, ScrollView滾動(dòng)過(guò)程中會(huì)因?yàn)镸ode的切換,而導(dǎo)致NSTimer將不再被調(diào)度。當(dāng)我們滾動(dòng)的時(shí)候,也希望不調(diào)度,那就應(yīng)該使用默認(rèn)模式。但是,如果希望在滾動(dòng)時(shí),定時(shí)器也要回調(diào),那就應(yīng)該使用NSRunLoopCommonModes
21.去掉絲滑效果
//- (void)viewDidAppear:(BOOL)animated{
//? ? [super viewDidAppear:animated];
//? ? if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
//? ? ? ? self.navigationController.interactivePopGestureRecognizer.enabled = NO;
//? ? }
//}
//- (void)viewWillDisappear:(BOOL)animated{
//? ? [super viewWillDisappear:animated];
//? ? if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
//? ? ? ? self.navigationController.interactivePopGestureRecognizer.enabled = NO;
//? ? }
//}
22.撥打電話
UIAlertAction *sure1 = [UIAlertAction actionWithTitle:@"撥打" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://400-832-5566"]];
}];
23.一行文字的顏色不同
self.vip_label.text = [NSString stringWithFormat:@"%@/30000",[dic objectForKey:@"growth"]];
NSRange range = [self.vip_label.text rangeOfString:@"/"];
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:self.vip_label.text];
[attString addAttributes:@{NSForegroundColorAttributeName:[UIColor blueColor]} range:NSMakeRange(0, range.location)];
self.vip_label.attributedText = attString;
24.提示框
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"電話號(hào)碼" message:@"400-832-5566"preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *sure = [UIAlertAction actionWithTitle:@"關(guān)閉" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction *sure1 = [UIAlertAction actionWithTitle:@"撥打" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://400-832-5566"]];
}];
[alert addAction:sure];
[alert addAction:sure1];
[self presentViewController:alert animated:YES completion:nil];