iOS的屏幕适配之Autoresizing、Autolayout、VFL、Masonry

一、苹果产品的发行

机型预装系统iPhone发行时间对应Xcode
iPhone4iOS 42010年06月08日Xcode3+
iPhone4SiOS 52011年10月04日Xcode4 (4.0收费,引入ARC)
iPhone5iOS 62012年09月21日Xcode4+ (4.1之后免费,引入Autolayout)
iPhone5SiOS 72013年09月20日Xcode5
iPhone 6/6 PlusiOS 82014年10月10日Xcode6
iPhone 6S/6S PlusiOS 92015年09月10日Xcode7

二、设备的分辨率

设备尺寸像素
iPhone \ iPhone 3G \ iPhone 3GS3.5 inch320 x 480320 x 480
iPhone 4 \ iPhone 4S3.5 inch640 x 960320 x 480
iPhone 5 \ iPhone 5C \ iPhone 5S4.0 inch640 x 1136320 x 568
iPhone64.7 inch750 x 1334375 x 667
iPhone6 plus5.5 inch1242 x 2208414 x 736
iPad \ iPad29.7 inch768 x 1024768 x 1024
iPad 3(The new iPad) \ iPad4 \ iPad Air9.7 inch1536 x 2048768 x 1024
iPad Mini7.9 inch768 x 1024768 x 1024
iPad Mini 2(iPad Mini with retina display)7.9 inch1536 x 2048768 x 1024

三、屏幕适配

  1. iPhone4S之前没有屏幕适配,因为屏幕尺寸不变,全部用frame、bounds、center进行布局。
  2. iphone5之后才开始有屏幕适配。

四、Autoresizing

  1. iPad的出现和iPhone横屏的出现,出现Autoresizing技术
  2. Autoresizing让横竖屏适配相对于用frame、bounds、center进行布局简单
  3. 使用Autoresizing的前提是:关闭Autolayout功能;因为有些功能重复
  4. 局限性
    - 只能解决子控件跟父控件的相对关系问题
    - 不能解决兄弟控件的相对关系问题
  5. 当控件的的autoresizesSubviews是YES时,(默认是YES),那么UIView对象的子控件会根据子控件自身的autoresizingMask属性值来自动适应与其父控件之间的位置和大小
  6. storyboard或xib下使用Autoresizing,宽高和宽度的自动调整:实线代表选中,左右上下间距的自动调整:虚线代表选中


    关闭自动布局


这里写图片描述


  1. 纯代码使用Autoresizing
---------- UIViewAutoresizing类型,有两个尖号<<代表可以复选,复选用竖杠隔开

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    //不自动调整
    UIViewAutoresizingNone                 = 0,
    //自动按与父控件比例调整与父控件左边的距离,且与父控件右边的距离不变
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    //自动按与父控件比例调整与父控件的右边距离,且与父控件左边的距离不变
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    //自动按与父控件比例调整与父控件的顶部距离,且与父控件底部的距离不变
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    //自动按与父控件比例调整与父控件的底部距离,且与父控件顶部的距离不变
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
    //自动与父控件按比例调整宽度
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    //自动与父控件按比例调整高度
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
};

---------- Autoresizing的使用 

#import "ViewController.h"

@interface ViewController ()


@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  //创建控件,做为父控件
  UIView *viewSuper = [[UIView alloc] initWithFrame:CGRectMake(40, 50, 200, 200)];
  viewSuper.backgroundColor = [UIColor greenColor];
  [self.view addSubview:viewSuper];
  //创建控件,做为子控件
  UIView *viewSub = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 50, 100)];
  viewSub.backgroundColor = [UIColor orangeColor];
  [viewSuper addSubview:viewSub];

  //autoresizesSubviews的默认值为YES
  //当值为NO时,不会根据子控件的autoresizingMask属性值来自动调整
  //viewSuper.autoresizesSubviews = NO;

  //自动按照比例调整与父控件的左间距和自动按比例调整宽度
  viewSub.autoresizingMask =   UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth;

}

//随机改变父控件的宽高,测试调整效果
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  //arc4random_uniform()是取随机数
  CGFloat w = 200 + arc4random_uniform(100);
  CGFloat h = 200 + arc4random_uniform(100);
  [[self.view.subviews lastObject] setFrame:CGRectMake(40, 40, w, h)];
}

