This commit is contained in:
2025-12-03 15:19:03 +08:00
parent 599a5de3bc
commit a50d18b486
14 changed files with 832 additions and 2 deletions

View File

@@ -99,6 +99,8 @@
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */; }; 04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */; };
04890B122EC2F00000FABA60 /* KBMyHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890B112EC2F00000FABA60 /* KBMyHeaderView.m */; }; 04890B122EC2F00000FABA60 /* KBMyHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890B112EC2F00000FABA60 /* KBMyHeaderView.m */; };
0498BD622EDFFC12006CC1D5 /* KBMyVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD612EDFFC12006CC1D5 /* KBMyVM.m */; }; 0498BD622EDFFC12006CC1D5 /* KBMyVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD612EDFFC12006CC1D5 /* KBMyVM.m */; };
0498BD652EE0116D006CC1D5 /* KBEmailLoginVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD642EE0116D006CC1D5 /* KBEmailLoginVC.m */; };
0498BD682EE01180006CC1D5 /* KBEmailRegistVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD672EE01180006CC1D5 /* KBEmailRegistVC.m */; };
049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; }; 049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; };
049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; }; 049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; };
049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; }; 049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; };
@@ -367,6 +369,10 @@
0498BD5E2EDF2157006CC1D5 /* KBBizCode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBBizCode.h; sourceTree = "<group>"; }; 0498BD5E2EDF2157006CC1D5 /* KBBizCode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBBizCode.h; sourceTree = "<group>"; };
0498BD602EDFFC12006CC1D5 /* KBMyVM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyVM.h; sourceTree = "<group>"; }; 0498BD602EDFFC12006CC1D5 /* KBMyVM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyVM.h; sourceTree = "<group>"; };
0498BD612EDFFC12006CC1D5 /* KBMyVM.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyVM.m; sourceTree = "<group>"; }; 0498BD612EDFFC12006CC1D5 /* KBMyVM.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyVM.m; sourceTree = "<group>"; };
0498BD632EE0116D006CC1D5 /* KBEmailLoginVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBEmailLoginVC.h; sourceTree = "<group>"; };
0498BD642EE0116D006CC1D5 /* KBEmailLoginVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmailLoginVC.m; sourceTree = "<group>"; };
0498BD662EE01180006CC1D5 /* KBEmailRegistVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBEmailRegistVC.h; sourceTree = "<group>"; };
0498BD672EE01180006CC1D5 /* KBEmailRegistVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmailRegistVC.m; sourceTree = "<group>"; };
049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = "<group>"; }; 049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = "<group>"; };
049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = "<group>"; }; 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = "<group>"; };
049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = "<group>"; }; 049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = "<group>"; };
@@ -1320,6 +1326,10 @@
04FC96122EB34E00007BD342 /* KBLoginSheetViewController.m */, 04FC96122EB34E00007BD342 /* KBLoginSheetViewController.m */,
047920612EDEEFC7004E8522 /* KBLoginVC.h */, 047920612EDEEFC7004E8522 /* KBLoginVC.h */,
047920622EDEEFC7004E8522 /* KBLoginVC.m */, 047920622EDEEFC7004E8522 /* KBLoginVC.m */,
0498BD662EE01180006CC1D5 /* KBEmailRegistVC.h */,
0498BD672EE01180006CC1D5 /* KBEmailRegistVC.m */,
0498BD632EE0116D006CC1D5 /* KBEmailLoginVC.h */,
0498BD642EE0116D006CC1D5 /* KBEmailLoginVC.m */,
); );
path = VC; path = VC;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1687,6 +1697,7 @@
04A9FE162EB873C80020DB6D /* UIViewController+Extension.m in Sources */, 04A9FE162EB873C80020DB6D /* UIViewController+Extension.m in Sources */,
04C6EABE2EAF86530089C901 /* AppDelegate.m in Sources */, 04C6EABE2EAF86530089C901 /* AppDelegate.m in Sources */,
04791FFF2ED830FA004E8522 /* KBKeyboardMaskView.m in Sources */, 04791FFF2ED830FA004E8522 /* KBKeyboardMaskView.m in Sources */,
0498BD652EE0116D006CC1D5 /* KBEmailLoginVC.m in Sources */,
04FC95F12EB339A7007BD342 /* LoginViewController.m in Sources */, 04FC95F12EB339A7007BD342 /* LoginViewController.m in Sources */,
048908E92EBF843000FABA60 /* KBSkinDetailHeaderCell.m in Sources */, 048908E92EBF843000FABA60 /* KBSkinDetailHeaderCell.m in Sources */,
04FC96142EB34E00007BD342 /* KBLoginSheetViewController.m in Sources */, 04FC96142EB34E00007BD342 /* KBLoginSheetViewController.m in Sources */,
@@ -1774,6 +1785,7 @@
A1B2C4002EB4A0A100000004 /* KBAuthManager.m in Sources */, A1B2C4002EB4A0A100000004 /* KBAuthManager.m in Sources */,
047C65532EBCBAC60035E841 /* KBCommunityVC.m in Sources */, 047C65532EBCBAC60035E841 /* KBCommunityVC.m in Sources */,
A1B2C4212EB4B7A100000001 /* KBKeyboardPermissionManager.m in Sources */, A1B2C4212EB4B7A100000001 /* KBKeyboardPermissionManager.m in Sources */,
0498BD682EE01180006CC1D5 /* KBEmailRegistVC.m in Sources */,
04122FB02EC73C0100EF7AB3 /* KBVipReviewItemCell.m in Sources */, 04122FB02EC73C0100EF7AB3 /* KBVipReviewItemCell.m in Sources */,
04122F822EC5FC6F00EF7AB3 /* KBJfPay.m in Sources */, 04122F822EC5FC6F00EF7AB3 /* KBJfPay.m in Sources */,
04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */, 04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */,

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "login_eye_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "login_eye_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "login_eyeslash_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "login_eyeslash_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -9,7 +9,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface BaseTabBarController : UITabBarController @interface BaseTabBarController : UITabBarController <UITabBarControllerDelegate>
@end @end

