一. 關(guān)于 info.plist 的國(guó)際化
info.plist 里面通常會(huì)添加【功能權(quán)限使用】相關(guān)的說(shuō)明,因此 info.plist 也需要國(guó)際化。如何操作呢?
- 新建一個(gè) .strings文件,命名為 InfoPlist.strings(文件名必須是這個(gè)!文件名必須是這個(gè)!文件名必須是這個(gè)!);
- 之后選中新建的 InfoPlist.strings 文件,點(diǎn)擊右側(cè) Inspector 面板中的 Localize... ;
- 然后添加要支持的語(yǔ)言;
- 分別添加功能權(quán)限的 key 對(duì)應(yīng)的文字說(shuō)明 value,如下
NSCameraUsageDescription = "Take passport/ID card photos to upload";
NSPhotoLibraryUsageDescription = "Select passport/ID picture from photo album";
你也可以給 key 加上雙引號(hào)(親測(cè)),像下面這樣
"NSCameraUsageDescription" = "Take passport/ID card photos to upload";
"NSPhotoLibraryUsageDescription" = "Select passport/ID picture from photo album";
功能權(quán)限對(duì)應(yīng)的 key 可以通過(guò)以下方式獲得,如圖

實(shí)踐過(guò)程中遇到的問(wèn)題
- 我們工程有兩個(gè) target,所以建了兩個(gè) plist 文件。關(guān)于這兩個(gè) plist 文件,一開(kāi)始我以為需要分別進(jìn)行國(guó)際化,所以建了兩個(gè)不同的 .strings 文件:InfoPlist.strings 和 AbroadInfoPlist.strings。調(diào)試我一直使用的是 AbroadInfoPlist.strings 對(duì)應(yīng)的 target,導(dǎo)致怎么調(diào)試、更改都不行。網(wǎng)上資料難道都錯(cuò)了?究竟哪里不對(duì)了? 心里是萬(wàn)x駝奔騰!后來(lái)才發(fā)現(xiàn)名稱必須得是 InfoPlist.strings。不過(guò)一下午的時(shí)間差不多都過(guò)去了!F...ck !
- 選中 info.plist 時(shí)右側(cè)面板也有 Localize... 的選項(xiàng),我也懷疑是不是通過(guò)這里進(jìn)行 info.plist 的初始化。后面發(fā)現(xiàn)不行,info.plist 會(huì)分別生成對(duì)應(yīng)語(yǔ)言的版本放到不同的 .lproj 文件(en.lproj 和 zh-Hans.lproj)中去。而 info.plist 需要在 build settings -> packaging -> info.plist File 中進(jìn)行路徑設(shè)置的。而且只能設(shè)置一個(gè)路徑。所以這條路走不通,具有迷惑性,也浪費(fèi)了我不少時(shí)間。
關(guān)于 info.plist 的國(guó)際化你也可以參考 http://m.itdecent.cn/p/eb968d10e656
二. AFNetworking 調(diào)試時(shí)報(bào)錯(cuò):Invalid parameter not satisfying: URLString
具體報(bào)錯(cuò)如下
Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Invalid parameter not satisfying: URLString'
起因
在做一個(gè)搜索界面,上方有一個(gè)搜索欄。用戶輸入之后的值會(huì)拼接到 path 的后面,如下
let path = "/api/search/\(inputText)"
后來(lái)發(fā)現(xiàn)是輸入的有空格,導(dǎo)致的這個(gè)問(wèn)題。解決方法,將輸入框中輸入的 inputText 做如下處理
let tmpKey = inputText.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
然后再拼接到 path 的后面去請(qǐng)求,就不會(huì)報(bào)錯(cuò)了!
這里有一個(gè)同樣的問(wèn)題:http://m.itdecent.cn/p/e0da891a05da
三. 禁用 UITextView 的復(fù)制,剪切,選擇,全選等功能
// 繼承UITextView重寫(xiě)這個(gè)方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// 返回NO為禁用,YES為開(kāi)啟
// 粘貼
if (action == @selector(paste:)) { return NO; }
// 剪切
if (action == @selector(cut:)) { return NO; }
// 復(fù)制
if (action == @selector(copy:)) { return NO; }
// 選擇
if (action == @selector(select:)) { return NO; }
// 選中全部
if (action == @selector(selectAll:)) { return NO; }
// 刪除
if (action == @selector(delete:)) { return NO; }
// 分享
if (action == @selector(share)) { return NO; }
return [super canPerformAction:action withSender:sender];
}
這里有一個(gè)討論:https://www.itranslater.com/qa/details/2325748042663724032
四. NSUserDefaults 支持存儲(chǔ)的數(shù)據(jù)類型
NSUserDefaults適合存儲(chǔ)輕量級(jí)的本地?cái)?shù)據(jù)。支持存儲(chǔ)的數(shù)據(jù)類型有:NSNumber(NSInteger、float、double)、NSString、NSDate、NSArray、NSDictionary、BOOL。
五. Xcode 真機(jī)調(diào)試報(bào)錯(cuò) Please reconnect the device
反復(fù)的重新連接手機(jī),但就是運(yùn)行報(bào)錯(cuò)。
具體報(bào)錯(cuò)如下:
Failed to prepare device for development.
If you are certain that Xcode supports development on this device, try disconnecting and reconnecting the device.
解決方案:
重啟手機(jī)?。?!
重啟大法就是好,能解決很多疑難雜癥!
六. App Store connect 中填寫(xiě)聯(lián)系信息報(bào) "此欄無(wú)效" 的錯(cuò)誤

解決方法:
大 11 位電話號(hào)碼前加地區(qū)號(hào),像這樣:+86-136xxxxxxxx
七. 如何取消 UIScrollView 的彈簧效果
scrollView.bounces = NO;
八、swift:Cannot convert value of type 'ArraySlice<UInt8>' to specified type '[UInt8]'

解決方案:Array(arr[2…<arr.count])

九、CUICatalog: Invalid asset name supplied
調(diào)試面板打印了許多如上所示的信息。
原因:使用[UIImage imageNamed:] 時(shí),圖片不存在或者傳入的圖片名為nil.
十、準(zhǔn)確計(jì)算 UILabel 文本內(nèi)容的高度
開(kāi)發(fā)過(guò)程中,在使用 boundingRectWithSize:方法計(jì)算字符串的行高時(shí),發(fā)現(xiàn)由于文本內(nèi)容是英文,計(jì)算出來(lái)的行高比實(shí)際顯示的要?。ㄖ形目赡軟](méi)有這個(gè)問(wèn)題)。經(jīng)過(guò)后來(lái)揣摩觀察發(fā)現(xiàn)是由于英文單詞的換行是按照 NSLineBreakByWordWrapping方式進(jìn)行導(dǎo)致的,按照 NSLineBreakByCharWrapping 就沒(méi)有問(wèn)題。
如下圖所示,藍(lán)框右則的文本由于按單詞換行導(dǎo)致沒(méi)有頂格顯示

解決方案:借助 NSMutableParagraphStyle 進(jìn)行計(jì)算
示例代碼如下
let str = attributedText.string
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byWordWrapping
// 加個(gè)換行符防止 str 不是分段落的文本內(nèi)容,如果 str 不是分段落的文本內(nèi)容下面的計(jì)算方式就無(wú)效
let tmpStr = "\(str)\n"
let tmpRect = tmpStr.boundingRect(with: CGSize(width: screenW - 32.0, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: [.font: font, .paragraphStyle: paragraphStyle], context: nil)
let height: CGFloat = ceil(tmpRect.height) + 1
問(wèn)題完美解決?。。?/strong> 學(xué)會(huì)了嗎!