UIView和UIViewController的区别

382 阅读2分钟

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**