赞
踩
当我们想让子视图随着父视图的变化跟着变化时,我们需要选择使用手动布局子视图或者自动布局子视图两个方法之一。
先来学习手动布局子视图。
首先,我们先创建一个父视图superView,
然后在ViewController中,实现两个内容:
我们使用UIView的 animateWithDuration: animations:方法来制作控制视图放大缩小的效果,该方法传入两个参数
duration(持续时间):这是动画的持续时间,以秒为单位。它指定了从动画开始到动画结束所经过的时间。在指定的持续时间内,UIKit 框架会根据动画块中的属性更改逐渐过渡到新的属性值。
animations(动画块):使用代码块更视图属性。在这个代码块中,可以修改视图的位置、大小、透明度等属性,UIKit 框架会在指定的持续时间内,根据动画块中的属性更改逐渐过渡到新的属性值。
#import "ViewController.h" #import "SuperView.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. //创建父视图 SuperView *sView = [[SuperView alloc] init]; sView.frame = CGRectMake(20, 50, 180, 280); sView.backgroundColor = [UIColor orangeColor]; //将父视图添加到主视图中 [self.view addSubview:sView]; //创建两个按钮控制放大缩小 UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = CGRectMake(240, 580, 80, 40); [btn setTitle:@"放大" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(pressLarge) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; UIButton *btn02 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn02.frame = CGRectMake(240, 620, 80, 40); [btn02 setTitle:@"缩小" forState:UIControlStateNormal]; [btn02 addTarget:self action:@selector(pressSmall) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn02]; sView.tag = 101; [sView creatSubViews]; } - (void) pressLarge { //放大父亲视图动画 SuperView *sView = (SuperView*)[self.view viewWithTag: 101]; [UIView animateWithDuration:1.0 animations:^{ sView.frame = CGRectMake(20, 50, 300, 480); }]; } //缩小父亲视图 - (void) pressSmall { SuperView *sView = (SuperView*)[self.view viewWithTag: 101]; [UIView animateWithDuration: 1.0 animations: ^{ sView.frame = CGRectMake(20, 50, 180, 280); }]; } @end
然后在父视图中接口文件中定义四个子视图属性,和创建子视图的方法。
//superView.h文件
#import <UIKit/UIKit.h>
@interface SuperView : UIView
{
UIView *_view01;
UIView *_view02;
UIView *_view03;
UIView *_view04;
}
-(void) creatSubViews;
@end
然后我们在实现文件中创建这四个子视图,并且手动布局子视图随着父视图的变化而改变。
注意的是,从iOS13.0起,弃用了beginAnimations: context:的方法,而改用基于代码块的动画实现这一功能。但是两者依旧都能运行,此处给出了两种方法的代码。我们还运用了-(void) layoutSubviews
方法:
#import "SuperView.h" @implementation SuperView -(void) creatSubViews { _view01 = [[UIView alloc] init]; _view01.frame = CGRectMake(0, 0, 40, 40); _view02 = [[UIView alloc] init]; _view02.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40); _view03 = [[UIView alloc] init]; _view03.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height-40, 40, 40); _view04 = [[UIView alloc] init]; _view04.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40); _view01.backgroundColor = [UIColor blueColor]; _view02.backgroundColor = [UIColor blueColor]; _view03.backgroundColor = [UIColor blueColor]; _view04.backgroundColor = [UIColor blueColor]; [self addSubview:_view01]; [self addSubview:_view02]; [self addSubview:_view03]; [self addSubview:_view04]; } //当需要重新布局时调用此函数 //通过次函数重新设定子视图的位置 //手动调整子视图的位置 -(void) layoutSubviews { // [UIView beginAnimations:nil context:nil]; // [UIView setAnimationDuration:1]; // _view01.frame = CGRectMake(0, 0, 40, 40); // _view02.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40); // _view03.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height-40, 40, 40); // _view04.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40); // //新版 [UIView animateWithDuration: 1.0 animations:^ { self->_view01.frame = CGRectMake(0, 0, 40, 40); self->_view02.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40); self->_view03.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40); self->_view04.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40); }]; } @end
效果(放大前):
放大后:
手动布局子视图需要我们自己手动调整子视图的原点位置,我们还可以自动控制子视图对齐。
需要注意:我们在viewController视图控制器中创建四个UILabel控件子视图,便于区别。
首先,我们在接口部分定义属性
#import <UIKit/UIKit.h> @interface ViewController : UIViewController { //创建父亲视图对象 UIView *superView; //创建四个标签 UILabel *label1; UILabel *label2; UILabel *label3; UILabel *label4; UIView *viewCenter; } @end
在实现部分中,我们首先创建接口部分中的六个视图。
再通过- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
方法,使用一个局部布尔变量储存当前屏幕状态,实现点击改变父视图大小。
再通过修改View的autoresizingMask自动调整布局属性,实现自动布局子视图。
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. superView = [[UIView alloc] init]; superView.frame = CGRectMake(20, 20, 180, 280); superView.backgroundColor = [UIColor blueColor]; label1 = [[UILabel alloc] init]; label1.text = @"1"; label1.frame = CGRectMake(0, 0, 40, 40); label1.backgroundColor = [UIColor greenColor]; label2 = [[UILabel alloc] init]; label2.frame = CGRectMake(180 - 40, 0, 40, 40); label2.text = @"2"; label2.backgroundColor = [UIColor greenColor]; label3 = [[UILabel alloc] init]; label3.frame = CGRectMake(180-40, 280-40, 40, 40); label3.text = @"3"; label3.backgroundColor = [UIColor greenColor]; label4 = [[UILabel alloc] init]; label4.frame = CGRectMake(0, 280-40, 40, 40); label4.text = @"4"; label4.backgroundColor = [UIColor greenColor]; [superView addSubview:label1]; [superView addSubview:label2]; [superView addSubview:label3]; [superView addSubview:label4]; [self.view addSubview:superView]; viewCenter = [[UIView alloc] init]; viewCenter.frame = CGRectMake(0, 0, superView.bounds.size.width, 40); viewCenter.center = CGPointMake(180/2, 280/2); viewCenter.backgroundColor = [UIColor orangeColor]; [superView addSubview:viewCenter]; //自动布局属性设置,通过此变量来调整视图再父亲视图中的位置和大小 //视图距离父亲视图的左侧是可以变化的 label2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; label4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; //左上可变,则实现移动到右下角 label3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; //上下都可变,即可实现居中效果 viewCenter.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin; //语句会覆盖 //viewCenter.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; } - (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //用一个局部变量来区分视图的大小的状态 static BOOL isLarge = NO; //设置动画效果 [UIView animateWithDuration: 1.0 animations:^{ if (isLarge == NO) { self->superView.frame = CGRectMake(10, 10, 350, 580); } else { self->superView.frame = CGRectMake(20, 20, 180, 280); } isLarge = !isLarge; }]; } @end
效果(放大前):
放大后:
我们以一个问题来总结:为什么手动布局子视图在父视图的文件中创建子视图,而自动布局子视图在视图控制器中创建子视图呢?
这两种不同的布局方式,在视图的管理和实现上也有不同。因此他们的位置是不同的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。