曾經,iOS開發是不需要考慮屏幕適配問題的,因為只有一種屏幕尺寸。而現在已經有了4種屏幕,4,5,6,6P,因此屏幕適配也成了iOS開發中必須考慮的問題。並且,這4種屏幕的寬高比全部都不一樣,所以簡單的按比例縮放並不能解決問題。我們最近做的一個APP也處理了屏幕適配,本文簡單總結一下
我不知道有沒有更好的辦法,我們的做法是根據設備類型,寫一些if...else,或者switch語句
判斷機型可以使用screen的height(不能使用width,因為4和5的width是一樣的,都是320),也可以使用API裡的宏,都差不多。我個人感覺,if...else似乎是不可避免的,雖然有auto layout,但是有一些大的布局改動,或者字體大小,不用判斷似乎是無法解決的
比如說,為了達到最佳顯示效果,我們在大的屏幕上使用CollectionView,而在4S上使用TableView,用自動布局應該是沒有辦法做到的。或者根據屏幕的大小,切換字體大小,好像也只能通過if...else來實現
根據屏幕類型適配,代碼類似:
if(screenType == LosScreenType6P){ layout.minimumInteritemSpacing = 30; }else if(screenType == LosScreenType5){ layout.minimumInteritemSpacing = 5; }else{ layout.minimumInteritemSpacing = 15; }
我們也用了比較多的“硬計算”,比如對於UICollectionView裡的每個cell的width,我們是這麼處理的:
CGRect rect = [[UIScreen mainScreen] bounds]; screenWidth = rect.size.width; cellWidth = (screenWidth - 30) / 3; cellHeight = cellWidth * 0.8 + 50;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(cellWidth, cellHeight); }
我不太確定這種方式好不好,不過對於這個頁面是好使的。類似這種基於屏幕尺寸做計算的方法,APP裡在幾個頁面都有用到
Masonry是我們實現屏幕適配的重要手段之一,本質上是界面約束的語法糖。基本上,我們的做法是:大的頁面關系,用計算完成;每個小塊裡面的相對位置關系,用Masonry來做。在有些場景下,Masonry有非常大的優勢。比如說:
1、設置某個View的寬高比
[thumbImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@0); make.left.equalTo(@0); make.width.equalTo(self); make.height.equalTo(thumbImageView.mas_width).multipliedBy(0.8); }];
2、設置居中,設置相對邊距
[authorName mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(avatarImageView); make.left.equalTo(avatarImageView.mas_right).offset(5); make.right.equalTo(@-5); }];
類似這種布局,用frame來寫會復雜很多,如果再考慮屏幕適配,需要非常多代碼。這類的需求,Masonry堪稱神器。不過使用中發現,用Masonry布局的View,我們通常會init,或者initWithFrame:CGRectZero。這個View直到經過Masonry處理以後,它的origin和size才能確定,如果在此之前就用到它的origin和size,就會有問題
對於適配後變化不大的頁面,把if...else寫在UIView裡,但是有個別頁面,完全要根據設備顯示不同的View。這種情況比較適合在Controller裡做判斷,然後load不同的View