AutoLayout對 scrollview的contentSize 和contentOffset屬性的影響
問題一、iOS開發中,如果在XIB文件中創建一個scrollview,同時給它設置布局限制,然后在viewDidload方法設置它的contentSize,仍然不能滾動?
應該就是勾選了AutoLayout選項導致的。因為在AutoLayout下,iOS計算scrollview的contentsize的機制是略有不同的。
在AutoLayout下,會在viewDidAppear之前根據subview的constraint重新計算scrollview的contentsize。 這就是為什么,在viewDidload里面手動設置了contentsize沒用。因為在后面,會再重新計算一次,前面手動設置的值會被覆蓋掉。
解決辦法有以下三種:
1.去除AutoLayout選項,自己手動設置contentSize。如 self.scrollView.contentSize = CGSizeMake(1200, 1200);
2.如果要使用AutoLayout,要么自己設置完subview的constraint,然后讓系統自動根據constraint計算出contentSize。
如 self.scrollView.contentSize = self.imgView.frame.size;
3.要么就在viewDidAppear里面自己手動設置contentsize。
另外,設置scrollView的初始偏移量contentOffset也會受到AutoLayout影響,在viewDidLoad中設置的偏移量,因受AutoLayout影響,在viewDidAppear方法中會被歸(0,0),此問題見以下代碼,可參考以上3種方法進行解決。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"viewDidLoad");
//設置scrollciew內容大小
self.scrollView.contentSize = self.imgView.frame.size;
//在viewDidLoad中做一次偏移(在viewDidAppear方法中,偏移會被歸0)
[self printOffset];
self.scrollView.contentOffset = CGPointMake(-200, -200); //結構體作為屬性時必須整體賦值,不可以單個修改結構體成員(這是OC的規定)
[self printOffset];
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
NSLog(@"viewDidAppear");
//在viewDidAppear中做一次偏移((但在viewDidAppear方法中,偏移會被歸0))
[self printOffset];
CGPoint origin = CGPointMake(-100, -100);
self.scrollView.contentOffset = origin; //結構體作為屬性時必須整體賦值,不可以單個修改結構體成員(這是OC的規定) [self printOffset];
}
打印結果如下:
2016-04-08 12:20:07.181 6.0 UIScrollView常用屬性[874:61590] viewDidLoad
2016-04-08 12:20:07.182 6.0 UIScrollView常用屬性[874:61590] offset: {0, 0}
2016-04-08 12:20:07.182 6.0 UIScrollView常用屬性[874:61590] offset: {-200, -200}
2016-04-08 12:20:07.257 6.0 UIScrollView常用屬性[874:61590] viewDidAppear
2016-04-08 12:20:07.257 6.0 UIScrollView常用屬性[874:61590] offset: {0, 0}
2016-04-08 12:20:07.257 6.0 UIScrollView常用屬性[874:61590] offset: {-100, -100}
問題二、iOS開發: 解決UIScrollView不滾動的問題
照着書上的Demo(iOS 5.0的教程),在- (void)viewDidLoad里設置scrollView的contentsize,讓它大於屏幕的高度,卻發現在模擬器中沒用,還是不能滾動。經過一翻搜索發現,這是因為iOS 6.0中新增的AutoLayout機制引起的,viewDidLoad后,AutoLayout會再一次把scrollView的contentSize設為屏幕的寬高,所以,我們的設置就無效了。
解決方法:把設置ContentSize的代碼放到viewDidAppear里。
- -(void)viewDidAppear:(BOOL)animated
- {
- [super viewDidAppear:animated];
- [_scrollView setContentSize:CGSizeMake(500, 1800)];
- }
關於網上很多博客寫着“結構體類型里面的某個屬性如果想要修改是不允許單個修改的” 之解釋:
其實並不是說結構體的成員就一定不能單個修改,例如在某方法中單獨定義一個結構體類型的臨時變量,是可以對它的成員直接進行修改的。
只是結構體在作為OC對象的屬性使用時,OC語法規定不能單獨對結構體屬性的單個成員進行修改,要改必須通過對對象的結構體屬性整體賦值,這樣做也確保數據的完整性。
