1. UICollectionViewLayout 的 prepareLayout 方法
// The collection view calls -prepareLayout once at its first layout as the first message to the layout instance.
collectionview會(huì)在第一次布局時(shí),調(diào)用 prepareLayout 方法一次,作為創(chuàng)建 layout 的第一個(gè)對(duì)象.
// The collection view calls <font color=red>-prepareLayout</font> again after layout is invalidated and before requerying the layout information.
collectionview 再次調(diào)用 prepareLayout 方法時(shí),是在 layout 失效或者重新查詢 layout 信息.
// Subclasses should always call super if they override.
子類必須調(diào)用父類的 prepareLayout 方法.
2. UICollectionViewLayout 的 layoutAttributesForElementsInRect 方法
// UICollectionView calls these four methods to determine the layout information.
UICollectionView調(diào)用以下4個(gè)方法來決定布局信息
// Implement -layoutAttributesForElementsInRect: to return layout attributes for for supplementary or decoration views, or to perform layout in an as-needed-on-screen fashion.
實(shí)現(xiàn) layoutAttributesForElementsInRect 方法來給 頭視圖或尾視圖或裝飾視圖 返回 layout 布局屬性,或者來實(shí)現(xiàn)按需顯示到屏幕上的策略
// Additionally, all layout subclasses should implement -layoutAttributesForItemAtIndexPath: to return layout attributes instances on demand for specific index paths.
額外的,所有的子類必須實(shí)現(xiàn) layoutAttributesForItemAtIndexPath 方法來創(chuàng)建 layout 布局屬性 以便實(shí)現(xiàn)特殊的行的需求.
// If the layout supports any supplementary or decoration view types, it should also implement the respective atIndexPath: methods for those types.
如果布局支持任何 頭視圖/尾視圖或裝飾視圖類型,那么也要實(shí)現(xiàn)各自的atIndexPath:方法.
(PS:應(yīng)該是代理方法collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法)
3. 使用內(nèi)購時(shí) , 必須有恢復(fù)未完成訂單的程序
We still found that your app uses intermediary currency to purchase items that function as non-consumable products but does not include a restore mechanism.
///我們?nèi)匀话l(fā)現(xiàn)虫啥,你的應(yīng)用程序使用中間貨幣來購買功能非消費(fèi)品的商品,但不包括恢復(fù)機(jī)制单匣。
Users restore transactions to maintain access to content that they've already purchased.
/// 用戶恢復(fù)事務(wù)以維護(hù)他們已經(jīng)購買的內(nèi)容的訪問權(quán)豁鲤。
4. 快速定位代碼位置
- tip 1: 通過 Charles 攔截接口,在代碼中查找對(duì)應(yīng)請(qǐng)求該接口的網(wǎng)絡(luò)請(qǐng)求類, 在其回調(diào)中查找配置的視圖或操作.
- tip 2: 運(yùn)行程序, 通過層次結(jié)構(gòu), 查找頁面的名稱, 定位具體的位置, 如TimeTaskView —> GetBambooView —> GetBambooView —> gainBamboos.
- tip 3: 在找不到點(diǎn)擊事件的時(shí)候, 可以在點(diǎn)擊后必須會(huì)調(diào)用的方法中插入斷點(diǎn), 通過調(diào)用過程, 反推點(diǎn)擊事件的原始地方.
- tip 4: 類似于修電腦的方法, 找一個(gè)正確的 UI 和有 bug 的UI進(jìn)行比較, 找出其中的異常.
5. 改 bug 的一些方法
- 高度或間距問題: 改 collectionview 的間距, 可以把layout:sizeForItemAtIndexPath: 方法返回的值, 全部改成無限大或無限小(先不管 section), 如果依舊沒什么用, 可以把layout:insetForSectionAtIndex:方法的值全部改成無限大或無限小(先不管 section), 也就是
不計(jì)后果
的那種. - 重疊問題: A頁面繼承于 B 頁面, A 的頁面明顯超出了 B 的位置 ===> 全局搜索 super 方法, 只有initWithFrame:方法中有 super, 因此需要在創(chuàng)建 A 或 B 時(shí), 各自單獨(dú)調(diào)用initWithFrame:中的方法 ==> 原因是 A 繼承了 B 的視圖, 自己也創(chuàng)建了一份, 但是只給 A 的視圖賦值并更新位置, 沒有給 B 的視圖賦值和更新位置.
6. 快速獲取頂部控制器
在 UIViewController 中很深的子視圖中, 需要調(diào)用UIViewController進(jìn)行跳轉(zhuǎn), 可以直接在當(dāng)前子視圖中遍歷當(dāng)前窗口的根控制器的最外層控制器, 找到后就直接跳轉(zhuǎn).
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[PTVSideMenuViewController class]])
{
PTVSideMenuViewController *sideMenuVc = (PTVSideMenuViewController *)rootViewController;
return [self topViewControllerWithRootViewController:sideMenuVc.rootViewController];
}
else if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}