一、iOS應用的 UIWindow
各種方式獲取的 window
:
[UIApplication sharedApplication].delegate.window; //應用的主線窗體, 大部分情況下都是 keyWindow (用 makeKeyAndVisible 設定), 一般提示彈窗什麼的都基於它
[UIApplication sharedApplication].keyWindow; //應用當前的活躍視窗, 一般是 delegate.window , 鍵盤出來後就是鍵盤所在的窗體
[UIApplication sharedApplication].windows.lastObject; //最後一個window, 一般是最上層的窗體, 可能是主程式檢視, 也可能是鍵盤或者其他小浮窗什麼的
複製程式碼
自己新建 window
:
- window 物件釋放 視窗即釋放, 所以物件要全域性儲存
- window 設定
BackgroundColor
為clearColor
, 或者opaque = NO
還是點不到下面的window, 除非設定alpha = 0
二、ALAssetRepresentation
取原圖的坑:
ALAssetRepresentation 自帶的取圖片的方法有兩個:
- fullScreenImage: 返回一個適合全屏顯示的圖片 (如果是長圖大圖則會降低解析度到螢幕解析度以下)
- fullResolutionImage: 返回原圖, 注意了! 如果用自帶的"編輯"功能處理過圖示, 這裡是返回被編輯前的圖片.
如果我們想拿到處理後的圖片, 但是又是原始解析度的話, 要先用fullResolutionImage
拿到原圖, 然後再加上編輯的處理效果, 程式碼示例如下:
#import "ALAssetRepresentation+Category.h"
@implementation ALAssetRepresentation (Category)
/**
* 原圖(或被iOS自帶Photos修改過的圖片)
*
* @return 返回原圖. 如果被iOS自帶Photos編輯過, 則返回編輯後的圖.
*/
-(UIImage*)originImage{
// 拿到原圖
CGImageRef fullResImage = [self fullResolutionImage];
// 通過 fullResolutionImage 獲取到的的高清圖實際上並不帶上在照片應用中使用“編輯”處理的效果,需要額外在 AlAssetRepresentation -> metadata -> AdjustmentXMP 中獲取這些資訊
NSDictionary * imgInfo = [self metadata];
NSString *adj = imgInfo[@"AdjustmentXMP"];
if (adj) {
// 如果有在照片應用中使用“編輯”效果,則需要獲取這些編輯後的濾鏡,手工疊加到原圖中
NSData *xmlData = [adj dataUsingEncoding:NSUTF8StringEncoding];
CIImage *image = [CIImage imageWithCGImage:fullResImage];
NSError *error = nil;
NSArray *filters = [CIFilter filterArrayFromSerializedXMP:xmlData
inputImageExtent:[image extent]
error:&error];
CIContext *context = [CIContext contextWithOptions:nil];
if (filters && !error) {
for (CIFilter *filter in filters) {
[filter setValue:image forKey:kCIInputImageKey];
image = [filter outputImage];
}
fullResImage = [context createCGImage:image fromRect:[image extent]];
}
}
UIImage *result = [UIImage imageWithCGImage:fullResImage
scale:[self scale]
orientation:(UIImageOrientation)[self orientation]];
return result;
}
@end
複製程式碼
三、iOS 檢視中的各種座標
- Frame: 控制元件相對於父控制元件的位置, 和控制元件在父控制元件中所佔的大小
- Bounds: 控制元件內部空間相對於控制元件自身的位置, 和控制元件內部空間的大小.
一般來說, Bounds
的值都等於{0,0,Frame.寬,Frame.高}
, 但是如果手動設定了一個父控制元件的Bounds
的值, 如{0,0,100,100}
設定成了{10,10,100,100}
, 那子控制元件的相對位置就從{10,10}
開始了, 就算設定了子控制元件的Frame
為{0,0,50,50}
, 這個子控制元件也會與父控制元件左上有個{10,10}
的間距
思考:
UIScrollView
的 contentOffset
、contentSize
、contentInset
屬性會不會也跟 Bounds
有關聯和影響
四、synchronized
和 dispatch_once
區別:
寫單例方法時, 我們一般有兩種方法:
+ (instancetype)shareInstance1{
static id instance = nil;
@synchronized (self) {
if (!instance) {
instance = [self new];
}
}
return instance;
}
+ (instancetype)shareInstance2{
static id instance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
instance = [self new];
});
return instance;
}
複製程式碼
一般來說用第二種效能更好, 推薦使用
五、NSSet
這兩個方法有區別的, 別忽略中間的s
而用混了
intersectsSet // 交集,判斷當前集合與指定集合是否有交集
intersectSet // 交集,返回當前集合與指定集合的交集
複製程式碼
六、在tableView didSelectRowAtIndexPath裡面彈出框alert彈出來很慢
一個框彈出來大概要兩三秒
這個貌似是蘋果的bug: openradar.appspot.com/19285091
在tableView didSelectRowAtIndexPath裡面彈出框慢大概找到3個解決辦法 (推薦第三種, 不影響本來的樣式和功能):
- 不要把
selectionStyle
設成UITableViewCellSelectionStyleNone
(但是設定成default點同一個cell依然會慢, 點不同的cell速度正常, 估計點不同的cell背景變色觸發了UI更新) - 第一行加上
[tableView deselectRowAtIndexPath:indexPath animated:NO];
- 在主佇列中非同步執行:
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:ac animated:YES completion:nil];
});
複製程式碼

相關問題: 如果把 UIAlertController
儲存下來, 下次繼續在tableView
裡面彈出來, 則只有灰色背景, 沒有彈框介面了, 也關不了了, 如果點選按鈕做這個操作就沒問題;