@end

五、Autolayout
(一).Autolayout的2个核心概念
1.参照:参照是指一个约束是根据那个控件来计算约束的,做为参照的控件位置和尺寸大小必须明确
2.约束:约束相当于控件的Frame,用来明确控件所处的位置和控件的的尺寸大小

(二).Autolayout核心计算公式
约束的计算方法:obj1.property =(<=或>=)(obj2.property * multiplier)+ constant
解析:
=: 等号可以根据需求改为:小于等于或大于等于
obj1:控件
property:左边线,右边线,垂直中心线,上边线,下边线,水平中心线,高度,宽度等的约束值
multiplier:倍数
constant:偏移量

(二).注意:
1.约束的本质:用来明确控件所处的位置和控件的的尺寸大小
2.约束和Frame类似,Frame也是用来确定位置和尺寸的大小
3.给一个控件加约束,要么不加,要么加全了;只要给控件添加一个约束,就要加全必要约束,要让控件明确的知道它自己的尺寸和所处的位置,苹果鼓励开发者尽量用Autolayout,忘掉Frame
4.Updata Frames:设置约束后更新Frame;如果约束不全,更新之后控件就会找不到
5.控件UILable很特殊,只约束它的位置,不约束尺寸大小,系统会自动添加宽度和高度约束,这个特性可以用于设置lable的宽度或高度随内容的变化而变化

(三).storyboard和xib下的设置

1.Autolayout的警告和错误
(1).警告
控件的frame不匹配所添加的约束
比如:约束控件的宽度为100, 而控件现在的宽度是110
(2).错误
a.缺乏必要的约束
比如:只约束了宽度和高度, 没有约束具体的位置
b.两个约束冲突
比如:1个约束控件的宽度为100, 1个约束控件的宽度为110

2.添加约束时,系统会自动以Top Layout Guide和Bottom Layout Guide两条线做为约束的参照物,这两天线是系统自动创建时就添加的
这里写图片描述


这里写图片描述


3.约束的属性面板:可以在这个面板修改约束
这里写图片描述


4.Constrain to margins:选中就默认在左右两边各加上16个像素
这里写图片描述


5.更新约束(一)
(1).成功添加就就马上更新
这里写图片描述


(2.)手动更新
这里写图片描述


6.拖拽添加约束
这里写图片描述


这里写图片描述


(四).代码实现Autolayout
1.实现步骤
(1).先禁止autoresizing功能,设置view的下面属性为NO

view.translatesAutoresizingMaskIntoConstraints = NO;

(2).利用NSLayoutConstraint类创建具体的约束对象
创建约束对象的常用方法:

+(instancetype)constraintWithItem:(id)view1 
                        attribute:(NSLayoutAttribute)attr1 
                        relatedBy:(NSLayoutRelation)relation 
                           toItem:(id)view2 
                        attribute:(NSLayoutAttribute)attr2 
                       multiplier:(CGFloat)multiplier 
                         constant:(CGFloat)c;
/**
解析:
     view1 :要约束的控件
     attr1 :约束的类型(上、下、左、右、顶部、底部)
  relation :与参照控件之间的关系(=、<=或>=)
     view2 :参照的控件
     attr2 :约束的类型(上、下、左、右、顶部、底部)
multiplier :乘数
         c :常量
计算公式:attr1 =(<=或>=) attr2 * multiplier + c
**/

(3).添加约束对象到相应的view上

- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;

2.添加约束的规则
(1).对于两个同层级view之间的约束关系,添加到它们的父view上
这里写图片描述


(2).对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
这里写图片描述


(3).对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
这里写图片描述


3.注意
(a).要先禁止autoresizing功能,设置view的translatesAutoresizingMaskIntoConstraints属性为NO;不然系统会自动把Autoresizing的值转换成约束
(b).添加约束之前,一定要保证相关控件都已经在各自的父控件上
(c).不用再给view设置frame
(d).添加约束不要添加错了控件
(e).一般报错原因是:约束冲突或者约束不完整
4.编程举例

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  //创建一个蓝色的View,不用设置Frame,设置了可能会起冲突
  UIView *blueView = [[UIView alloc] init];
  blueView.backgroundColor = [UIColor blueColor];
  //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束
  blueView.translatesAutoresizingMaskIntoConstraints = NO;
  [self.view addSubview: blueView];

  //创建一个红色的View,不用设置Frame,设置了可能会起冲突
  UIView *redView = [[UIView alloc] init];
  redView.backgroundColor = [UIColor redColor];
  //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束
  redView.translatesAutoresizingMaskIntoConstraints = NO;
  [self.view addSubview:redView];


