// // YMVerifyCodeLoginView.m // MSYOUPAI // // Created by YoMi on 2024/2/4. // Copyright © 2024 MS. All rights reserved. // #import "YMVerifyCodeLoginView.h" #import "YMVerifyCodeLoginViewModel.h" #import "YMCaptchaPopupView.h" #import "CaptchaCenter.h" @interface YMVerifyCodeLoginView () /// 验证码登录VM @property (nonatomic, strong) YMVerifyCodeLoginViewModel *viewModel; /// 手机视图 @property (nonatomic, strong) UIView *mobileView; /// 手机号标签 @property (nonatomic, strong) UILabel *mobileLb; /// 手机号输入框 @property (nonatomic, strong) UITextField *mobileInputBox; /// 验证码视图 @property (nonatomic, strong) UIView *verifyCodeView; /// 验证码标签 @property (nonatomic, strong) UILabel *verifyCodeLb; /// 验证码输入框 @property (nonatomic, strong) UITextField *verifyCodeInputBox; /// 获取验证码 @property (nonatomic, strong) YMCaptchaCountdownButton *getVerifyCodeBtn; /// 协议视图 @property (nonatomic, strong) UIView *agreementView; /// 单选按钮 @property (nonatomic, strong) UIButton *radioBtn; /// 协议标签 @property (nonatomic, strong) YYLabel *agreementLb; /// 登录按钮 @property (nonatomic, strong) UIButton *loginBtn; /** 注册按钮*/ @property (nonatomic, strong) UIButton *registerBtn; @end @implementation YMVerifyCodeLoginView - (void)ym_setupViews{ [self addSubview:self.mobileView]; [self.mobileView addSubview:self.mobileLb]; [self.mobileView addSubview:self.mobileInputBox]; [self addSubview:self.verifyCodeView]; [self.verifyCodeView addSubview:self.verifyCodeLb]; [self.verifyCodeView addSubview:self.verifyCodeInputBox]; [self.verifyCodeView addSubview:self.getVerifyCodeBtn]; [self addSubview:self.agreementView]; [self.agreementView addSubview:self.radioBtn]; [self.agreementView addSubview:self.agreementLb]; [self addSubview:self.loginBtn]; [self addSubview:self.registerBtn]; [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; } - (void)updateConstraints{ [self.mobileView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self).offset(adapt(24)); make.left.equalTo(self).offset(adapt(28)); make.right.equalTo(self).offset(adapt(-28)); }]; [self.mobileLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileView); make.left.equalTo(self.mobileView); }]; [self.mobileInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.mobileView); make.right.equalTo(self.mobileView); make.bottom.equalTo(self.mobileView); make.height.mas_equalTo(adapt(30)); }]; [self.verifyCodeView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileView.mas_bottom).offset(adapt(24)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); }]; [self.verifyCodeLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeView); make.left.equalTo(self.verifyCodeView); }]; [self.verifyCodeInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.verifyCodeView); make.bottom.equalTo(self.verifyCodeView); make.height.mas_equalTo(adapt(30)); }]; [self.getVerifyCodeBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.verifyCodeInputBox.mas_right).offset(adapt(5)); make.right.equalTo(self.verifyCodeView); make.bottom.equalTo(self.verifyCodeView); make.width.mas_equalTo(adapt(100)); }]; [self.loginBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeView.mas_bottom).offset(adapt(24)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); make.height.mas_equalTo(adapt(40)); }]; [self.registerBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.loginBtn.mas_centerX); make.top.equalTo(self.loginBtn.mas_bottom).offset(adapt(16)); make.height.mas_equalTo(adapt(25)); }]; [self.agreementView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.mas_centerX); make.bottom.equalTo(self).offset(Is_iPhoneX ? adapt(-32) : adapt(-12)); }]; [self.radioBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.agreementLb.mas_centerY); make.left.equalTo(self.agreementView).offset(adapt(5)); make.width.height.mas_equalTo(adapt(12)); }]; [self.agreementLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.agreementView).offset(adapt(10)); make.left.equalTo(self.radioBtn.mas_right).offset(adapt(5)); make.right.equalTo(self.agreementView).offset(adapt(-5)); make.bottom.equalTo(self.agreementView).offset(adapt(-10)); }]; [super updateConstraints]; } - (void)ym_bindViewModel:(YMVerifyCodeLoginViewModel *)viewModel{ if (!viewModel) { return; } _viewModel = viewModel; RAC(self.viewModel , mobile) = [[RACSignal merge:@[RACObserve(self.mobileInputBox, text),self.mobileInputBox.rac_textSignal]] takeUntil:self.rac_willDeallocSignal]; RAC(self.viewModel , verifyCode) = [[RACSignal merge:@[RACObserve(self.verifyCodeInputBox, text),self.verifyCodeInputBox.rac_textSignal]]takeUntil:self.rac_willDeallocSignal]; RAC(self.loginBtn , enabled) = self.viewModel.validLoginSignal; [self.viewModel.validLoginSignal subscribeNext:^(id _Nullable value) { self.loginBtn.enabled = [value boolValue]; if ([value boolValue]) { self.loginBtn.alpha = 1; } else { self.loginBtn.alpha = 0.5; } }]; } - (UIView *)mobileView{ if (!_mobileView) { _mobileView = [[UIView alloc]init]; } return _mobileView; } - (UILabel *)mobileLb{ if (!_mobileLb) { _mobileLb = [[UILabel alloc]init]; _mobileLb.font = LCBoldFont(17); _mobileLb.textColor = HexColorFromRGB(0x1B2739); _mobileLb.textAlignment = NSTextAlignmentLeft; _mobileLb.text = @"手机号"; } return _mobileLb; } - (UITextField *)mobileInputBox{ if (!_mobileInputBox) { NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; style.minimumLineHeight = 0; NSMutableAttributedString *placeholderAttributed = [[NSMutableAttributedString alloc]initWithString:@"请输入手机号"]; placeholderAttributed.yy_paragraphStyle = style; placeholderAttributed.yy_font = LCFont(14); placeholderAttributed.yy_color = HexColorFromRGB(0xADB0BC); _mobileInputBox = [[UITextField alloc]init]; _mobileInputBox.attributedPlaceholder = placeholderAttributed; _mobileInputBox.clearButtonMode = UITextFieldViewModeWhileEditing; _mobileInputBox.autocorrectionType = UITextAutocorrectionTypeDefault; _mobileInputBox.autocapitalizationType = UITextAutocapitalizationTypeNone; _mobileInputBox.keyboardType = UIKeyboardTypePhonePad; _mobileInputBox.ba_maxLength = 11; } return _mobileInputBox; } - (UIView *)verifyCodeView{ if (!_verifyCodeView) { _verifyCodeView = [[UIView alloc]init]; } return _verifyCodeView; } - (UILabel *)verifyCodeLb{ if (!_verifyCodeLb) { _verifyCodeLb = [[UILabel alloc]init]; _verifyCodeLb.font = LCBoldFont(17); _verifyCodeLb.textColor = HexColorFromRGB(0x1B2739); _verifyCodeLb.textAlignment = NSTextAlignmentLeft; _verifyCodeLb.text = @"验证码"; } return _verifyCodeLb; } - (UITextField *)verifyCodeInputBox{ if (!_verifyCodeInputBox) { NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; style.minimumLineHeight = 0; NSMutableAttributedString *placeholderAttributed = [[NSMutableAttributedString alloc]initWithString:@"请输入验证码"]; placeholderAttributed.yy_paragraphStyle = style; placeholderAttributed.yy_font = LCFont(14); placeholderAttributed.yy_color = HexColorFromRGB(0xADB0BC); _verifyCodeInputBox = [[UITextField alloc]init]; _verifyCodeInputBox.attributedPlaceholder = placeholderAttributed; _verifyCodeInputBox.clearButtonMode = UITextFieldViewModeWhileEditing; _verifyCodeInputBox.autocorrectionType = UITextAutocorrectionTypeDefault; _verifyCodeInputBox.autocapitalizationType = UITextAutocapitalizationTypeNone; _verifyCodeInputBox.keyboardType = UIKeyboardTypeDecimalPad; _verifyCodeInputBox.ba_maxLength = 4; } return _verifyCodeInputBox; } - (YMCaptchaCountdownButton *)getVerifyCodeBtn{ if (!_getVerifyCodeBtn) { _getVerifyCodeBtn = [YMCaptchaCountdownButton buttonWithType:UIButtonTypeCustom]; _getVerifyCodeBtn.titleLabel.font = LCFont(14); [_getVerifyCodeBtn setTitleColor:HexColorFromRGB(0xB26AFD) forState:UIControlStateNormal]; [_getVerifyCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal]; @weakify(self) [_getVerifyCodeBtn countDownButtonHandler:^(YMCaptchaCountdownButton *sender, NSInteger tag) { @strongify(self) if (OCStringIsEmpty(self.mobileInputBox.text)) { [ZCHUDHelper showTitle:@"请输入手机号"]; return; } [self.mobileInputBox resignFirstResponder]; [self.verifyCodeInputBox resignFirstResponder]; [self.verifyCodeInputBox resignFirstResponder]; [CaptchaCenter.defaultCenter getCaptchaType:^(NSNumber * _Nullable type, NSError * _Nullable error) { if (error) { [ZCHUDHelper showTitle:@"获取验证码失败"]; return; } if ([type isEqualToNumber:@1]) { // 原生 YMCaptchaPopupView *view = [[YMCaptchaPopupView alloc] init]; view.cancelButtonTappedBlock = ^{}; @weakify(self) view.confirmButtonTappedBlock = ^(NSString * _Nonnull input) { @strongify(self) [self getVerifyCodeWithCapthca:input sender:sender]; }; UIView *currentVCView = [LCTools getCurrentVC].view; if (currentVCView != nil && ![currentVCView isEqual:NSNull.null]) { [view showInView:currentVCView]; } } else { // 阿里 @weakify(self) [CaptchaCenter.defaultCenter verifyCompletion:^(NSString * _Nonnull status, NSDictionary * _Nonnull result) { @strongify(self) [self getVerifyCodeWithCapthca:result sender:sender]; }]; } }]; }]; } return _getVerifyCodeBtn; } - (void)getVerifyCodeWithCapthca:(id)capthca sender:(YMCaptchaCountdownButton *)sender { //@weakify(self) [self.viewModel getVerifyCodeWithCaptcha:capthca Handler:^(NSDictionary * _Nonnull dic, NSError * _Nullable error) { //@strongify(self) sender.enabled = NO; [sender startCountDownWithSecond:59]; [sender countDownChanging:^NSString *(YMCaptchaCountdownButton *countDownButton, NSUInteger second) { NSString *title = [NSString stringWithFormat:@"重新发送(%zds)",second]; return title; }]; [sender countDownFinished:^NSString *(YMCaptchaCountdownButton *countDownButton, NSUInteger second) { countDownButton.enabled = YES; return @"重新发送"; }]; }]; } - (UIView *)agreementView{ if (!_agreementView) { _agreementView = [[UIView alloc]init]; } return _agreementView; } - (UIButton *)radioBtn{ if (!_radioBtn) { _radioBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_radioBtn setBackgroundImage:ImageByName(@"ym_login_auth_normal_icon") forState:UIControlStateNormal]; [_radioBtn setBackgroundImage:ImageByName(@"ym_login_auth_selected_icon") forState:UIControlStateSelected]; WS(weakSelf) [[[_radioBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { sender.selected = !sender.selected; }]; } return _radioBtn; } - (YYLabel *)agreementLb{ if (!_agreementLb) { _agreementLb = [[YYLabel alloc] init]; _agreementLb.numberOfLines = 0; _agreementLb.preferredMaxLayoutWidth = kFrameWidth - adapt(55); NSString *agreementText = @"同意《用户协议》和《隐私协议》"; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init]; paragraphStyle.alignment = NSTextAlignmentLeft; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:agreementText]; attributedString.yy_font = LCFont(11); attributedString.yy_color = HexColorFromRGB(0x7E848D); attributedString.yy_paragraphStyle = paragraphStyle; //设置高亮色和点击事件 [attributedString yy_setTextHighlightRange:[agreementText rangeOfString:@"《用户协议》"] color:HexColorFromRGB(0xB26AFD) backgroundColor:[UIColor clearColor] tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { YMWebArticleViewModel *webArticleVM = [[YMWebArticleViewModel alloc]initWithParams:@{ ParamsUrl:[NSString stringWithFormat:@"%@%@",[LCSaveData getBaseURL]?[LCSaveData getBaseURL]:BaseURL,UserProtocolH5] }]; [YMRouter openURL:stringFormat(@"%@%@", YM_ROUTER_URL_PREFIX, YM_ROUTER_WEB_ARTICLE) withUserInfo:@{ RouterViewModel:webArticleVM } completion:nil]; }]; //设置高亮色和点击事件 [attributedString yy_setTextHighlightRange:[[attributedString string] rangeOfString:@"《隐私协议》"] color:HexColorFromRGB(0xB26AFD) backgroundColor:[UIColor clearColor] tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { YMWebArticleViewModel *webArticleVM = [[YMWebArticleViewModel alloc]initWithParams:@{ ParamsUrl:[NSString stringWithFormat:@"%@%@",[LCSaveData getBaseURL]?[LCSaveData getBaseURL]:BaseURL,UserPrivacyH5] }]; [YMRouter openURL:stringFormat(@"%@%@", YM_ROUTER_URL_PREFIX, YM_ROUTER_WEB_ARTICLE) withUserInfo:@{ RouterViewModel:webArticleVM } completion:nil]; }]; _agreementLb.attributedText = attributedString; } return _agreementLb; } - (UIButton *)loginBtn{ if (!_loginBtn) { _loginBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _loginBtn.titleLabel.font = LCBoldFont(15); [_loginBtn setTitle:@"登录" forState:UIControlStateNormal]; [_loginBtn setTitleColor:kMainGradTitleC forState:UIControlStateNormal]; [_loginBtn ym_setGradientBackgroundWithColors:kMainGradColors locations:kMainGradLocation startPoint:kMainGradStartP endPoint:kMainGradEndP]; _loginBtn.layer.cornerRadius = adapt(40)/2; WS(weakSelf) [[[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { if (OCStringIsEmpty(weakSelf.mobileInputBox.text)) { [ZCHUDHelper showTitle:@"请输入手机号"]; return; } if (OCStringIsEmpty(weakSelf.verifyCodeInputBox.text)) { [ZCHUDHelper showTitle:@"请输入验证码"]; return; } if (!weakSelf.radioBtn.selected) { YMLoginRegistrAgreementPopupView *customView = [[YMLoginRegistrAgreementPopupView alloc]init]; YMPopupView *popupView = [YMPopupView initWithCustomView:customView parentView:nil popStyle:YMPopupStyleFade dismissStyle:YMDismissStyleFade]; popupView.priority = 999; popupView.cornerRadius = adapt(10); popupView.rectCorners = UIRectCornerAllCorners; popupView.positionStyle = YMPositionStyleCenter; popupView.isHideBg = NO; popupView.bgAlpha = 0.3; [popupView pop]; @weakify(popupView) customView.buttonBlock = ^(BOOL isConfirm) { @strongify(popupView) if (isConfirm) { weakSelf.radioBtn.selected = YES; [weakSelf.viewModel loginRequest]; } [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; customView.dismissBlock = ^{ @strongify(popupView) [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; return; } [weakSelf.viewModel loginRequest]; }]; } return _loginBtn; } - (UIButton *)registerBtn{ if (!_registerBtn) { _registerBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _registerBtn.titleLabel.font = LCFont(14); [_registerBtn setTitle:@"新用户注册" forState:UIControlStateNormal]; [_registerBtn setTitleColor:HexColorFromRGB(0xB26AFD) forState:UIControlStateNormal]; WS(weakSelf) [[[_registerBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { [weakSelf.viewModel gotoRegisterVC]; }]; } return _registerBtn; } @end