「 iOS 知识小集 」2018 · 第 23 期
上周公眾號發布的以下文章:
- 美團客戶端響應式框架 EasyReact 開源
- 巧妙利用 KVO 實現精準的 VC 耗時檢測
- 微信小程序適配 iPhone X 總結
- Shortcuts, Siri 功能增強器
本期知識小集的主要內容包括:
- 用 NSDecimalNumber 處理 iOS 中的貨幣金額
- 如何更容易看懂宏
- Storyboard/Xib 顏色空間的坑
- VC 多層 push 后回到指定頁面的幾種方法
- 添加沙箱技術測試員報錯的問題
- UIViewController 設置導航欄和標簽欄不同 title 的問題
- 蘋果官方類庫中 NSDateFormatter 的小 bug
用 NSDecimalNumber 處理 iOS 中的貨幣金額
作者: halohily
在iOS開發中,經常遇到貨幣金額的表示與計算,你可能會使用 double 或 float 這樣的浮點數,也可能使用 NSString 。無論用哪個,都需要再編寫繁瑣的精度控制、小數位數控制等代碼。其實,蘋果為我們提供了一個標準類 NSDecimalNumber 來處理這樣的需求。
NSDecimalNumber 是 NSNumber 的子類,它提供了完善的初始化方法。對于令人頭疼的金額計算,它還提供了貼心的加、減、乘、除運算方法。在進行這些運算的時候,你還可以通過 NSDecimalNumberHandler 對象來對運算的處理策略進行設置,比如舍入模式的選擇,數據溢出、除零等異常情況的處理等。
下次遇到貨幣金額的需求,不妨了解一下 NSDecimalNumber。
參考資料:
- iOS 數字精準計算之NSDecimalNumber https://www.jianshu.com/p/ea4da259a062
- NSDecimalNumber數字精確 https://www.jianshu.com/p/25d24a184016
如何更容易看懂宏
作者: Lefe_x
相信你和我一樣,也遇到過特別難理解的宏定義,比如宏與宏之間嵌套、帶參數的宏。我們看個例子(這個宏并不是特別難,但也很繞):
+ (instancetype)_name:(_type)obj \ { \JPBoxing *boxing = [[JPBoxing alloc] init]; \boxing._prop = obj; \return boxing; \ }JPBOXING_GEN(boxObj, obj, id) 復制代碼這個例子看著總是怪怪的,如果把上面的宏轉換成實際代碼,相信你會很容易看懂。
+ (instancetype)boxObj:(id)obj {JPBoxing *boxing = [[JPBoxing alloc] init];boxing.obj = obj;return boxing; } 復制代碼其實就是各種參數的替換導致閱讀起來比較困難。我們都知道程序經過預處理后就會把宏轉換為實際的代碼,而 Xcode 為我們提供了對單個文件進行預處理(Produce -> Perform Action -> Preprocess 'xxxx.m'),這樣處理后,上面的宏就變成了:
+ (instancetype)boxObj:(id)obj { JPBoxing *boxing = [[JPBoxing alloc] init]; boxing.obj = obj; return boxing; } 復制代碼經過預處理后和我們手動翻譯的結果一樣。
Storyboard/Xib 顏色空間的坑
作者: Vong_HUST
今天分享一下 Xcode Interface Builder 設置背景色的一個坑。從 Xcode8 起,Xib/Storyboard 里的顏色空間默認從 Generic RGB 換成了 sRGB,但又不是所有的都會轉換,很奇怪。所以當時在適配 Xcode8 的時候,顏色空間都統一全局替換了一遍。最近又遇到一次這個坑,在 Storyboard 把某個視圖背景色從白色更改為 0xf0f1f2,然后 run 起來,和其 superview (superview 的背景色是用代碼設置的 0xf0f1f2)竟然有一個明顯的分割線,所以回想起當時適配時的這個問題,然后取到 Storyboard 里面一看,果然是顏色空間被莫名改為了 Generic RGB,如圖所示。所以手動改變其顏色空間為 sRGB 即可。
參考鏈接
- Xcode Interface Builder 指定顏色與實際有出入 http://t.cn/RgpFOPg
- WWDC Working with Wide Color http://t.cn/ReADdu7
VC 多層 push 后回到指定頁面的幾種方法
作者: 這個湯圓沒有餡
場景如下: RootVC -- > A -- > B -- > C,然后現在要求C直接pop回到A。
方法一:C返回到B的時候寫個回調,B接收到回調再自己pop到A,但是這個方法B的頁面會閃現一下,用戶體驗不好,不推薦。
方法二:在B push 到C的時候,直接把B從導航控制器的堆棧中移除,如圖一。
方法三:寫一個UIViewController的catrgory,方法實現如圖二。在C的backAct方法中使用,如圖三。有的同學可能會懷疑B會不會內存泄露,可以在B中打印dealloc。
這里比較推薦方法三。不論有多少級的push,只要傳入指定頁面的類名,都能回到該頁面。
添加沙箱技術測試員報錯的問題
作者: 高老師很忙
在測試 IAP 的時候需要添加沙箱技術測試員,相當于創建一個虛擬的 AppleID,填寫的郵箱是不能寫真實 AppleID 郵箱的,要不然就會報錯,可以隨意寫一個不存在的郵箱,為了方便,創建一個簡短的密碼就會報錯誤:
按照提示改好后,依然報錯:
并且沒有任何的提示,感覺這點好坑,嘗試了N遍之后發現是密碼的復雜度不夠,要包含大小寫和數字,雖然是虛擬的 AppleID,但是密碼規則要和正式的 AppleID 一樣,希望以后蘋果把錯誤提示做的更好吧!?
UIViewController 設置導航欄和標簽欄不同 title 的問題
作者: KANGZUBIN
我們通常會在一個 UIViewController 的 viewDidLoad 方法中通過 self.title = xxx 的方式給一個頁面設置其導航欄標題,相信大家對這再熟悉不過了。
如果一個 VC 頁面中同時具有 NavigationBar(導航欄)和 TabBar(標簽欄),而且我們又想讓這兩個地方的標題顯示不一致,如下圖所示,在首頁頂部導航欄標題中顯示“知識小集”,而在底部標簽欄標題中顯示“首頁”:
但是,當我們在 UITabBarController 中初始化好上述頁面結構后,且設置首頁 VC 的 tabBarItem.title 為 “首頁”,然后在首頁 VC 的 viewDidLoad 方法中設置 self.title 為 “知識小集”,編譯運行后我們發現首頁底部標簽欄的標題也變成“知識小集”了,而不是剛設置的“首頁”。
查了蘋果文檔中關于 UIViewController 中 title 屬性的定義,有如下一段描述:
If the view controller has a valid navigation item or tab-bar item, assigning a value to this property updates the title text of those objects.
也就是說,如果一個 VC 同時有導航欄和標簽欄,那么當給 title 賦值時,會同時修改這兩個地方的標題。所以如果我們只想設置導航欄的標題,可以通過 self.navigationItem.title = xxx 的方式來實現。
因此,在一個 VC 中設置相關標題簡單總結如下:
-
self.navigationItem.title: 設置 VC 頂部導航欄的標題
-
self.tabBarItem.title: 設置 VC 底部標簽欄的標題
-
self.title: 同時修改上述兩處的標題
參考文檔
- UIViewController.title https://developer.apple.com/documentation/uikit/uiviewcontroller/1621364-title?language=objc
蘋果官方類庫中 NSDateFormatter 的小 bug
作者: 我是喬忘記瘋狂
不知道有多少人和我一樣是今天才知道這個問題的
let formatter = NSDateFormatter() formatter.dateFormat = "yyyy-MM-dd" let date = formatter.dateFromString("1987-04-12") // nil 復制代碼這個問題在 StackOverflow 上是有人提過的。其實主要跟一些國家實行 夏時制(Daylight saving time) 有關系,尤其是美國
解決辦法我是嘗試這樣增加一句代碼
let formatter = NSDateFormatter() formatter.dateFormat = "yyyy-MM-dd" formatter.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601) let date = formatter.dateFromString("1987-04-12") // Apr 12, 1987, 1:00 AM 復制代碼最后推薦一個夏時制的相關閱讀,高曉松的 魚羊野史 第1卷 中1月6日那一章,有講到美國于1974年1月6日開始實行夏時制并一直到今天,還講到其他一些相關的有意思的事情。
參考文檔
- NSDateFormatter.dateFromString returns nil for specific dates in specific languages
https://stackoverflow.com/questions/32408898/nsdateformatter-datefromstring-returns-nil-for-specific-dates-in-specific-langua
關注我們
歡迎關注我們的公眾號:iOS-Tips,也歡迎加入我們的群組討論問題。可以公眾號留言 ios、flutter、web、pwa、小程序 等關鍵詞獲取入群方式。
總結
以上是生活随笔為你收集整理的「 iOS 知识小集 」2018 · 第 23 期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初识 Vue(18)---(非父子组件间
- 下一篇: mongodb(2)