#pragma mark - 设置蓝色的约束

  //给蓝色View添加约束:顶部距离父控件上边框50像素
  NSLayoutConstraint *blueTopLayout = [NSLayoutConstraint
                                       constraintWithItem:blueView
                                                attribute:NSLayoutAttributeTop
                                                relatedBy:NSLayoutRelationEqual
                                                   toItem:self.view
                                                attribute:NSLayoutAttributeTop
                                               multiplier:1.0
                                                 constant:50];
  [self.view addConstraint:blueTopLayout];

  //给蓝色View添加约束:左边距离父控件左边框180像素
  NSLayoutConstraint *blueLeftLayout = [NSLayoutConstraint
                                        constraintWithItem:blueView
                                                 attribute:NSLayoutAttributeLeft
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.view
                                                 attribute:NSLayoutAttributeLeft
                                                multiplier:1.0
                                                  constant:80];
  [self.view addConstraint:blueLeftLayout];

  //给蓝色View添加约束:宽度为100个像素
  NSLayoutConstraint *blueWidthLayout = [NSLayoutConstraint
                                         constraintWithItem:blueView
                                                  attribute:NSLayoutAttributeWidth
                                                  relatedBy:NSLayoutRelationEqual
                                                     toItem:nil
                                                  attribute:NSLayoutAttributeNotAnAttribute
                                                 multiplier:0.0
                                                   constant:100];
  [blueView addConstraint:blueWidthLayout];

  //给蓝色View添加约束:高度为100个像素
  NSLayoutConstraint *blueHeightLayout = [NSLayoutConstraint
                                          constraintWithItem:blueView
                                                   attribute:NSLayoutAttributeHeight
                                                   relatedBy:NSLayoutRelationEqual
                                                      toItem:nil
                                                   attribute:NSLayoutAttributeNotAnAttribute
                                                  multiplier:0.0
                                                    constant:100];
  [blueView addConstraint:blueHeightLayout];


#pragma mark - 设置红色的约束

  //给红色View添加约束:宽度为100个像素
  NSLayoutConstraint *redWidthLayout = [NSLayoutConstraint
                                        constraintWithItem:redView
                                                 attribute:NSLayoutAttributeWidth
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:nil
                                                attribute:NSLayoutAttributeNotAnAttribute
                                               multiplier:0.0
                                                 constant:100];

  //给红色View添加约束:高度为100个像素
  NSLayoutConstraint *redHeightLayout = [NSLayoutConstraint
                                         constraintWithItem:redView
                                                  attribute:NSLayoutAttributeHeight
                                                  relatedBy:NSLayoutRelationEqual
                                                     toItem:nil
                                                  attribute:NSLayoutAttributeNotAnAttribute
                                                 multiplier:0.0
                                                   constant:100];

  //用数组的方式批量添加约束
  [redView addConstraints:@[redWidthLayout,redHeightLayout]];

  //给红色View添加约束:红色的左边线距离蓝色的右边线距0个像素
  NSLayoutConstraint *redLeftLayout = [NSLayoutConstraint
                                       constraintWithItem:redView
                                                attribute:NSLayoutAttributeLeft
                                                relatedBy:NSLayoutRelationEqual
                                                   toItem:blueView
                                                attribute:NSLayoutAttributeRight
                                               multiplier:1.0
                                                 constant:0];

  //给红色View添加约束:红色的上边线与蓝色的上边线对齐
  NSLayoutConstraint *redTopLayout = [NSLayoutConstraint
                                         constraintWithItem:redView
                                                  attribute:NSLayoutAttributeTop
                                                  relatedBy:NSLayoutRelationEqual
                                                     toItem:blueView
                                                  attribute:NSLayoutAttributeTop
                                                 multiplier:1.0
                                                   constant:0];

  //用数组的方式批量添加约束
  [self.view addConstraints: @[redLeftLayout,redTopLayout]];

}

@end

