界面适配:UICollectionView 全面屏safeAre

2018-12-04  本文已影响0人  光之盐汽水

UICollectionView是功能强大的控件,正确使用CollectionView可以让我们的研发更方便快捷。今天我们来学习的是横竖屏时,collectionView的界面显示处理,方法非常简单。

1、首先我们先创建一个collectionView

@interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>

@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) UICollectionViewFlowLayout *collectionViewLayout;

@end

@implementation ViewController

/**
 collectionView
 */
- (UICollectionView *)collectionView {
    
    if (!_collectionView) {
        _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:self.collectionViewLayout];
        _collectionView.backgroundColor = [UIColor whiteColor];
        
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        
        // 注册cell
        [_collectionView registerNib:[UINib nibWithNibName:@"XZCourceCell" bundle:nil] forCellWithReuseIdentifier:@"cource"];
        // 注册cell
        [_collectionView registerNib:[UINib nibWithNibName:@"FiFNewsCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"newsCell"];
        // 注册headerView
        [_collectionView registerNib:[UINib nibWithNibName:@"XZManHuaHeaderView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
    }
    return _collectionView;
}

- (UICollectionViewFlowLayout *)collectionViewLayout {
    
    if (!_collectionViewLayout) {
        _collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];
        // 设置滑动方向
        _collectionViewLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
        // 设置最小行间距
        _collectionViewLayout.minimumLineSpacing = 10.f;
        // 设置分区的EdgeInset
        _collectionViewLayout.sectionInset = UIEdgeInsetsZero;
    }
    return _collectionViewLayout;
}

#pragma mark -UICollectionView

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 5;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 6;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section % 2 == 0) {
        FiFNewsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"newsCell" forIndexPath:indexPath];
        return cell;
    }
    else {
        XZCourceCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cource" forIndexPath:indexPath];
        return cell;
    }
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    if (indexPath.section % 2 == 0) {
        return CGSizeMake(self.collectionView.bounds.size.width, 100);
    } else {
        return CGSizeMake(75, 125);
    }
    
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    return CGSizeMake(self.collectionView.bounds.size.width, 50);
}
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    XZManHuaHeaderView *reusableView=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
    if (indexPath.section==0) {
        reusableView.nameTitle=@"热门推荐";
    } else {
        reusableView.nameTitle=@"强力推荐";
    }
    return reusableView;
}
@end

2、适配横竖屏
当横竖屏的时候,系统提供了回调方法。


对于UIViewController
-(void)viewSafeAreaInsetsDidChange NS_REQUIRES_SUPER API_AVAILABLE(ios(11.0), tvos(11.0));
对于UIView
-(void)safeAreaInsetsDidChange API_AVAILABLE(ios(11.0),tvos(11.0));


由于如果在viewSafeAreaInsetsDidChange方法中适配界面的话,可能在界面push进来的时候,会有一些不必要的动画,所以我们统一在viewDidLayoutSubviews方法中进行界面布局的适配。由于viewDidLayoutSubviews方法会因为其他操作(比如collectionView的滚动)调动的很频繁,所以,我们先添加一个标记,只有在viewSafeAreaInsetsDidChange之后,才进行布局的适配。

@interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
{
    
    // 标志,用于判断SafeArea是否改变
    BOOL _isSafeAreaInsetsDidChange;
}

@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) UICollectionViewFlowLayout *collectionViewLayout;

@end

@implementation ViewController

- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    
    _isSafeAreaInsetsDidChange = YES;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    if (_isSafeAreaInsetsDidChange == YES) {
        _isSafeAreaInsetsDidChange = NO;
        
        if (@available(iOS 11.0, *)) {
            - (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    
    _isSafeAreaInsetsDidChange = YES;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    if (_isSafeAreaInsetsDidChange == YES) {
        _isSafeAreaInsetsDidChange = NO;
        
        if (@available(iOS 11.0, *)) {
            self.collectionView.frame = self.view.safeAreaLayoutGuide.layoutFrame;
        } else {
            // Fallback on earlier versions
            self.collectionView.frame = self.view.bounds;
        }
    }
} = self.view.safeAreaLayoutGuide.layoutFrame;
        } else {
            // Fallback on earlier versions
            self.collectionView.frame = self.view.bounds;
        }
    }
}

@end

这样就可以确保在横竖屏时,collectionView的frame一直处在self.view.safeAreaLayoutGuide里面了。

看一下最终显示的效果吧~


image.png
image.png
上一篇下一篇

猜你喜欢

热点阅读