UIView和UIViewController都能实现对视图的定义和状态逻辑的管理,它们有什么区别?
结论:UIViewController用来管理页面的生命周期、业务逻辑、和页面的子视图。 UIView相当于一个盒子,用来自定义UI组件,和管理UI组件的状态(组件的大小、颜色、位置等),不推荐用来管理业务逻辑。
UIView和UIViewController的功能
UIView是所有视图的基础类,负责绘制界面元素处理用户交互。可以理解成Web中的div+ js控制逻辑,或者Flutter中的Container+状态管理
UIView中管理的状态,通常是视图自身的属性,比如颜色、透明的、尺寸、位置等。
不要直接把业务逻辑或者应用程序级别的状态变化放在UIView中处理, 比如网络请求的结果、用户输入验证等。
UIViewController 是用来管理视图的控制器类,可以理解成一个页面的框架+Controller, 管理界面的生命周期、视图、业务逻辑等。相当于MVC模式中的VC。
每个UIViewController都管理着一个根视图self.view,可以拥有多个子视图。
不仅负责界面的现实,还负责界面的导航、数据传递、声明周期管理(如 viewDidLoad, viewWillAppear 等方法)以及协调不同视图之间的交互。
在UIViewController处理业务逻辑,比如处理用户输入、调用网络服务、更新视图等。
UIView示例代码
//定义 block 类型
//typedef 返回值(^闭包名称)(闭包入参)
**typedef** **void** (^Demo02ViewClickBlock)(**void**);
**@interface** Demo02View : UIView
**@property**(**nonatomic**, **strong**) NSString* title;
**@property**(**nonatomic**, **copy**) Demo02ViewClickBlock onTap; //点击回调
-(**instancetype**)initWithTitle:(NSString*)title;
**@end**
**@implementation** Demo02View {
UILabel *titleLabel;
}
-(**instancetype**)initWithTitle:(NSString*)title {
**self** = [**super** init];
**if** (**self**) {
**self**.title = title;
[**self** _buildViews];
}
**return** **self**;
}
-(**void**)_buildViews {
[**self** setUpTapGesture];
titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 50)];
titleLabel.text = **self**.title;
titleLabel.textColor = [UIColor yellowColor];
titleLabel.backgroundColor = [UIColor blackColor];
titleLabel.textAlignment = NSTextAlignmentCenter;
[**self** addSubview:titleLabel];
}
//确保设置了frame后居中显示
- (**void**)layoutSubviews {
[**super** layoutSubviews];
CGFloat labelWidth = 100;
CGFloat labelHeight = 50;
titleLabel.frame = CGRectMake((**self**.bounds.size.width - labelWidth) / 2,
(**self**.bounds.size.height - labelHeight) / 2,
labelWidth,
labelHeight);
}
// 👇 关键点:重写 setTitle: 方法,更新 label 内容
- (**void**)setTitle:(NSString *)title {
_title = title;
**if** (titleLabel) {
titleLabel.text = title;
}
}
-(**void**)setUpTapGesture {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:**self** action: **@selector**(handleTap)];
tap.numberOfTapsRequired = 1;
[**self** addGestureRecognizer:tap];
}
-(**void**)handleTap {
**if** (**self**.onTap) {
**self**.onTap();
}
}
**@end**
UIViewController示例代码
**@interface** Demo02ViewController : UIViewController
**@end**
#import "Demo02ViewController.h"
#import "Demo02View.h"
**@interface** Demo02ViewController ()
**@property**(**nonatomic**, **assign**) NSInteger count;
**@property**(**nonatomic**, **strong**) Demo02View *demo02View;
**@end**
**@implementation** Demo02ViewController
- (**void**)viewDidLoad {
[**super** viewDidLoad];
[**self** _buildViews];
}
- (**void**)_buildViews {
**self**.navigationItem.title = @"UIView和UIViewController的区别";
**self**.view.backgroundColor = [UIColor blueColor];
_demo02View = [[Demo02View alloc] initWithTitle:@"UIView"];
_demo02View.frame = CGRectMake(0, 0, 100, 100);
_demo02View.center = **self**.view.center;
_demo02View.backgroundColor = [UIColor redColor];
[**self**.view addSubview:_demo02View];
**__weak** **typeof**(**self**) weakSelf = **self**;
_demo02View.onTap = ^{
**typeof**(**self**) strongSelf = weakSelf;
**if** (!strongSelf) **return**;
strongSelf.count++;
// 安全获取当前标题
NSString *currentTitle = @"UIView";
strongSelf.demo02View.title = [NSString stringWithFormat:@"%@: %ld", currentTitle, strongSelf.count];
};
}
**@end**