// // KBLoginVC.m // keyBoard // // Created by Mac on 2025/12/2. // #import "KBLoginVC.h" #import @interface KBLoginVC () // 背景 @property (nonatomic, strong) UIImageView *bgImageView; // 整体背景图:login_bg_icon @property (nonatomic, strong) UIImageView *topRightImageView; // 顶部右侧装饰图:login_jianp_icon // 底部白色容器(仅上圆角 26) @property (nonatomic, strong) UIView *contentContainerView; // 标题 @property (nonatomic, strong) UILabel *titleLabel; // 按钮 @property (nonatomic, strong) UIControl *appleLoginButton; // Apple 原生登录按钮(iOS13 以下降级为普通按钮) @property (nonatomic, strong) UIButton *emailLoginButton; // 邮箱登录按钮 // 协议 & 底部文案 @property (nonatomic, strong) UILabel *agreementLabel; // “By Continuing, You Agree To Our” @property (nonatomic, strong) UIButton *policyButton; // “Terms Of Service & Privacy Policy” @property (nonatomic, strong) UILabel *noAccountLabel; // “Don't Have An Account?” @property (nonatomic, strong) UIButton *signUpButton; // “Sign Up” @property (nonatomic, strong) UIButton *forgotPasswordButton; // “Forgot Password?” @end @implementation KBLoginVC - (void)viewDidLoad { [super viewDidLoad]; // 使用全屏内容,隐藏自定义导航栏 self.kb_enableCustomNavBar = NO; self.view.backgroundColor = [UIColor whiteColor]; [self setupUI]; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // 仅白色容器的左上、右上圆角为 26 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.topRightImageView]; [self.topRightImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.view).offset(KB_StatusBarHeight() + KBFit(24)); make.right.equalTo(self.view).offset(-KBFit(20)); 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); // 顶部位置大致贴合设计稿,可根据实际效果微调 make.top.equalTo(self.view).offset(272); }]; // 标题 [self.contentContainerView addSubview:self.titleLabel]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.contentContainerView).offset(32); make.centerX.equalTo(self.contentContainerView); }]; // Apple 登录按钮 [self.contentContainerView addSubview:self.appleLoginButton]; [self.appleLoginButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.titleLabel.mas_bottom).offset(24); make.left.equalTo(self.contentContainerView).offset(30); make.right.equalTo(self.contentContainerView).offset(-30); make.height.mas_equalTo(52); }]; // 邮箱登录按钮 [self.contentContainerView addSubview:self.emailLoginButton]; [self.emailLoginButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.appleLoginButton.mas_bottom).offset(16); make.left.right.height.equalTo(self.appleLoginButton); }]; // 底部协议文案 [self.contentContainerView addSubview:self.policyButton]; [self.contentContainerView addSubview:self.agreementLabel]; [self.policyButton mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.contentContainerView); make.bottom.equalTo(self.contentContainerView).offset(-KB_SAFE_BOTTOM - 84); }]; [self.agreementLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.contentContainerView); make.bottom.equalTo(self.policyButton.mas_top).offset(-4); }]; // 底部账号相关文案 UIButton *forgot = self.forgotPasswordButton; [self.contentContainerView addSubview:forgot]; [forgot mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.contentContainerView); make.bottom.equalTo(self.contentContainerView).offset(-KB_SAFE_BOTTOM - 24); }]; UIView *accountLine = [UIView new]; [self.contentContainerView addSubview:accountLine]; [accountLine mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.contentContainerView); make.bottom.equalTo(forgot.mas_top).offset(-8); }]; [accountLine addSubview:self.noAccountLabel]; [accountLine addSubview:self.signUpButton]; [self.noAccountLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.bottom.equalTo(accountLine); }]; [self.signUpButton mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.noAccountLabel.mas_right).offset(4); make.right.equalTo(accountLine); make.centerY.equalTo(self.noAccountLabel); }]; } #pragma mark - Actions - (void)onTapAppleLogin { // 后续可接入 Apple Sign-In 逻辑,这里先占位 } - (void)onTapEmailLogin { // 后续接入邮箱登录逻辑 } - (void)onTapPolicy { // 打开服务条款/隐私政策 } - (void)onTapSignUp { // 打开注册页 } - (void)onTapForgotPassword { // 打开忘记密码页 } #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; } - (UIView *)contentContainerView { if (!_contentContainerView) { _contentContainerView = [UIView new]; _contentContainerView.backgroundColor = [UIColor whiteColor]; } return _contentContainerView; } - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; _titleLabel.text = KBLocalized(@"Log In To Key Of Love"); _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _titleLabel.font = [KBFont bold:18]; _titleLabel.textAlignment = NSTextAlignmentCenter; } return _titleLabel; } - (UIControl *)appleLoginButton { if (!_appleLoginButton) { ASAuthorizationAppleIDButton *btn = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeSignIn style:ASAuthorizationAppleIDButtonStyleWhite]; [btn addTarget:self action:@selector(onTapAppleLogin) forControlEvents:UIControlEventTouchUpInside]; btn.cornerRadius = 10.0; btn.layer.borderColor = [UIColor colorWithHex:0xE5E5E5].CGColor; btn.layer.borderWidth = 1; _appleLoginButton = btn; } 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 colorWithHex:0xF7F7F7]; _emailLoginButton.layer.cornerRadius = 10.0; _emailLoginButton.layer.masksToBounds = YES; UIImage *icon = [UIImage imageNamed:@"login_email_icon"]; if (icon) { [_emailLoginButton setImage:icon forState:UIControlStateNormal]; // 图片在左,文字在右,保持与截图类似 _emailLoginButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; _emailLoginButton.imageEdgeInsets = UIEdgeInsetsMake(0, 16, 0, 0); _emailLoginButton.titleEdgeInsets = UIEdgeInsetsMake(0, 32, 0, 0); } [_emailLoginButton addTarget:self action:@selector(onTapEmailLogin) forControlEvents:UIControlEventTouchUpInside]; } return _emailLoginButton; } - (UILabel *)agreementLabel { if (!_agreementLabel) { _agreementLabel = [UILabel new]; _agreementLabel.text = KBLocalized(@"By Continuing, You Agree To Our"); _agreementLabel.font = [KBFont regular:12]; _agreementLabel.textColor = [UIColor colorWithWhite:0.45 alpha:1.0]; _agreementLabel.textAlignment = NSTextAlignmentCenter; _agreementLabel.numberOfLines = 1; } return _agreementLabel; } - (UIButton *)policyButton { if (!_policyButton) { _policyButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_policyButton setTitle:KBLocalized(@"Terms Of Service & Privacy Policy") forState:UIControlStateNormal]; [_policyButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; _policyButton.titleLabel.font = [KBFont regular:12]; [_policyButton addTarget:self action:@selector(onTapPolicy) forControlEvents:UIControlEventTouchUpInside]; } return _policyButton; } - (UILabel *)noAccountLabel { if (!_noAccountLabel) { _noAccountLabel = [UILabel new]; _noAccountLabel.text = KBLocalized(@"Don't Have An Account?"); _noAccountLabel.font = [KBFont regular:13]; _noAccountLabel.textColor = [UIColor colorWithWhite:0.45 alpha:1.0]; } return _noAccountLabel; } - (UIButton *)signUpButton { if (!_signUpButton) { _signUpButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_signUpButton setTitle:KBLocalized(@"Sign Up") forState:UIControlStateNormal]; [_signUpButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; _signUpButton.titleLabel.font = [KBFont medium:13]; [_signUpButton addTarget:self action:@selector(onTapSignUp) forControlEvents:UIControlEventTouchUpInside]; } return _signUpButton; } - (UIButton *)forgotPasswordButton { if (!_forgotPasswordButton) { _forgotPasswordButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_forgotPasswordButton setTitle:KBLocalized(@"Forgot Password?") forState:UIControlStateNormal]; [_forgotPasswordButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; _forgotPasswordButton.titleLabel.font = [KBFont regular:13]; [_forgotPasswordButton addTarget:self action:@selector(onTapForgotPassword) forControlEvents:UIControlEventTouchUpInside]; } return _forgotPasswordButton; } @end