View File

@@ -23,6 +23,8 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
self.delegate = self;
[self setupTabbarAppearance]; [self setupTabbarAppearance];
// 4 Tab / / / // 4 Tab / / /
@@ -104,6 +106,28 @@
return item; return item;
} }
#pragma mark - UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
// tab
if (tabBarController.selectedViewController == viewController) {
return YES;
}
NSUInteger index = [tabBarController.viewControllers indexOfObject:viewController];
if (index == NSNotFound) {
return YES;
}
// tab 4 3
if (index == 3 && ![KBUserSessionManager shared].isLoggedIn) {
[[KBUserSessionManager shared] goLoginVC];
return NO;
}
return YES;
}
/* /*
#pragma mark - Navigation #pragma mark - Navigation

View File

@@ -0,0 +1,16 @@
//
// KBEmailLoginVC.h
// keyBoard
//
// Created by Mac on 2025/12/3.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface KBEmailLoginVC : UIViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,31 @@
//
// KBEmailLoginVC.m
// keyBoard
//
// Created by Mac on 2025/12/3.
//
#import "KBEmailLoginVC.h"
@interface KBEmailLoginVC ()
@end
@implementation KBEmailLoginVC
- (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

View File

@@ -0,0 +1,18 @@
//
// KBEmailRegistVC.h
// keyBoard
//
// Created by Mac on 2025/12/3.
//
#import "BaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
/// 邮箱注册/登录表单页(使用邮箱+密码)
/// 仅负责展示 UI 与基础交互,具体注册/登录逻辑后续接入 VM。
@interface KBEmailRegistVC : BaseViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,682 @@
//
// KBEmailRegistVC.m
// keyBoard
//
// Created by Mac on 2025/12/3.
//
#import "KBEmailRegistVC.h"
@interface KBEmailRegistVC () <UITextViewDelegate, UITextFieldDelegate>
//
@property (nonatomic, strong) UIImageView *bgImageView; // login_bg_icon
@property (nonatomic, strong) UIImageView *topRightImageView; // login_jianp_icon
@property (nonatomic, strong) UIButton *backButton; //
// 26
@property (nonatomic, strong) UIView *contentContainerView;
//
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *scrollContentView;
//
@property (nonatomic, strong) UILabel *titleLabel;
//
@property (nonatomic, strong) UIView *emailFieldContainer;
@property (nonatomic, strong) UITextField *emailTextField;
@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 *submitButton; // 绿 Login
//
@property (nonatomic, strong) UIButton *appleLoginButton; // Continue Through Apple
@property (nonatomic, strong) UIButton *emailLoginButton; // Continue Via Email
// &
@property (nonatomic, strong) UITextView *agreementTextView; //
@property (nonatomic, strong) UILabel *accountTipLabel; // Already Have An Account?
@property (nonatomic, strong) UIButton *switchAccountButton; // Sign In
@end
@implementation KBEmailRegistVC
- (void)viewDidLoad {
[super viewDidLoad];
// KBLoginVC 使
self.kb_enableCustomNavBar = NO;
self.view.backgroundColor = [UIColor whiteColor];
[self setupUI];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// 26 KBLoginVC
if (!CGRectIsEmpty(self.contentContainerView.bounds)) {
UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.contentContainerView.bounds
byRoundingCorners:corners
cornerRadii:CGSizeMake(26, 26)];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.frame = self.contentContainerView.bounds;
mask.path = path.CGPath;
self.contentContainerView.layer.mask = mask;
}
}
#pragma mark - UI
- (void)setupUI {
//
[self.view addSubview:self.bgImageView];
[self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
//
[self.view addSubview:self.backButton];
[self.backButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.top.equalTo(self.view).offset(KB_StatusBarHeight() + 8);
make.width.height.mas_equalTo(32);
}];
//
[self.view addSubview:self.topRightImageView];
[self.topRightImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(KB_StatusBarHeight() + KBFit(24));
make.right.equalTo(self.view).offset(KBFit(10));
make.width.mas_equalTo(KBFit(244));
make.height.mas_equalTo(KBFit(224));
}];
//
[self.view addSubview:self.contentContainerView];
[self.contentContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self.view);
// KBLoginVC
make.top.equalTo(self.view).offset(KBFit(272));
}];
//
[self.contentContainerView addSubview:self.scrollView];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.contentContainerView);
}];
[self.scrollView addSubview:self.scrollContentView];
[self.scrollContentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.scrollView);
make.width.equalTo(self.scrollView); //
}];
// Sign Up
[self.scrollContentView addSubview:self.titleLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.scrollContentView).offset(27);
make.centerX.equalTo(self.scrollContentView);
}];
//
[self.scrollContentView addSubview:self.emailFieldContainer];
[self.emailFieldContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).offset(24);
make.left.equalTo(self.scrollContentView).offset(30);
make.right.equalTo(self.scrollContentView).offset(-30);
make.height.mas_equalTo(52);
}];
[self.emailFieldContainer addSubview:self.emailTextField];
[self.emailTextField mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.emailFieldContainer).insets(UIEdgeInsetsMake(0, 16, 0, 16));
}];
//
[self.scrollContentView addSubview:self.passwordFieldContainer];
[self.passwordFieldContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.emailFieldContainer.mas_bottom).offset(16);
make.left.right.equalTo(self.emailFieldContainer);
make.height.equalTo(self.emailFieldContainer);
}];
[self.passwordFieldContainer addSubview:self.passwordToggleButton];
[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.passwordFieldContainer addSubview:self.passwordTextField];
[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.scrollContentView addSubview:self.repeatPasswordFieldContainer];
[self.repeatPasswordFieldContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.passwordFieldContainer.mas_bottom).offset(16);
make.left.right.height.equalTo(self.emailFieldContainer);
}];
[self.repeatPasswordFieldContainer addSubview:self.repeatPasswordToggleButton];
[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.repeatPasswordFieldContainer addSubview:self.repeatPasswordTextField];
[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);
}];
// 绿 Login
[self.scrollContentView addSubview:self.submitButton];
[self.submitButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.repeatPasswordFieldContainer.mas_bottom).offset(24);
make.left.right.equalTo(self.emailFieldContainer);
make.height.mas_equalTo(56);
}];
// Apple
[self.scrollContentView addSubview:self.appleLoginButton];
[self.appleLoginButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.submitButton.mas_bottom).offset(24);
make.left.right.equalTo(self.emailFieldContainer);
make.height.mas_equalTo(52);
}];
//
[self.scrollContentView addSubview:self.emailLoginButton];
[self.emailLoginButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.appleLoginButton.mas_bottom).offset(12);
make.left.right.height.equalTo(self.appleLoginButton);
}];
//
[self.scrollContentView addSubview:self.agreementTextView];
[self.agreementTextView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.emailLoginButton.mas_bottom).offset(16);
make.left.equalTo(self.scrollContentView).offset(30);
make.right.equalTo(self.scrollContentView).offset(-30);
}];
//
UIView *accountLine = [UIView new];
[self.scrollContentView addSubview:accountLine];
[accountLine mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.agreementTextView.mas_bottom).offset(16);
make.centerX.equalTo(self.scrollContentView);
make.bottom.equalTo(self.scrollContentView).offset(-KB_SAFE_BOTTOM - 16);
}];
[accountLine addSubview:self.accountTipLabel];
[accountLine addSubview:self.switchAccountButton];
[self.accountTipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.bottom.equalTo(accountLine);
}];
[self.switchAccountButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.accountTipLabel.mas_right).offset(4);
make.right.equalTo(accountLine);
make.centerY.equalTo(self.accountTipLabel);
}];
}
#pragma mark - Actions
- (void)onTapBack {
// BaseViewController pop dismiss
if (self.navigationController && self.navigationController.viewControllers.count > 1) {
[self.navigationController popViewControllerAnimated:YES];
} else if (self.presentingViewController) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}
- (void)onTapSubmit {
// /
KBLOG(@"onTapSubmit email=%@, password length=%zd",
self.emailTextField.text,
self.passwordTextField.text.length);
}
- (void)onTapForgotPassword {
KBLOG(@"onTapForgotPassword in KBEmailRegistVC");
}
- (void)onTapSwitchAccount {
// /
KBLOG(@"onTapSwitchAccount");
}
- (void)onTapTogglePassword:(UIButton *)sender {
sender.selected = !sender.selected;
BOOL showPassword = sender.selected;
if (sender == self.passwordToggleButton) {
self.passwordTextField.secureTextEntry = !showPassword;
} else if (sender == self.repeatPasswordToggleButton) {
self.repeatPasswordTextField.secureTextEntry = !showPassword;
}
}
- (void)onTapAppleLogin {
KBLOG(@"onTapAppleLogin in KBEmailRegistVC");
}
- (void)onTapEmailLogin {
KBLOG(@"onTapEmailLogin in KBEmailRegistVC");
}
#pragma mark - Agreement Tap
- (void)kb_handleAgreementTap:(UITapGestureRecognizer *)tap {
UITextView *textView = self.agreementTextView;
CGPoint point = [tap locationInView:textView];
// textContainer
CGPoint location = point;
location.x -= textView.textContainerInset.left;
location.y -= textView.textContainerInset.top;
NSLayoutManager *layoutManager = textView.layoutManager;
NSTextContainer *textContainer = textView.textContainer;
NSUInteger glyphIndex = [layoutManager glyphIndexForPoint:location
inTextContainer:textContainer];
if (glyphIndex >= textView.textStorage.length) { return; }
NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
NSString *lowerFull = textView.text.lowercaseString ?: @"";
NSRange termsRange = [lowerFull rangeOfString:@"terms of service"];
NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"];
BOOL hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange));
BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange));
if (hitTerms || hitPrivacy) {
KBLOG(@"tap policy in KBEmailRegistVC");
//
}
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == self.emailTextField) {
[self.passwordTextField becomeFirstResponder];
} else if (textField == self.passwordTextField) {
[self.repeatPasswordTextField becomeFirstResponder];
} else if (textField == self.repeatPasswordTextField) {
[textField resignFirstResponder];
[self onTapSubmit];
}
return YES;
}
#pragma mark - Lazy UI
- (UIImageView *)bgImageView {
if (!_bgImageView) {
_bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"login_bg_icon"]];
_bgImageView.contentMode = UIViewContentModeScaleAspectFill;
_bgImageView.clipsToBounds = YES;
}
return _bgImageView;
}
- (UIImageView *)topRightImageView {
if (!_topRightImageView) {
_topRightImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"login_jianp_icon"]];
_topRightImageView.contentMode = UIViewContentModeScaleAspectFit;
_topRightImageView.clipsToBounds = YES;
}
return _topRightImageView;
}
- (UIButton *)backButton {
if (!_backButton) {
_backButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *img = [UIImage imageNamed:@"back"];
if (!img) { img = [UIImage imageNamed:@"back_black_icon"]; }
if (img) {
[_backButton setImage:img forState:UIControlStateNormal];
}
_backButton.adjustsImageWhenHighlighted = YES;
_backButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[_backButton addTarget:self action:@selector(onTapBack) forControlEvents:UIControlEventTouchUpInside];
}
return _backButton;
}
- (UIView *)contentContainerView {
if (!_contentContainerView) {
_contentContainerView = [UIView new];
_contentContainerView.backgroundColor = [UIColor whiteColor];
}
return _contentContainerView;
}
- (UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [UIScrollView new];
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.alwaysBounceVertical = NO; //
_scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
}
return _scrollView;
}
- (UIView *)scrollContentView {
if (!_scrollContentView) {
_scrollContentView = [UIView new];
_scrollContentView.backgroundColor = [UIColor clearColor];
}
return _scrollContentView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [UILabel new];
//
_titleLabel.text = KBLocalized(@"Sign Up");
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_titleLabel.font = [KBFont bold:18];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
- (UIView *)emailFieldContainer {
if (!_emailFieldContainer) {
_emailFieldContainer = [UIView new];
_emailFieldContainer.backgroundColor = [UIColor colorWithHex:0xF7F7F7];
_emailFieldContainer.layer.cornerRadius = 10.0;
_emailFieldContainer.layer.masksToBounds = YES;
}
return _emailFieldContainer;
}
- (UITextField *)emailTextField {
if (!_emailTextField) {
_emailTextField = [[UITextField alloc] init];
_emailTextField.delegate = self;
_emailTextField.keyboardType = UIKeyboardTypeEmailAddress;
_emailTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
_emailTextField.autocorrectionType = UITextAutocorrectionTypeNo;
_emailTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
_emailTextField.textColor = [UIColor colorWithHex:KBBlackValue];
_emailTextField.font = [KBFont regular:14];
_emailTextField.returnKeyType = UIReturnKeyNext;
NSString *ph = KBLocalized(@"Enter Email Address");
_emailTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:ph
attributes:@{
NSForegroundColorAttributeName : [UIColor colorWithWhite:0.75 alpha:1.0],
NSFontAttributeName : [KBFont regular:14]
}];
}
return _emailTextField;
}
- (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 = UIReturnKeyDone;
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 *)forgotPasswordButton {
// 使
return nil;
}
- (UIButton *)submitButton {
if (!_submitButton) {
_submitButton = [UIButton buttonWithType:UIButtonTypeCustom];
// LoginSign Up
[_submitButton setTitle:KBLocalized(@"Login") forState:UIControlStateNormal];
[_submitButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_submitButton.titleLabel.font = [KBFont medium:16];
_submitButton.backgroundColor = [UIColor colorWithHex:KBColorValue];
_submitButton.layer.cornerRadius = 28.0;
_submitButton.layer.masksToBounds = YES;
[_submitButton addTarget:self
action:@selector(onTapSubmit)
forControlEvents:UIControlEventTouchUpInside];
}
return _submitButton;
}
- (UIButton *)appleLoginButton {
if (!_appleLoginButton) {
_appleLoginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_appleLoginButton setTitle:KBLocalized(@"Continue Through Apple") forState:UIControlStateNormal];
[_appleLoginButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal];
_appleLoginButton.titleLabel.font = [KBFont medium:16];
_appleLoginButton.backgroundColor = [UIColor whiteColor];
_appleLoginButton.layer.cornerRadius = 10.0;
_appleLoginButton.layer.masksToBounds = YES;
_appleLoginButton.layer.borderColor = [UIColor colorWithHex:0xE5E5E5].CGColor;
_appleLoginButton.layer.borderWidth = 1;
_appleLoginButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
// Apple imageEdgeInsets
[_appleLoginButton addTarget:self
action:@selector(onTapAppleLogin)
forControlEvents:UIControlEventTouchUpInside];
}
return _appleLoginButton;
}
- (UIButton *)emailLoginButton {
if (!_emailLoginButton) {
_emailLoginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_emailLoginButton setTitle:KBLocalized(@"Continue Via Email") forState:UIControlStateNormal];
[_emailLoginButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal];
_emailLoginButton.titleLabel.font = [KBFont medium:16];
_emailLoginButton.backgroundColor = [UIColor whiteColor];
_emailLoginButton.layer.cornerRadius = 10.0;
_emailLoginButton.layer.masksToBounds = YES;
_emailLoginButton.layer.borderColor = [UIColor colorWithHex:0xE5E5E5].CGColor;
_emailLoginButton.layer.borderWidth = 1;
_emailLoginButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
UIImage *icon = [UIImage imageNamed:@"login_email_icon"];
if (icon) {
CGFloat targetHeight = 12;
CGFloat scale = targetHeight / icon.size.height;
CGSize targetSize = CGSizeMake(icon.size.width * scale, targetHeight);
UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0);
[icon drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];
UIImage *scaledIcon = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[_emailLoginButton setImage:scaledIcon forState:UIControlStateNormal];
//
_emailLoginButton.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
}
[_emailLoginButton addTarget:self
action:@selector(onTapEmailLogin)
forControlEvents:UIControlEventTouchUpInside];
}
return _emailLoginButton;
}
- (UITextView *)agreementTextView {
if (!_agreementTextView) {
_agreementTextView = [UITextView new];
_agreementTextView.backgroundColor = [UIColor clearColor];
_agreementTextView.editable = NO;
_agreementTextView.selectable = NO;
_agreementTextView.scrollEnabled = NO;
_agreementTextView.textAlignment = NSTextAlignmentCenter;
_agreementTextView.textContainerInset = UIEdgeInsetsZero;
_agreementTextView.textContainer.lineFragmentPadding = 0;
NSString *fullText = @"By continuing, you agree to our terms of service and confirm that you have read our privacy policy";
NSString *termsText = @"terms of service";
NSString *privacyText = @"privacy policy";
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter;
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:fullText
attributes:@{
NSFontAttributeName : [KBFont regular:10],
NSForegroundColorAttributeName : [UIColor colorWithHex:0x717171],
NSParagraphStyleAttributeName : paragraph
}];
NSString *lowerFull = fullText.lowercaseString;
NSRange termsRange = [lowerFull rangeOfString:termsText.lowercaseString];
if (termsRange.location != NSNotFound) {
[attr addAttributes:@{
NSForegroundColorAttributeName : [UIColor colorWithHex:KBBlackValue],
NSUnderlineStyleAttributeName : @(NSUnderlineStyleNone)
} range:termsRange];
}
NSRange privacyRange = [lowerFull rangeOfString:privacyText.lowercaseString];
if (privacyRange.location != NSNotFound) {
[attr addAttributes:@{
NSForegroundColorAttributeName : [UIColor colorWithHex:KBBlackValue],
NSUnderlineStyleAttributeName : @(NSUnderlineStyleNone)
} range:privacyRange];
}
_agreementTextView.linkTextAttributes = @{
NSForegroundColorAttributeName : [UIColor colorWithHex:KBBlackValue],
NSUnderlineStyleAttributeName : @(NSUnderlineStyleNone)
};
_agreementTextView.attributedText = attr;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(kb_handleAgreementTap:)];
_agreementTextView.userInteractionEnabled = YES;
[_agreementTextView addGestureRecognizer:tap];
}
return _agreementTextView;
}
- (UILabel *)accountTipLabel {
if (!_accountTipLabel) {
_accountTipLabel = [UILabel new];
_accountTipLabel.text = KBLocalized(@"Already Have An Account?");
_accountTipLabel.font = [KBFont regular:10];
_accountTipLabel.textColor = [UIColor colorWithHex:KBBlackValue];
}
return _accountTipLabel;
}
- (UIButton *)switchAccountButton {
if (!_switchAccountButton) {
_switchAccountButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_switchAccountButton setTitle:KBLocalized(@"Sign In") forState:UIControlStateNormal];
[_switchAccountButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal];
_switchAccountButton.titleLabel.font = [KBFont medium:10];
[_switchAccountButton addTarget:self
action:@selector(onTapSwitchAccount)
forControlEvents:UIControlEventTouchUpInside];
}
return _switchAccountButton;
}
@end

View File

@@ -9,6 +9,7 @@
#import <AuthenticationServices/AuthenticationServices.h> #import <AuthenticationServices/AuthenticationServices.h>
#import "KBLoginVM.h" #import "KBLoginVM.h"
#import "AppDelegate.h" #import "AppDelegate.h"
#import "KBEmailRegistVC.h"
@interface KBLoginVC () <UITextViewDelegate> @interface KBLoginVC () <UITextViewDelegate>
@@ -88,7 +89,7 @@
[self.view addSubview:self.topRightImageView]; [self.view addSubview:self.topRightImageView];
[self.topRightImageView mas_makeConstraints:^(MASConstraintMaker *make) { [self.topRightImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(KB_StatusBarHeight() + KBFit(24)); make.top.equalTo(self.view).offset(KB_StatusBarHeight() + KBFit(24));
make.right.equalTo(self.view).offset(-KBFit(20)); make.right.equalTo(self.view).offset(KBFit(10));
make.width.mas_equalTo(KBFit(244)); make.width.mas_equalTo(KBFit(244));
make.height.mas_equalTo(KBFit(224)); make.height.mas_equalTo(KBFit(224));
}]; }];
@@ -197,6 +198,8 @@
- (void)onTapSignUp { - (void)onTapSignUp {
// //
KBLOG(@"onTapSignUp"); KBLOG(@"onTapSignUp");
KBEmailRegistVC *vc = [[KBEmailRegistVC alloc] init];
[KB_CURRENT_NAV pushViewController:vc animated:true];
} }
- (void)onTapForgotPassword { - (void)onTapForgotPassword {