六、VFL语言
1.VFL全称是Visual Format Language,翻译过来是“可视化格式语言”
2.VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言
3.语法
(1).语法列表

表达式功能
v:表示垂直
H:表示水平
|表示父控件的边框,前面是V:就代表垂直方向的父控件边框,前面是H:就代表水平方向的父控件边框,竖线前面没有V:和H:默认是水平方向,如 |[redView]表示redView紧贴父控件的左边框
-表示一个小间隔或表示距离,如:V:|-20- 表示距离顶部20像素,|-[redView]表示redView距离父控件的左边框有一个小间隔
( )括号里可以写控件名,如:H:|-[button1(button)]表示button1与button等宽;也可以写H:|-[button(==30)]表示button宽等于30像素
[]方括号里表示写控件名,[button]表示button控件;H:[button1][button2]表示两个控件水平紧贴着
@value表示优先级别,如: H:[button(>=50@800)] 表示button宽度大于等于50像素,该约束条件优先级为800(优先级最大值为1000,优先级越高的约束越先被满足)

(2).举例
H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton宽72,acceptButton宽50,它们之间间距12

H:[wideView(>=60@700)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)

V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox

H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
4.使用VFL语言设置约束的步骤
(1).用VFL语言创建VFL语句,用字符串表示
(2).把VFL语句中包含的数值或控件用字典表示

//创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义
NSDictionary *dic = NSDictionaryOfVariableBindings(…);

(3).使用VFL来创建约束数组的常用方法

+ (NSArray *)constraintsWithVisualFormat:(NSString *)format 
                                 options:(NSLayoutFormatOptions)opts 
                                 metrics:(NSDictionary *)metrics 
                                   views:(NSDictionary *)views;
/**
解析
 format :VFL语句
   opts :约束类型,一般写kNilOptions,表示空选项
metrics :VFL语句中用到的具体数值
  views :VFL语句中用到的控件
**/

(4).把约束数组添加到对应的控件中

- (void)addConstraints:(NSArray *)constraints;

5.代码举例

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  //创建一个蓝色的View,不用设置Frame
  UIView *blueView = [[UIView alloc] init];
  blueView.backgroundColor = [UIColor blueColor];
  //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束
  blueView.translatesAutoresizingMaskIntoConstraints = NO;
  [self.view addSubview: blueView];

  //水平方向下:控件blueView的宽度等于100像素,左右边距为默认一个小间距
  NSString *vfl1 = @"H:|-[blueView(==100)]-|";
  NSDictionary *ditViews1 =  NSDictionaryOfVariableBindings(blueView);
  NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl1 options:kNilOptions metrics:nil views:ditViews1];
  [self.view addConstraints:constraints];

  //垂直方向下:控件blueView距左边距50个像素,高度等于100像素,右边距为默认一个小间距
  NSNumber *n = @100;
  NSString *vfl2 = @"V:|-50-[blueView(==n)]-|";
  NSDictionary *metrics =  NSDictionaryOfVariableBindings(n);
  NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:kNilOptions metrics:metrics views:ditViews1];
  [self.view addConstraints:constraints2];

}
@end

6.有用到Frmae属性的控件,不用把translatesAutoresizingMaskIntoConstraints属性设置为NO,设置为NO后,Frame将不起作用,值为0

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  //创建一个蓝色的View
  UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(100, 50, 200, 200)];
  blueView.backgroundColor = [UIColor blueColor];
  //如果控件不设置约束,而是直接使用Frame,就不用设置属性为NO
  blueView.translatesAutoresizingMaskIntoConstraints = YES;
  [self.view addSubview: blueView];

  //创建一个红色的View,不用设置Frame
  UIView *redView = [[UIView alloc] init];
  redView.backgroundColor = [UIColor redColor];
  //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束
  redView.translatesAutoresizingMaskIntoConstraints = NO;
  [blueView addSubview:redView];

  //redView与父控件的左右边距各为一个小间隔
  NSString *vflH = @"|-[redView]-|";
  NSDictionary *dic = NSDictionaryOfVariableBindings(redView);
  NSArray *constraints1 = [NSLayoutConstraint constraintsWithVisualFormat:vflH options:kNilOptions metrics:nil views:dic];
  [blueView addConstraints:constraints1];

  //redView紧贴父控件的上边框,高度为100
  NSString *vflV = @"V:|[redView(==100)]";
  NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vflV options:kNilOptions metrics:nil views:dic];
  [blueView addConstraints:constraints2];

}
@end

