實(shí)驗(yàn)記錄
一
// AppDelegate
self.window.rootViewController = [[ViewController alloc] init];
// ViewController
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
沒有NavBar厢塘,沒有設(shè)置任何東西,最簡單情況侈询。左邊為iOS 8舌涨,右邊為iOS 11。發(fā)現(xiàn)iOS 8沒有向下偏移扔字,iOS 11向下偏移了20像素囊嘉。
在iOS 11中決定tableView的內(nèi)容與邊緣距離的是adjustedContentInset
屬性。
在iOS 11中啦租,新增了安全區(qū)域的概念哗伯。由于頂部有狀態(tài)欄,所以系統(tǒng)會自動計算出tv.adjustedContentInset
值為{20, 0, 0, 0}
篷角。從而使得了tv向下偏移20像素焊刹。
二
// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
// ViewController
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
兩者都向下偏移64像素。
在iOS 11以下恳蹲,控制器有
automaticallyAdjustsScrollViewInsets
屬性虐块,默認(rèn)為YES。
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets
API_DEPRECATED("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); // Defaults to YES
這個屬性設(shè)置為YES時嘉蕾,系統(tǒng)會自動把tv向下偏移贺奠。
而在iOS 11中,可以看到automaticallyAdjustsScrollViewInsets
屬性被廢棄错忱,但是為什么仍然向下偏移了64像素呢儡率。原因和一一致,現(xiàn)在的安全區(qū)域已經(jīng)變成了NavBar以下以清,tv.adjustedContentInset
被改為了{64, 0, 0, 0}
儿普,因此也向下偏移64。
三
// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
// ViewController
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
self.automaticallyAdjustsScrollViewInsets = NO;
三是二的反例掷倔。設(shè)置了
self.automaticallyAdjustsScrollViewInsets = NO;
眉孩,iOS 11以下不偏移了。
四
// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
// ViewController
self.tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tv.delegate = self;
self.tv.dataSource = self;
[self.view addSubview:self.tv];
if (@available(iOS 11.0, *)) {
self.tv.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
通過設(shè)置tv.contentInsetAdjustmentBehavior
為UIScrollViewContentInsetAdjustmentNever
,可以不讓系統(tǒng)計算adjustedContentInset
值浪汪。從而使得tv不再偏移巴柿。
五
// AppDelegate
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
// ViewController
self.navigationController.navigationBar.hidden = YES;
self.view.backgroundColor = [UIColor yellowColor];
self.tv = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height - 64) style:UITableViewStylePlain];
self.tv.delegate = self;
self.tv.dataSource = self;
[self.view addSubview:self.tv];
有時候需要自定義導(dǎo)航控制器,這個時候需要把自帶的NavBar隱藏死遭。發(fā)現(xiàn)在iOS 11以下系統(tǒng)中广恢,tv還是會偏移,并且偏移20像素殃姓。而iOS 11就沒有問題袁波。
解決辦法仍然是設(shè)置
automaticallyAdjustsScrollViewInsets
為NO瓦阐。
iOS 11之前的 automaticallyAdjustsScrollViewInsets
我發(fā)現(xiàn)這個屬性很有意思蜗侈。
1 無NavBar
沒有設(shè)置NavigationController的時候,也就是不存在NavBar的時候睡蟋,這個屬性不會起到作用踏幻,tv不會存在偏移問題。
2 有NavBar
2.1 顯示NavBar
當(dāng)設(shè)置了NavigationController的時候戳杀,并不隱藏NavBar该面,會默認(rèn)向下偏移64像素。并且是不管你的NavBar是否遮擋住了tv信卡,都會偏移隔缀。下圖tv.y = 64
2.2 不顯示NavBar
當(dāng)設(shè)置了NavigationController的時候,并隱藏NavBar傍菇,會默認(rèn)向下偏移20像素猾瘸。并且和2.1一致,無論tv的frame如何丢习,都會偏移牵触。下圖tv.y = 64
如果你嫌這個屬性麻煩,就設(shè)為NO咐低,然后手動管理tv的frame揽思。
總結(jié)
經(jīng)過上面的實(shí)驗(yàn),個人認(rèn)為见擦,有一個比較好的解決UIScrollView偏移問題的方法钉汗。就是在代碼中加上下面這一段代碼:
if (@available(iOS 11.0, *)) {
self.tv.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
這樣你就可以為所欲為了,科科鲤屡。