// // YMPasswordLoginView.m // MSYOUPAI // // Created by YoMi on 2024/2/4. // Copyright © 2024 MS. All rights reserved. // #import "YMPasswordLoginView.h" #import "YMPasswordLoginViewModel.h" @interface YMPasswordLoginView () /// 密码登录VM @property (nonatomic, strong) YMPasswordLoginViewModel *viewModel; @property (nonatomic, strong) UIView *topView; @property (nonatomic, strong) UILabel *topLb1; @property (nonatomic, strong) UILabel *topLb2; @property (nonatomic, strong) UIImageView *bgImgv; /// 手机视图 @property (nonatomic, strong) UIView *mobileView; /// 手机号标签 @property (nonatomic, strong) UILabel *mobileLb; /// 手机号输入框 @property (nonatomic, strong) UITextField *mobileInputBox; /// 密码视图 @property (nonatomic, strong) UIView *passwordView; /// 密码标签 @property (nonatomic, strong) UILabel *passwordLb; /// 密码输入框 @property (nonatomic, strong) UITextField *passwordInputBox; @property (nonatomic, strong) UIView *lineView1; @property (nonatomic, strong) UIView *lineView2; /// 登录按钮 @property (nonatomic, strong) UIButton *loginBtn; /** 忘记密码按钮*/ @property (nonatomic, strong) UIButton *forgotPasswordBtn; /** 注册按钮*/ @property (nonatomic, strong) UIButton *registerBtn; /** 登录方式堆叠视图*/ @property (nonatomic, strong) UIStackView *loginMethodStackView; /// 微信登录按钮 @property (nonatomic, strong) UIButton *wechatLoginBtn; /// 协议视图 @property (nonatomic, strong) UIView *agreementView; /// 单选按钮 @property (nonatomic, strong) UIButton *radioBtn; /// 协议标签 @property (nonatomic, strong) YYLabel *agreementLb; @end @implementation YMPasswordLoginView - (void)ym_setupViews{ [self addSubview:self.bgImgv]; [self addSubview:self.topView]; [self.topView addSubview:self.topLb1]; [self.topView addSubview:self.topLb2]; [self addSubview:self.mobileView]; [self.mobileView addSubview:self.mobileLb]; [self.mobileView addSubview:self.mobileInputBox]; [self.mobileView addSubview:self.lineView1]; [self addSubview:self.passwordView]; [self.passwordView addSubview:self.passwordLb]; [self.passwordView addSubview:self.passwordInputBox]; [self.passwordView addSubview:self.lineView2]; [self addSubview:self.loginBtn]; [self addSubview:self.forgotPasswordBtn]; [self addSubview:self.registerBtn]; [self addSubview:self.loginMethodStackView]; [self.loginMethodStackView addArrangedSubview:self.wechatLoginBtn]; [self addSubview:self.agreementView]; [self.agreementView addSubview:self.radioBtn]; [self.agreementView addSubview:self.agreementLb]; [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; } - (void)updateConstraints{ [self.bgImgv mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.right.equalTo(self); make.height.mas_equalTo(adapt(330)); }]; [self.topView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self).offset(adapt(30)); make.left.equalTo(self).offset(adapt(30)); make.right.equalTo(self).offset(adapt(-30)); make.height.mas_equalTo(adapt(85)); }]; [self.topLb1 mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.topView); make.left.equalTo(self.topView); make.right.equalTo(self.topView); }]; [self.topLb2 mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.topLb1.mas_bottom).offset(5); make.left.equalTo(self.topView); make.right.equalTo(self.topView); }]; [self.mobileView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.topView.mas_bottom); make.left.equalTo(self).offset(adapt(30)); make.right.equalTo(self).offset(adapt(-30)); make.height.mas_equalTo(adapt(55)); }]; [self.mobileLb mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.mobileView); make.left.equalTo(self.mobileView); make.width.mas_equalTo(adapt(65)); }]; [self.mobileInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileView); make.left.equalTo(self.mobileLb.mas_right).offset(adapt(10)); make.right.equalTo(self.mobileView); make.bottom.equalTo(self.mobileView); //make.height.mas_equalTo(adapt(30)); }]; [self.lineView1 mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.mobileView); make.left.equalTo(self.mobileLb.mas_right); make.height.mas_equalTo(adapt(34)); make.width.mas_equalTo(1); }]; [self.passwordView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileView.mas_bottom).offset(adapt(16)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); make.height.mas_equalTo(adapt(55)); }]; [self.passwordLb mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.passwordView); make.left.equalTo(self.passwordView); make.width.mas_equalTo(adapt(65)); }]; [self.passwordInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.passwordView); make.left.equalTo(self.passwordLb.mas_right).offset(adapt(10)); make.right.equalTo(self.passwordView); make.bottom.equalTo(self.passwordView); //make.height.mas_equalTo(adapt(30)); }]; [self.lineView2 mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.passwordView); make.left.equalTo(self.passwordLb.mas_right); make.height.mas_equalTo(adapt(34)); make.width.mas_equalTo(1); }]; [self.loginBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.passwordView.mas_bottom).offset(adapt(16)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); make.height.mas_equalTo(55); }]; [self.forgotPasswordBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.loginBtn.mas_bottom).offset(adapt(16)); make.left.equalTo(self.loginBtn.mas_left); make.height.mas_equalTo(adapt(25)); }]; [self.registerBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.loginBtn.mas_bottom).offset(adapt(16)); make.right.equalTo(self.loginBtn.mas_right); make.height.mas_equalTo(adapt(25)); }]; [self.loginMethodStackView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.mas_centerX); make.bottom.equalTo(self.agreementView.mas_top).offset(adapt(-10)); }]; [self.wechatLoginBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.height.mas_equalTo(53); make.bottom.equalTo(self.agreementView.mas_top).offset(adapt(-10)); }]; [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(17)); }]; [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:(YMPasswordLoginViewModel *)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 , password) = [[RACSignal merge:@[RACObserve(self.passwordInputBox, text),self.passwordInputBox.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; } }]; } - (UIImageView *)bgImgv { if (!_bgImgv) { _bgImgv = [[UIImageView alloc] initWithImage:ImageByName(@"ym_login_phone_bg")]; } return _bgImgv; } - (UIView *)mobileView{ if (!_mobileView) { _mobileView = [[UIView alloc]init]; _mobileView.backgroundColor = UIColor.whiteColor; [_mobileView addRectCorner:(UIRectCornerAllCorners) radius:adapt(55) / 2.0]; } return _mobileView; } - (UIView *)topView{ if (!_topView) { _topView = [[UIView alloc]init]; _topView.hidden = NO; } return _topView; } - (UILabel *)mobileLb{ if (!_mobileLb) { _mobileLb = [[UILabel alloc]init]; _mobileLb.font = LCBoldFont(16); _mobileLb.textColor = HexColorFromRGB(0x1B2739); _mobileLb.textAlignment = NSTextAlignmentCenter; _mobileLb.text = @"+86"; } return _mobileLb; } - (UILabel *)topLb1{ if (!_topLb1) { _topLb1 = [[UILabel alloc]init]; _topLb1.font = LCBoldFont(27); _topLb1.textColor = HexColorFromRGB(0xEE538F); _topLb1.textAlignment = NSTextAlignmentLeft; _topLb1.text = @"Hello!"; } return _topLb1; } - (UILabel *)topLb2{ if (!_topLb2) { _topLb2 = [[UILabel alloc]init]; _topLb2.font = LCBoldFont(17); _topLb2.textColor = HexColorFromRGB(0xEE538F); _topLb2.textAlignment = NSTextAlignmentLeft; _topLb2.text = @"你来啦~"; } return _topLb2; } - (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 *)passwordView{ if (!_passwordView) { _passwordView = [[UIView alloc]init]; _passwordView.backgroundColor = UIColor.whiteColor; [_passwordView addRectCorner:(UIRectCornerAllCorners) radius:adapt(55) / 2.0]; } return _passwordView; } - (UIView *)lineView1{ if (!_lineView1) { _lineView1 = [[UIView alloc]init]; _lineView1.backgroundColor = HexColorFromRGBA(0x7E868E,0.24); } return _lineView1; } - (UIView *)lineView2{ if (!_lineView2) { _lineView2 = [[UIView alloc]init]; _lineView2.backgroundColor = HexColorFromRGBA(0x7E868E,0.24); } return _lineView2; } - (UILabel *)passwordLb{ if (!_passwordLb) { _passwordLb = [[UILabel alloc]init]; _passwordLb.font = LCBoldFont(17); _passwordLb.textColor = HexColorFromRGB(0x1B2739); _passwordLb.textAlignment = NSTextAlignmentCenter; _passwordLb.text = @"密码"; } return _passwordLb; } - (UITextField *)passwordInputBox{ if (!_passwordInputBox) { 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); _passwordInputBox = [[UITextField alloc]init]; _passwordInputBox.attributedPlaceholder = placeholderAttributed; _passwordInputBox.clearButtonMode = UITextFieldViewModeWhileEditing; _passwordInputBox.autocorrectionType = UITextAutocorrectionTypeDefault; _passwordInputBox.autocapitalizationType = UITextAutocapitalizationTypeNone; _passwordInputBox.keyboardType = UIKeyboardTypeDefault; _passwordInputBox.secureTextEntry = YES; } return _passwordInputBox; } - (UIButton *)loginBtn{ if (!_loginBtn) { _loginBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _loginBtn.titleLabel.font = LCBoldFont(19); [_loginBtn setTitle:@"登录" forState:UIControlStateNormal]; [_loginBtn setTitleColor:MAINGRIDTitleC forState:UIControlStateNormal]; [_loginBtn ym_setGradientBackgroundWithColors:kMainGradColors locations:kMainGradLocation startPoint:kMainGradStartP endPoint:kMainGradEndP]; _loginBtn.layer.cornerRadius = adapt(55) / 2.0; _loginBtn.layer.masksToBounds = YES; 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.passwordInputBox.text)) { [ZCHUDHelper showTitle:@"请输入密码"]; return; } if (!weakSelf.radioBtn.selected) { YMLoginRegistrAgreementPopupView *customView = [[YMLoginRegistrAgreementPopupView alloc]init]; YMPopupView *popupView = [YMPopupView initWithCustomView:customView parentView:[YMGlobalUtils getCurrentVC].view 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 accountPasswordLoginRequest]; } [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; customView.dismissBlock = ^{ @strongify(popupView) [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; return; } [weakSelf.viewModel accountPasswordLoginRequest]; }]; } return _loginBtn; } - (UIButton *)forgotPasswordBtn{ if (!_forgotPasswordBtn) { _forgotPasswordBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _forgotPasswordBtn.titleLabel.font = LCFont(12); [_forgotPasswordBtn setTitle:@"忘记密码?" forState:UIControlStateNormal]; [_forgotPasswordBtn setTitleColor:HexColorFromRGB(0x000000) forState:UIControlStateNormal]; WS(weakSelf) [[[_forgotPasswordBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { [weakSelf.viewModel gotoForgetPasswordVC]; }]; } return _forgotPasswordBtn; } - (UIButton *)registerBtn{ if (!_registerBtn) { _registerBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _registerBtn.titleLabel.font = LCFont(12); [_registerBtn setTitle:@"新用户注册" forState:UIControlStateNormal]; [_registerBtn setTitleColor:HexColorFromRGB(0x000000) forState:UIControlStateNormal]; WS(weakSelf) [[[_registerBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { [weakSelf.viewModel gotoRegisterVC]; }]; } return _registerBtn; } - (UIStackView *)loginMethodStackView{ if (!_loginMethodStackView) { _loginMethodStackView = [[UIStackView alloc]init]; /** UILayoutConstraintAxisVertical 纵向 UILayoutConstraintAxisHorizontal 横向 */ _loginMethodStackView.axis = UILayoutConstraintAxisHorizontal; /** UIStackViewAlignmentFill 将stackView充满 比如label,不管文字多少,将大小按照设置的非主轴方向充满 ex: Vertical 就是水平铺满 UIStackViewAlignmentLeading 在Vertical方向上生效,表示左对齐 比如label,文字自适应,如果小于非主轴方向的宽度,将不充满 UIStackViewAlignmentTop 在Horizontal方向上生效,表示左对齐 比如label,文字自适应,如果小于非主轴方向的高度,将不充满 本质UIStackViewAlignmentTop = UIStackViewAlignmentLeading UIStackViewAlignmentTrailing 在Vertical方向上生效,表示右对齐 比如label,文字自适应,如果小于非主轴方向的宽度,将不充满 UIStackViewAlignmentBottom 在Horizontal方向上生效,表示右对齐 比如label,文字自适应,如果小于非主轴方向的高度,将不充满 本质UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing UIStackViewAlignmentLastBaseline 仅限于Horizontal 按照最高的一个视图的bottom对齐,最高的视图top对齐 UIStackViewAlignmentCenter 中心对齐 不充满,沿主轴方向中心对齐 */ _loginMethodStackView.alignment = UIStackViewAlignmentCenter; _loginMethodStackView.spacing = adapt(10); } return _loginMethodStackView; } - (UIButton *)wechatLoginBtn{ if (!_wechatLoginBtn) { _wechatLoginBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_wechatLoginBtn setBackgroundImage:ImageByName(@"ym_login_wechat_login_icon") forState:UIControlStateNormal]; WS(weakSelf) [[[_wechatLoginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { 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 sendWechatAuth]; } [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; customView.dismissBlock = ^{ @strongify(popupView) [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; return; } [weakSelf.viewModel sendWechatAuth]; }]; } return _wechatLoginBtn; } - (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]; [[[_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(12); attributedString.yy_color = HexColorFromRGBA(0x000000,0.65); attributedString.yy_paragraphStyle = paragraphStyle; //设置高亮色和点击事件 [attributedString yy_setTextHighlightRange:[agreementText rangeOfString:@"《用户协议》"] color:AGREEMENTColor 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:AGREEMENTColor 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; } @end