七、Masonry
(一).简介
1.目前最流行的Autolayout第三方框架
2.用优雅的代码方式编写Autolayout
3.省去了苹果官方Autolayout长代码

(二).添加约束的类型
1.尺寸:width\height\size
2.边界:left\leading\right\trailing\top\bottom
3.中心点:center\centerX\centerY
4.边界:edges

(三).添加约束的方法
1.mas_makeConstraints:这个方法只会添加新的约束
2.mas_updateConstraints:这个方法将会覆盖以前的某些特定的约束
3.mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束

(四).注意
1.创建的控件时不用再把控件的translatesAutoresizingMaskIntoConstraints属性设置为NO,框架里已经封装
2.equalTo方法不会对数据进行包装
3.mas_equalTo方法会对参数进行包装
4.multipliedBy表示乘数
5.offset:这个方法代表偏移量,正表示往下或往右移动,负表示往上或往左移动
6.当只对宽高进行约束,不对位置约束时,位置默认在父控件的左上角
7.只要添加了#define MAS_SHORTHAND这个宏,就不用带mas_前缀
8.只要添加了#define MAS_SHORTHAND_GLOBALS这个宏,equalTo就等价于mas_equalTo
9.#define MAS_SHORTHAND 和 #define MAS_SHORTHAND_GLOBALS 一定要添加到#import “Masonry.h”上面,因为Masonry.h里面的代码要用到这两个宏

(五).代码举例
下面代码中,每一个添加约束的方法都可以独立完整的添加约束,可以挨个进行测试

#import "ViewController.h"

//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS

#import "Masonry.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  //创建一个红色视图
  UIView *redView = [[UIView alloc] init];
  redView.backgroundColor = [UIColor redColor];
  [self.view addSubview:redView];

  //mas_makeConstraints:这个方法只会添加新的约束
  [redView mas_makeConstraints:^(MASConstraintMaker *make) {

    //equalTo:这个方法不会对参数进行包装,
    make.width.equalTo(@100);

    //mas_equalTo:这个方法会对参数进行包装
    make.width.mas_equalTo(100);

    //offset:这个方法代表偏移量,正表示往下或往右移动,负表示往上或往右移动
    make.top.equalTo(self.view).offset(100);
    make.right.equalTo(self.view.mas_left).offset(200);

  }];

  //mas_updateConstraints:这个方法将会覆盖以前的某些特定的约束
  [redView mas_updateConstraints:^(MASConstraintMaker *make) {

    //size:设置宽和高的约束
    make.size.equalTo([NSValue valueWithCGSize:CGSizeMake(50, 50)]);

    //make.size.mas_equalTo(CGSizeMake(200 , 200));

  }];

  //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束
  [redView mas_remakeConstraints:^(MASConstraintMaker *make) {

    //redView高等于父控件的0.5倍,在加上10个像素
    make.height.equalTo(self.view.mas_height).multipliedBy(0.5).offset(10);
    //redView宽等于父控件的0.5倍,在减去10个像素
    make.width.mas_equalTo(self.view.mas_width).multipliedBy(0.5).offset(-10);

  }];

  //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束
  [redView mas_remakeConstraints:^(MASConstraintMaker *make) {

    //距离父控件四周都是50间距
    make.edges.mas_equalTo(self.view).insets(UIEdgeInsetsMake(50, 50, 50, 50));

  }];

  //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束
  [redView mas_remakeConstraints:^(MASConstraintMaker *make) {

    make.width.equalTo(@150);
    make.height.mas_equalTo(150);
    //redView的中心在父控件的中心
    make.center.mas_equalTo(self.view).insets(UIEdgeInsetsZero);

  }];

  //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束
  [redView mas_remakeConstraints:^(MASConstraintMaker *make) {

    //必须要在文件开头添加 #define MAS_SHORTHAND 和 #define MAS_SHORTHAND_GLOBALS
    //才能在equalTo中用基本数据类型的数据,宏定义会自动包装基本数据类型的数据
    make.width.equalTo(100);
    make.height.equalTo(100);
    make.centerX.equalTo(self.view.centerX);
    make.centerY.equalTo(self.view.centerY);

  }];

}

@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值