- XIB不支持静态Cell,只有Storyboard才支持, storyboard是用来描述多个控制器之间的关系的,所以只能拖控制器,不能拖拽基本UI, storyboard是属于一种资源文件不会自动加载,必须要手动加载,一般整个界面只有一个静态TableView时使用storyboard比较方便(如 我、设置等界面),其他情况下能用XIB不要用storyboard,XIB一般用于描述单个控制器视图或者单个视图控制器视图的一部分区域。
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:NSStringFromClass([BWMeViewController class]) bundle:nil];
// 实例化初始的视图控制器 加载箭头->指向的控制器
BWMeViewController *meViewController = [storyboard instantiateInitialViewController];
//------加载局部XIB-----------------------------------------
CustomView *view = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] firstObject];
- UITableView的顶部和尾部的宽度是系统管理的,我们无法改变
- UITableView的第一段的y值默认是35,如果想调整第一段的y坐标可以通过调整tableView的内容偏移量contentInset来间接达到目的, self.tableView.contentInset = UIEdgeInsetsMake(-25, 0, 0, 0); // 这样间隙是35 +(-25) = 10, 这样虽没有调整y坐标的值但同样达到第一段和视图最上层10坐标的差距。
- 在UIView中布局子视图使用layoutSubviews方法,在ViewController中布局子视图使用viewDidLayoutSubviews方法
- 网页展示的方式
- 使用Safari浏览器:自带很多功能(进度条、前进、后退、刷新) 缺点:需要跳出应用
- 使用UIWebView: 需要自己去实现各种功能,但是无法实现进度条功能,系统没有提供该方法
- iOS9.0 使用SFSafariViewController SafariServices框架
- 第三方框架 WKWebView iOS8 (UIWebView的升级版:可以监听进度、缓存)导入WebKit
- 计算缓存大小 和 清除缓存(删除沙盒Cache目录中的所有文件)
// 获取缓存大小
NSUInteger size = [SDImageCache sharedImageCache].getSize;
// 清除缓存
NSString *CachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *subPaths = [fileManager contentsOfDirectoryAtPath:CachePath error:nil];
for (NSString *subPath in subPaths) {
NSString *filePath = [CachePath stringByAppendingPathComponent:subPath];
[fileManager removeItemAtPath:filePath error:nil];
}
- 异步(全局队列,哦哦)和同步(主队列)
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 异步逻辑处理
// 操作UI必须回到主线程
dispatch_sync(dispatch_get_main_queue(), ^{
completion(xxx); // 通过代码块将异步结果返回出去
});
});
- 使用[NSException exceptionWithName:reason:userinfo] 检查方法参数
- alpha:透明度:此属性会让所有的子视图跟着透明,如果只想让某一个控件透明可以设置背景颜色透明,有三种方式
- backgroundColor = [UIColor colorWithRed:green:blue:alpha:0.5];
- backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.5]; // 只适用于白色
- backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.5];
- 屏幕的左上角为原点,想在导航条下显示UI,y坐标是 状态栏20+导航栏44 = 64 ,特殊情况:如果当前视图控制器有导航栏并且导航栏遮挡住了UIScrollView,在这样的前提条件下,如果scrollView的内容被导航栏遮挡住时,此时内容的y坐标系统会自动向下移动64,系统自动下移64只针对UIScrollView这一个控件,其他控件不会这样做。这是一种特例
- 关于UIButton的状态:当长按Button不松时,系统会调用Button的setHighlighted:highlighted方法,将hightlighted 设置成YES,系统使用KVO检测到hightlighted属性发生改变时去刷新UI 高亮颜色;当Button同时拥有两种状态时,按钮的状态是普通状态normal, 例如 当我们长按按钮时同时设置button.selected = YES; 这样同时拥有 高亮和选中 状态,系统最终的状态是 normal状态。在这种情况下当长按时已经不再是高亮状态了; 如何禁用高亮状态:重写setHighlighted方法,方法什么都不写,这样highlighted的值一直是NO,然后我们设置选中状态的颜色, 这样就能达到 长按按钮不松开时的高亮颜色
- 一个ViewController继承UITableViewController,就不必再手动遵守协议,也不必手动设置代理,这个类也会提供一个tableView属性来管理UITableView
- UIViewController中的view的y=0, 而UITableViewController的y= 20, 不是所有的的视图控制器对应的视图的纵坐标都是从0开始的
- contentInset:内容内边距:即内容相对于父视图上下左右的空隙,padding = contentInset
- viewWithTag:该方法首先会查找当前视图对应的tag是否满足条件,如果找不到再找该父视图对应的子视图对应的tag, 如果找不到就再继续找子视图对应的子视图。注意一个控件的tag默认值是0, 我们给其他tag赋值的时候尽量大于0,因为如果从0开始的话,viewWithTag会先从自己开始查找,自己的默认值是0就把自己返回出去了,显然返回的不是想要的结果,一般循环给控件的tag赋值成索引,索引从0开始时,xxx.tag=i, 使用viewWithTag:0 时一般返回的结果是父视图而不是index=0的子视图;
- contentOffset = contentSize - frame, contentSize: 是指内容尺寸,contentInset:是指内边距padding,即在内容周边的空隙,内边距是不属于内容的,是在内容之外的周围
- 重新认识frame:之前知道frame是相对于父视图左上角为原点而言的,具体点是相对于父视图的内容的左上角为原点而言,相对于父视图的内容的左上角为原点而言,相对于父视图的内容的左上角为原点而言,重要的事情说三遍。之前一直认为frame是相对于父视图的左上角为原点的,这适合大部分情况,但是不适合内容滚动的视图,如tableView,表格的内容是 表头+Cell+表尾, 当表格滚动时,Cell的位置发生了变化,即表格的内容的位置发生变化,如果往tableView上加一个子视图,坐标为(0, -64, 200, 64), 其实是加在表头的上方64上,界面一加载的时候此时是看不到刚添加的子视图的,需要往上拉一下才能看到。
- 重新认识bounds:以自己内容左上角为原点,自己的内容相对于控件的位置,bounds = 自己内容 - frame; 对于内容不能滚动的UI,bounds.origin 永远等于(0, 0), 对于内容滚动的视图UIScrollView, UITableView, bounds.origin = 自己内容 - frame = contentOffset.origin;
scrollView.contentOffset.origin=scrollView.bounds.origin; 滚动视图的内容偏移量等于滚动视图的bounds, 对于滚动视图的子视图有一个结论:childView.frame = self.scrollView.bounds; 之前认为bounds.origin 永远等于0是错误的结论! - 通过self.view.window == nil 来判断当前视图现在是否被加载到window上了,像TabBarController的子控制器当点击别的BarButtonItem时,上一个子控制器会被卸载掉的,不再展示在UIWindow上了
- tableView:heightForRowAtIndexPath:默认情况下每次reloadData,数据源中数组有多少个数据就会调用多少次!一口气计算数组中每个数据源的高度,然后每当有Cell进入屏幕范围的时候都会调用一次。加入数据源中有20条数据,系统首先一口气计算20次,加入一屏只能显示3个单元格,然后系统还会再调用3次,可以将高度保存到模型中,如果模型中有值就直接返回
- [[XxxViewController alloc] init] 中的view的认识:首先系统会加载名字和视图控制器完全一样的.xib文件如(XxxViewController.xib)作为XxxViewController的view,如果该文件不存在,系统继续加载视图控制器名字去掉后缀Controller对应的.xib文件(XxxView.xib), 如果还没有找到,系统自动创建一个UIView作为视图控制器的view。预定大于配置,名字的规律是固定的,如果不想作为视图控制器对一个的视图,那么注意起名字时注意这个规律,避开这个特定的名字
- UIView.autoresizingMask 用于子视图是否虽父视图自动调整大小
- 等比计算:交叉相乘相等,一般用于算等比例图片的高度。
- 对于自定义Cell时,一般layoutSubviews是在最后时刻调用的,即一般是给cell设置完model之后返回cell之后才会调用自动布局子视图,即调用顺序 cell.model = xxx —> layoutSubviews
- 在自定义Cell和给cell填充数据的时候,由于循环应用问题,一般有if必有else
- 使用SDWebImage时一般会在合适的时候清理内存缓存。
[[SDImageCache sharedImageCache] clearMemory]; // 清除内存中的缓存
因为所有的图片SDWebImage框架都会以图片路径为key,图片为Value进行NSCache缓存,当在UITableView中的Cell滑出去后,图片的引用技术仍然被NSCache引用一次,计数器为1,在内存中永远不会释放,当长时间滑动Cell时,内存会一直增大,为了稳定内存,必须在合适的时候将NSCache中的所有缓存都清掉,这样之前不用的图片的引用技术就为0了,就能释放了。