影响屏幕适配的因素及tableview的ContentSize不正确的问题

上一节说了屏幕适配, iOS6与iOS7屏幕适配 edgesForExtendedLayout, 这节来说说影响iOS6与iOS7屏幕适配的参数和因素都有哪些.其中包括UIViewController 的属性: automaticallyAdjustsScrollViewInsets/ extendedLayoutIncludesOpaqueBars和 UINavigationBar的属性 translucent.

automaticallyAdjustsScrollViewInsets

有一种特殊情况, 就是在 iOS7以后, 有导航栏情况下. 请看如下代码:

#import "ViewController.h"

@interface ViewController ()<UITableViewDataSource, UITableViewDelegate>

@end

@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 300, 600) style:UITableViewStylePlain];
    tableView.delegate = self;
    tableView.dataSource = self;
    [self.view addSubview:tableView];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc]init];
    cell.textLabel.text = @"哈哈哈";
    cell.backgroundColor = [UIColor redColor];
    return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}

@end

效果:
这里写图片描述
这里写图片描述

布局时你会发现, 这个 frame 不正确, 但是滑动后发现, 其实 frame 是对的, 因为tableview 可以透过导航栏看到. 原因为何呢?需要来介绍下automaticallyAdjustsScrollViewInsets属性了, UIViewController 的属性, 默认值为YES.
官方文档:

A Boolean value that indicates whether the view controller should automatically adjust its scroll view insets.
The default value of this property is YES, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to NO if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.
当视图中有状态栏,导航栏以及工具栏或标签栏时, 可以通过它来调整scrollview 展示的位置, 默认自动可以显示出本来应该遮挡在导航栏下的内容, 所以才会有上面那种情况.文中还提到, 如果有多层视图可以滚动的话可以将其设置为 NO.

当将其设置为 NO 后 , 你会发现一开始tableview 展示的位置不会再向下做出导航栏高度的调整, 并且也不容易看到最顶端的内容, 因为它最顶端始终会被导航栏遮挡.

这样的话,也可以看出automaticallyAdjustsScrollViewInsets和上一篇edgesForExtendedLayout属性的区别了.

extendedLayoutIncludesOpaqueBars

@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.

A Boolean value indicating whether or not the extended layout includes opaque bars.
The default value of this property is NO.

这个属性是指是否在不透明导航栏情况下延展布局。

translucent

导航栏透明状态影响布局

@property(nonatomic,assign,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(3_0) UI_APPEARANCE_SELECTOR; // Default is NO on iOS 6 and earlier. Always YES if barStyle is set to UIBarStyleBlackTranslucent

注意:
iOS6及之前默认为不透明, 之后就默认为透明的了. 这也是为什么 iOS6和 iOS7在添加视图时, frame 不一致需要适配的区别之处.
1.因为navigationBar在透明情况,与contentView会重合一部分区域。在不透明情况,contentView紧挨在navigationBar的下⾯.
2.且当透明状态的时候,设置背景图片时,其默认的平铺效果就会消失.

self.navigationController.navigationBar.translucent = NO;
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
view.backgroundColor = [UIColor greenColor];
[self.view addSubview:view];

效果图对比:
这里写图片描述

UIScrollView及其子类屏幕适配总结

这里的UIScrollView(包含其子类UITableView和UICollectionView), 再次引入本篇以及上篇文章介绍过的 contentInset, edgesForExtendedLayout, translucent, hidesBottomBarWhenPushed , automaticallyAdjustsScrollViewInsets等5个参数参数。

contentInset 默认情况下是 UIEdgeInsetsZero 的, 但它会受以下参数影响而产生改变。

VC的属性 edgesForExtendedLayout 默认值为 UIRectEdgeAll, 是允许四个边都可以延伸的; 所以当其改为 UIRectEdgeNone 后四个边都不可以延伸了, scrollView的 contentInset 的值也就变为UIEdgeInsetsZero 了。

navigationBar的属性 translucent 默认值在iOS6是为NO, iOS7为YES, 这个属性其实也就是iOS6与iOS7布局时区别的根源。 translucentNO 情况下, 布局的坐标 y 为0时, 从导航栏下部开始布局(有导航栏情况下)。scrollView是没有顶部内延的, 所以contentInset 属性的top值为0; 当其为 YES 时, 从屏幕顶部开始布局。 scrollView的 contentInset 属性的top值为 64。

VC的属性 hidesBottomBarWhenPushed 默认值是 NO 。当底部的tabBar存在时(包含其仅仅修改hidden为YES情况下), contentInset 属性的bottom值为49; hidesBottomBarWhenPushed为YES时, tabBar是不存在的, contentInset 属性的bottom值为0。

VC的属性 automaticallyAdjustsScrollViewInsets 默认为 YES 的情况下, scrollView的 contentInset 属性值是受底部tabBar是否存在, 顶部导航栏是否存在, 以及顶部导航栏的translucent 属性影响的。这里举例以导航栏和tabBar同时存在且都为默认属性情况下的。
其默认YES 情况下, contentInset 值为UIEdgeInsetsMake(64, 0, 49, 0), 这就是为什么scrollView在iOS7默认情况下, 会自动调整顶部导航栏和底部tabBar不会遮挡内容。所以当设置为 NO 后, 便不会根据页面实际的遮挡情况去自动调整的内嵌距离。

归根结底, UIScrollView(包含其子类UITableView和UICollectionView)的布局其实都是通过VC或者navigationBar的某些属性来影响tableview的contentInset 属性以致于影响布局的显示的。所以我们只需要根据自己项目的需求, 来对这些属性进行调整就可了。

更详细的说明在这里:
给你的TableView一个最合适的布局

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值