iOS Developer

全屏幕适配

2017-05-02  本文已影响82人  bigParis

说起屏幕适配, 估计很多人都会想到autoLayout, 想到Masonry, 但是今天说的屏幕适配与这自动布局没关系, 这是一种全局的方式.

故事背景

很多时候我们开发一个UI, 设计给出的标注都是按照某个机型来标注的, 里面的像素都是写死的, 但实际上, 对于不同的屏幕, 这些值可能是需要变化的, 但是设计并不会在设计图上说, 这东西可能会变化, 也不会说哪里变化, 哪里不变, 这就可能恶心到我们, 辛辛苦苦做的一个UI, 在小屏幕的手机上一运行发现显示不下, 这就尴尬了, 这个锅设计和产品肯定不背, 最后还是要我们开发撅着屁股去改.

iphone6下的布局

由于公司的设计用的是iphone6, 所以所有的标注都是按照iphone6来的, 上图的布局在iphone6下显示是没有问题的, 居中显示, 下面是代码.

static const CGFloat iphone6Width = 375.0f;
static const CGFloat iphone6Height = 667.0f;

@interface ViewController ()

@property (nonatomic, weak) UIView *redView;
@property (nonatomic, weak) UIView *blueView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initViews];
}

- (void)initViews {
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    self.redView = redView;
    
    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];
    self.blueView = blueView;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.redView.frame = CGRectMake((iphone6Width - 250) * 0.5, 100, 250, 100);
    self.blueView.frame = CGRectMake((iphone6Width - 250) * 0.5, CGRectGetMaxY(self.redView.frame) + 10, 250, 100);
}
@end

这应该是一个简单不能再简单的布局了, 然而, 这种写法显然是不对的, iphone6Width是固定的值, 到了其它屏幕显示就会有问题.

SE上的布局

但是可能我们开发的时候并没有注意要多机型屏幕适配, 那就尴尬了, 如果不是2个view, VC中有几十个view就尴尬大了, 不过没关系, 用了今天的方法, 很快就能搞定.

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initViews];
}

- (void)initViews {
    
    UIView *iphone6View = [[UIView alloc] init];
//    iphone6View.backgroundColor = [UIColor greenColor];
    [self.view addSubview:iphone6View];
    self.iphone6View = iphone6View;
    
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.iphone6View addSubview:redView];
    self.redView = redView;
    
    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.iphone6View addSubview:blueView];
    self.blueView = blueView;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    float sx = self.view.bounds.size.width / iphone6Width;
    float sy = self.view.bounds.size.height / iphone6Height;
    self.iphone6View.transform = CGAffineTransformMakeScale(sx, sy);
    
    [self layoutForIPhone6];
}

- (void)layoutForIPhone6 {
    self.redView.frame = CGRectMake((iphone6Width - 250) * 0.5, 100, 250, 100);
    self.blueView.frame = CGRectMake((iphone6Width - 250) * 0.5, CGRectGetMaxY(self.redView.frame) + 10, 250, 100);
}
@end

我们还是按照原来的方式去做, 只是把view都添加到iphone6View上, 而iphone6View是个虚拟的view, 我们把iphone6View进行放射变化, 里面的子view也随之变换了, 我们根据设计的标注, 把子view都添加到iphone6View就可以了, 这样还能解决不同屏幕下字体的缩放问题, 使用自动布局只能调整view自适应, 但是很难搞定不同尺寸下字体的问题.

在实际开发中, iphone6View还是要设置一个真实的frame才可以, 因为子view要取iphone6View作为参照.

- (void)initViews {
    
    UIView *iphone6View = [[UIView alloc] init];
//    iphone6View.backgroundColor = [UIColor greenColor];
    [self.view addSubview:iphone6View];
    self.iphone6View = iphone6View;
    
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.iphone6View addSubview:redView];
    self.redView = redView;
    
    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.iphone6View addSubview:blueView];
    self.blueView = blueView;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.iphone6View.bounds = CGRectMake(0, 0, iphone6Width, iphone6Height);
    self.iphone6View.center = self.view.center;
    float sx = self.view.bounds.size.width / iphone6Width;
    float sy = self.view.bounds.size.height / iphone6Height;
    self.iphone6View.transform = CGAffineTransformMakeScale(sx, sy);
    
    [self layoutForIPhone6];
}

- (void)layoutForIPhone6 {
    self.redView.frame = CGRectMake((self.iphone6View.bounds.size.width - 250) * 0.5, 100, 250, 100);
    self.blueView.frame = CGRectMake((self.iphone6View.bounds.size.width - 250) * 0.5, CGRectGetMaxY(self.redView.frame) + 10, 250, 100);
}
@end
总结

本例在多屏幕的适配上取得了很好的效果, 在iphone现在机型长宽比差距不是很大的情况下, 进行等比例缩放不会有什么问题, 但如果日后出现很多新机型, 长宽比出现很大差距, 可能就要针对不同机型进行不同的缩放了.

上一篇 下一篇

猜你喜欢

热点阅读