From d06e0499bca020dd16a0d8936d52ff8c4d8c8978 Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Wed, 3 Dec 2025 16:38:20 +0800 Subject: [PATCH] 1 --- keyBoard.xcodeproj/project.pbxproj | 6 + keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.h | 4 +- keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.m | 241 +++++++++++++++++- keyBoard/Class/Login/VC/KBForgetVerPwdVC.m | 9 + keyBoard/Class/Login/VC/KBRegistVerEmailVC.h | 16 ++ keyBoard/Class/Login/VC/KBRegistVerEmailVC.m | 31 +++ 6 files changed, 296 insertions(+), 11 deletions(-) create mode 100644 keyBoard/Class/Login/VC/KBRegistVerEmailVC.h create mode 100644 keyBoard/Class/Login/VC/KBRegistVerEmailVC.m diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 296448a..d94d4a9 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -104,6 +104,7 @@ 0498BD6B2EE025FC006CC1D5 /* KBForgetPwdVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD6A2EE025FC006CC1D5 /* KBForgetPwdVC.m */; }; 0498BD6E2EE0285D006CC1D5 /* KBForgetVerPwdVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD6D2EE0285D006CC1D5 /* KBForgetVerPwdVC.m */; }; 0498BD712EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD702EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.m */; }; + 0498BD742EE02E3D006CC1D5 /* KBRegistVerEmailVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD732EE02E3D006CC1D5 /* KBRegistVerEmailVC.m */; }; 049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; }; 049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; }; 049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; }; @@ -382,6 +383,8 @@ 0498BD6D2EE0285D006CC1D5 /* KBForgetVerPwdVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBForgetVerPwdVC.m; sourceTree = ""; }; 0498BD6F2EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBForgetPwdNewPwdVC.h; sourceTree = ""; }; 0498BD702EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBForgetPwdNewPwdVC.m; sourceTree = ""; }; + 0498BD722EE02E3D006CC1D5 /* KBRegistVerEmailVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBRegistVerEmailVC.h; sourceTree = ""; }; + 0498BD732EE02E3D006CC1D5 /* KBRegistVerEmailVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBRegistVerEmailVC.m; sourceTree = ""; }; 049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = ""; }; 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = ""; }; 049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = ""; }; @@ -1337,6 +1340,8 @@ 047920622EDEEFC7004E8522 /* KBLoginVC.m */, 0498BD662EE01180006CC1D5 /* KBEmailRegistVC.h */, 0498BD672EE01180006CC1D5 /* KBEmailRegistVC.m */, + 0498BD722EE02E3D006CC1D5 /* KBRegistVerEmailVC.h */, + 0498BD732EE02E3D006CC1D5 /* KBRegistVerEmailVC.m */, 0498BD632EE0116D006CC1D5 /* KBEmailLoginVC.h */, 0498BD642EE0116D006CC1D5 /* KBEmailLoginVC.m */, 0498BD692EE025FC006CC1D5 /* KBForgetPwdVC.h */, @@ -1742,6 +1747,7 @@ 04FC95E52EB220B5007BD342 /* UIColor+Extension.m in Sources */, 048908E02EBF73DC00FABA60 /* MySkinVC.m in Sources */, 048908F22EC047FD00FABA60 /* KBShopHeadView.m in Sources */, + 0498BD742EE02E3D006CC1D5 /* KBRegistVerEmailVC.m in Sources */, 049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */, 048908EC2EBF849300FABA60 /* KBSkinTagsContainerCell.m in Sources */, 049FB2172EC20A6600FAB05D /* BMLongPressDragCellCollectionView.m in Sources */, diff --git a/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.h b/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.h index 6d70c45..c99d6c9 100644 --- a/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.h +++ b/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.h @@ -5,11 +5,11 @@ // Created by Mac on 2025/12/3. // -#import +#import "BaseViewController.h" NS_ASSUME_NONNULL_BEGIN -@interface KBForgetPwdNewPwdVC : UIViewController +@interface KBForgetPwdNewPwdVC : BaseViewController @end diff --git a/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.m b/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.m index 6039790..8a4bc93 100644 --- a/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.m +++ b/keyBoard/Class/Login/VC/KBForgetPwdNewPwdVC.m @@ -7,7 +7,18 @@ #import "KBForgetPwdNewPwdVC.h" -@interface KBForgetPwdNewPwdVC () +@interface KBForgetPwdNewPwdVC () + +@property (nonatomic, strong) UILabel *titleLabel; // Reset Password +@property (nonatomic, strong) UIView *passwordFieldContainer; +@property (nonatomic, strong) UITextField *passwordTextField; +@property (nonatomic, strong) UIButton *passwordToggleButton; + +@property (nonatomic, strong) UIView *repeatPasswordFieldContainer; +@property (nonatomic, strong) UITextField *repeatPasswordTextField; +@property (nonatomic, strong) UIButton *repeatPasswordToggleButton; + +@property (nonatomic, strong) UIButton *nextButton; // Next Step @end @@ -15,17 +26,229 @@ - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view. + self.view.backgroundColor = [UIColor whiteColor]; + self.kb_titleLabel.text = KBLocalized(@"Reset Password"); + + [self setupUI]; } -/* -#pragma mark - Navigation +#pragma mark - UI -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. +- (void)setupUI { + [self.view addSubview:self.titleLabel]; + [self.view addSubview:self.passwordFieldContainer]; + [self.passwordFieldContainer addSubview:self.passwordTextField]; + [self.passwordFieldContainer addSubview:self.passwordToggleButton]; + [self.view addSubview:self.repeatPasswordFieldContainer]; + [self.repeatPasswordFieldContainer addSubview:self.repeatPasswordTextField]; + [self.repeatPasswordFieldContainer addSubview:self.repeatPasswordToggleButton]; + [self.view addSubview:self.nextButton]; + + // 标题 + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(24); + make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 32); + }]; + + // 新密码 + [self.passwordFieldContainer mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.titleLabel.mas_bottom).offset(24); + make.left.equalTo(self.view).offset(24); + make.right.equalTo(self.view).offset(-24); + make.height.mas_equalTo(52); + }]; + + [self.passwordToggleButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.passwordFieldContainer); + make.right.equalTo(self.passwordFieldContainer).offset(-16); + make.width.height.mas_equalTo(24); + }]; + + [self.passwordTextField mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.equalTo(self.passwordFieldContainer); + make.left.equalTo(self.passwordFieldContainer).offset(16); + make.right.equalTo(self.passwordToggleButton.mas_left).offset(-8); + }]; + + // 确认密码 + [self.repeatPasswordFieldContainer mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.passwordFieldContainer.mas_bottom).offset(16); + make.left.right.height.equalTo(self.passwordFieldContainer); + }]; + + [self.repeatPasswordToggleButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.repeatPasswordFieldContainer); + make.right.equalTo(self.repeatPasswordFieldContainer).offset(-16); + make.width.height.mas_equalTo(24); + }]; + + [self.repeatPasswordTextField mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.equalTo(self.repeatPasswordFieldContainer); + make.left.equalTo(self.repeatPasswordFieldContainer).offset(16); + make.right.equalTo(self.repeatPasswordToggleButton.mas_left).offset(-8); + }]; + + // Next Step 按钮 + [self.nextButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.repeatPasswordFieldContainer.mas_bottom).offset(24); + make.left.right.equalTo(self.passwordFieldContainer); + make.height.mas_equalTo(56); + }]; +} + +#pragma mark - Actions + +- (void)onTapTogglePassword:(UIButton *)sender { + sender.selected = !sender.selected; + BOOL show = sender.selected; + if (sender == self.passwordToggleButton) { + self.passwordTextField.secureTextEntry = !show; + } else if (sender == self.repeatPasswordToggleButton) { + self.repeatPasswordTextField.secureTextEntry = !show; + } +} + +- (void)onTapNext { + NSString *pwd = self.passwordTextField.text ?: @""; + NSString *repeat = self.repeatPasswordTextField.text ?: @""; + + if (pwd.length == 0 || repeat.length == 0) { + [KBHUD showInfo:KBLocalized(@"Please complete all fields")]; + return; + } + if (![pwd isEqualToString:repeat]) { + [KBHUD showInfo:KBLocalized(@"The two passwords do not match")]; + return; + } + + KBLOG(@"KBForgetPwdNewPwdVC next step, pwdLen=%zd", pwd.length); + // TODO: 提交新密码逻辑 +} + +#pragma mark - UITextFieldDelegate + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + if (textField == self.passwordTextField) { + [self.repeatPasswordTextField becomeFirstResponder]; + } else if (textField == self.repeatPasswordTextField) { + [textField resignFirstResponder]; + [self onTapNext]; + } + return YES; +} + +#pragma mark - Lazy UI + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [UILabel new]; + _titleLabel.text = KBLocalized(@"Reset Password"); + _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; + _titleLabel.font = [KBFont bold:20]; + _titleLabel.textAlignment = NSTextAlignmentLeft; + } + return _titleLabel; +} + +- (UIView *)passwordFieldContainer { + if (!_passwordFieldContainer) { + _passwordFieldContainer = [UIView new]; + _passwordFieldContainer.backgroundColor = [UIColor colorWithHex:0xF7F7F7]; + _passwordFieldContainer.layer.cornerRadius = 10.0; + _passwordFieldContainer.layer.masksToBounds = YES; + } + return _passwordFieldContainer; +} + +- (UITextField *)passwordTextField { + if (!_passwordTextField) { + _passwordTextField = [[UITextField alloc] init]; + _passwordTextField.delegate = self; + _passwordTextField.secureTextEntry = YES; + _passwordTextField.textColor = [UIColor colorWithHex:KBBlackValue]; + _passwordTextField.font = [KBFont regular:14]; + _passwordTextField.returnKeyType = UIReturnKeyNext; + + NSString *ph = KBLocalized(@"Enter Password"); + _passwordTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:ph + attributes:@{ + NSForegroundColorAttributeName : [UIColor colorWithWhite:0.75 alpha:1.0], + NSFontAttributeName : [KBFont regular:14] + }]; + } + return _passwordTextField; +} + +- (UIButton *)passwordToggleButton { + if (!_passwordToggleButton) { + _passwordToggleButton = [UIButton buttonWithType:UIButtonTypeCustom]; + UIImage *eye = [UIImage imageNamed:@"login_eye_icon"]; + UIImage *eyeSlash = [UIImage imageNamed:@"login_eyeslash_icon"]; + [_passwordToggleButton setImage:eye forState:UIControlStateNormal]; + [_passwordToggleButton setImage:eyeSlash forState:UIControlStateSelected]; + [_passwordToggleButton addTarget:self + action:@selector(onTapTogglePassword:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _passwordToggleButton; +} + +- (UIView *)repeatPasswordFieldContainer { + if (!_repeatPasswordFieldContainer) { + _repeatPasswordFieldContainer = [UIView new]; + _repeatPasswordFieldContainer.backgroundColor = [UIColor colorWithHex:0xF7F7F7]; + _repeatPasswordFieldContainer.layer.cornerRadius = 10.0; + _repeatPasswordFieldContainer.layer.masksToBounds = YES; + } + return _repeatPasswordFieldContainer; +} + +- (UITextField *)repeatPasswordTextField { + if (!_repeatPasswordTextField) { + _repeatPasswordTextField = [[UITextField alloc] init]; + _repeatPasswordTextField.delegate = self; + _repeatPasswordTextField.secureTextEntry = YES; + _repeatPasswordTextField.textColor = [UIColor colorWithHex:KBBlackValue]; + _repeatPasswordTextField.font = [KBFont regular:14]; + _repeatPasswordTextField.returnKeyType = UIReturnKeyDone; + + NSString *ph = KBLocalized(@"Enter Repeat Password"); + _repeatPasswordTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:ph + attributes:@{ + NSForegroundColorAttributeName : [UIColor colorWithWhite:0.75 alpha:1.0], + NSFontAttributeName : [KBFont regular:14] + }]; + } + return _repeatPasswordTextField; +} + +- (UIButton *)repeatPasswordToggleButton { + if (!_repeatPasswordToggleButton) { + _repeatPasswordToggleButton = [UIButton buttonWithType:UIButtonTypeCustom]; + UIImage *eye = [UIImage imageNamed:@"login_eye_icon"]; + UIImage *eyeSlash = [UIImage imageNamed:@"login_eyeslash_icon"]; + [_repeatPasswordToggleButton setImage:eye forState:UIControlStateNormal]; + [_repeatPasswordToggleButton setImage:eyeSlash forState:UIControlStateSelected]; + [_repeatPasswordToggleButton addTarget:self + action:@selector(onTapTogglePassword:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _repeatPasswordToggleButton; +} + +- (UIButton *)nextButton { + if (!_nextButton) { + _nextButton = [UIButton buttonWithType:UIButtonTypeCustom]; + [_nextButton setTitle:KBLocalized(@"Next Step") forState:UIControlStateNormal]; + [_nextButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + _nextButton.titleLabel.font = [KBFont medium:16]; + _nextButton.backgroundColor = [UIColor colorWithHex:KBColorValue]; + _nextButton.layer.cornerRadius = 28.0; + _nextButton.layer.masksToBounds = YES; + [_nextButton addTarget:self action:@selector(onTapNext) + forControlEvents:UIControlEventTouchUpInside]; + } + return _nextButton; } -*/ @end diff --git a/keyBoard/Class/Login/VC/KBForgetVerPwdVC.m b/keyBoard/Class/Login/VC/KBForgetVerPwdVC.m index d779320..b1d1dde 100644 --- a/keyBoard/Class/Login/VC/KBForgetVerPwdVC.m +++ b/keyBoard/Class/Login/VC/KBForgetVerPwdVC.m @@ -7,6 +7,7 @@ #import "KBForgetVerPwdVC.h" #import "CRBoxInputView.h" +#import "KBForgetPwdNewPwdVC.h" @interface KBForgetVerPwdVC () @@ -74,6 +75,13 @@ } KBLOG(@"KBVerPwdVC next step with code=%@", code); // TODO: 接后续重置密码的下一步逻辑 + KBForgetPwdNewPwdVC *vc = [[KBForgetPwdNewPwdVC alloc] init]; + UINavigationController *nav = KB_CURRENT_NAV; + if ([nav isKindOfClass:[BaseNavigationController class]]) { + [(BaseNavigationController *)nav kb_pushViewControllerRemovingSameClass:vc animated:YES]; + } else { + [nav pushViewController:vc animated:YES]; + } } #pragma mark - Lazy UI @@ -122,6 +130,7 @@ prop.cornerRadius = 8.0; prop.cellBgColorNormal = [UIColor colorWithHex:0xF7F7F7]; prop.cellBgColorSelected = [UIColor colorWithHex:0xE0F5F2]; + prop.cellCursorColor = [UIColor colorWithHex:KBBlackValue]; prop.cellFont = [KBFont bold:20]; prop.cellTextColor = [UIColor colorWithHex:KBBlackValue]; _codeInputView.customCellProperty = prop; diff --git a/keyBoard/Class/Login/VC/KBRegistVerEmailVC.h b/keyBoard/Class/Login/VC/KBRegistVerEmailVC.h new file mode 100644 index 0000000..f309cf8 --- /dev/null +++ b/keyBoard/Class/Login/VC/KBRegistVerEmailVC.h @@ -0,0 +1,16 @@ +// +// KBRegistVerEmailVC.h +// keyBoard +// +// Created by Mac on 2025/12/3. +// 注册验证邮箱 + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KBRegistVerEmailVC : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Login/VC/KBRegistVerEmailVC.m b/keyBoard/Class/Login/VC/KBRegistVerEmailVC.m new file mode 100644 index 0000000..fe8ec96 --- /dev/null +++ b/keyBoard/Class/Login/VC/KBRegistVerEmailVC.m @@ -0,0 +1,31 @@ +// +// KBRegistVerEmailVC.m +// keyBoard +// +// Created by Mac on 2025/12/3. +// + +#import "KBRegistVerEmailVC.h" + +@interface KBRegistVerEmailVC () + +@end + +@implementation KBRegistVerEmailVC + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end