一、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
里面弹出来, 则只有灰色背景, 没有弹框界面了, 也关不了了, 如果点击按钮做这个操作就没问题;