美文网首页
关于拆分View层的一种优化实战

关于拆分View层的一种优化实战

作者: 键狂2017 | 来源:发表于2019-12-22 22:32 被阅读0次

今天给大家提供一种在iOS开发中View层的一种优化思路。

在iOS开发中,不管你是用纯代码布局,还是用Storyboard布局,都免不了在Controller中加入一些界面相关的逻辑,随着业务逻辑复杂度的增加,Controller里的代码会越来越多,不方便阅读,还不方便维护,这时候除了把一些业务逻辑分出去之外,还可以把界面相关的代码优化一把。

优化主要借助Controller中的loadView来实现,对于这个方法,官方文档里描述的很清楚,这里不再过多描述。我们主要是在loadView中把我们自己定义的View赋给Controller的view属性,然后把所有界面相关的代码都在我们自己定义的View中去管理。

画板.png

这里我使用App的登录注册功能做简单分析,界面如上图所示,图一是登录界面,图二是注册界面,其中图一的布局是用Storyoard做的,图二是用纯代码配合Masonry写的,先说图二纯代码写的吧,首先我们需要写一个RegistView,相关代码如下:

@interface RegistView : UIView

@property (nonatomic, strong) UITextField *userNameTextField;
@property (nonatomic, strong) UITextField *userPswdTextField;
@property (nonatomic, strong) UITextField *againPswdTextField;
@property (nonatomic, strong) UIButton *registButton;

@property (nonatomic, copy) void (^registCallBack)(NSString *, NSString *, NSString *);

@end

@implementation RegistView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self loadSubviews];
    }
    return self;
}

- (void)loadSubviews {
    self.backgroundColor = [UIColor whiteColor];
    [self addSubview:self.userNameTextField];
    [self addSubview:self.userPswdTextField];
    [self addSubview:self.againPswdTextField];
    [self addSubview:self.registButton];
    
    [self.userNameTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.mas_left).offset(58);
        make.right.equalTo(self.mas_right).offset(-58);
        make.top.equalTo(self.mas_safeAreaLayoutGuideTop).offset(49);
        make.height.mas_equalTo(34);
    }];
    
    [self.userPswdTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.userNameTextField);
        make.top.equalTo(self.userNameTextField.mas_bottom).offset(22);
        make.height.mas_equalTo(34);
    }];
    
    [self.againPswdTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.userNameTextField);
        make.top.equalTo(self.userPswdTextField.mas_bottom).offset(22);
        make.height.mas_equalTo(34);
    }];
    
    [self.registButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.userNameTextField);
        make.top.equalTo(self.againPswdTextField.mas_bottom).offset(22);
        make.height.mas_equalTo(50);
    }];
}

#pragma mark - Action

- (void)registAction {
    if (self.registCallBack) {
        self.registCallBack(self.userNameTextField.text, self.userPswdTextField.text, self.againPswdTextField.text);
    }
}

#pragma mark - Get

- (UITextField *)userNameTextField {
    if (!_userNameTextField) {
        _userNameTextField = [UITextField new];
        _userNameTextField.borderStyle = UITextBorderStyleRoundedRect;
        _userNameTextField.placeholder = @"点击输入用户名";
    }
    return _userNameTextField;
}

- (UITextField *)userPswdTextField {
    if (!_userPswdTextField) {
        _userPswdTextField = [UITextField new];
        _userPswdTextField.borderStyle = UITextBorderStyleRoundedRect;
        _userPswdTextField.placeholder = @"点击输入密码";
        _userPswdTextField.secureTextEntry = YES;
    }
    return _userPswdTextField;
}

- (UITextField *)againPswdTextField {
    if (!_againPswdTextField) {
        _againPswdTextField = [UITextField new];
        _againPswdTextField.borderStyle = UITextBorderStyleRoundedRect;
        _againPswdTextField.placeholder = @"点击再次输入密码";
        _againPswdTextField.secureTextEntry = YES;
    }
    return _againPswdTextField;
}

- (UIButton *)registButton {
    if (!_registButton) {
        _registButton = [UIButton buttonWithType:UIButtonTypeSystem];
        [_registButton setTitle:@"注册" forState:UIControlStateNormal];
        [_registButton addTarget:self action:@selector(registAction) forControlEvents:UIControlEventTouchUpInside];
        
    }
    return _registButton;
}

其次是在Controller里面loadView方法里面给view属性赋值,代码如下:

@interface RegistViewController ()

@property (nonatomic, strong) RegistView *mainView;

@end

@implementation RegistViewController

- (void)loadView {
    self.mainView = [[RegistView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.view = self.mainView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self configViews];
}

- (void)dealloc {
    NSLog(@"%s", __func__);
}

#pragma mark -

- (void)configViews {
    self.title = @"注册";
    __weak typeof(self) weakSelf = self;
    self.mainView.registCallBack = ^(NSString * _Nonnull userName, NSString * _Nonnull userPswd, NSString * _Nonnull userAgainPswd) {
        if (nil != weakSelf) {
            
        }
        NSLog(@"%@ %@ %@", userName, userPswd, userAgainPswd);
    };
}


@end

这样我们就顺利的把Controller里面对关于View的东西都优雅的拿出来了。

如果你是Storyboard爱好者,同样的也有办法去处理,以图一为例,首先我们要在Storyboard里面完成LoginView的布局,如图: WX20191222-161005@2x.png

其中我们把Storyboard中Controller的view关联到了我们本地创建的LoginView上,对相应的一些空间也做了关联,相关代码如下:


@interface LoginView : UIView
@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *userPswdTextField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@property (weak, nonatomic) IBOutlet UIButton *registButton;


@end

@implementation LoginView

-(void)awakeFromNib {
    [super awakeFromNib];
    NSLog(@"%s", __func__);
    // TODO: 操作一些样式相关、状态相关的
}
@end

而在Controller里面我们需要对view做一个类型转换,然后才能使用,相关代码如下:

@interface LoginViewController ()

@property (nonatomic, weak) LoginView *mainView;

@end

@implementation LoginViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"登录";
}

#pragma mark - Action

- (IBAction)loginAction:(id)sender {
    NSString *userName = self.mainView.userNameTextField.text;
    NSString *userPswd = self.mainView.userPswdTextField.text;
    
    NSLog(@"%@ %@", userName, userPswd);
    
    // TODO: 处理登录的逻辑
}

- (IBAction)registAction:(id)sender {
    RegistViewController *vc = [RegistViewController new];
    [self.navigationController pushViewController:vc animated:YES];
}


#pragma mark - View

- (LoginView *)mainView {
    return (LoginView *)self.view;
}


@end

这样,我们就优雅的完成了对View层的拆分。点击下载demo

如果大家有什么问题,或者发现了有什么不对的地方,再或者有更好的方法,欢迎留言。

相关文章

网友评论

      本文标题:关于拆分View层的一种优化实战

      本文链接:https://www.haomeiwen.com/subject/uhjanctx.html