diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 7a38435..97d174b 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -84,6 +84,7 @@ 049FB2202EC30D2700FAB05D /* HomeRankDetailPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB21F2EC30D2700FAB05D /* HomeRankDetailPopView.m */; }; 049FB2232EC311F900FAB05D /* KBPersonInfoVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */; }; 049FB2262EC3136D00FAB05D /* KBPersonInfoItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2252EC3136D00FAB05D /* KBPersonInfoItemCell.m */; }; + 049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */; }; 049FB31D2EC21BCD00FAB05D /* KBMyKeyboardCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB31C2EC21BCD00FAB05D /* KBMyKeyboardCell.m */; }; 04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC97082EB31B14007BD342 /* KBHUD.m */; }; 04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */; }; @@ -293,6 +294,8 @@ 049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPersonInfoVC.m; sourceTree = ""; }; 049FB2242EC3136D00FAB05D /* KBPersonInfoItemCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPersonInfoItemCell.h; sourceTree = ""; }; 049FB2252EC3136D00FAB05D /* KBPersonInfoItemCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPersonInfoItemCell.m; sourceTree = ""; }; + 049FB2272EC31BB000FAB05D /* KBChangeNicknamePopView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBChangeNicknamePopView.h; sourceTree = ""; }; + 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBChangeNicknamePopView.m; sourceTree = ""; }; 049FB31B2EC21BCD00FAB05D /* KBMyKeyboardCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyKeyboardCell.h; sourceTree = ""; }; 049FB31C2EC21BCD00FAB05D /* KBMyKeyboardCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyKeyboardCell.m; sourceTree = ""; }; 04A9A67D2EB9E1690023B8F4 /* KBResponderUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBResponderUtils.h; sourceTree = ""; }; @@ -885,6 +888,8 @@ 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */, 049FB2242EC3136D00FAB05D /* KBPersonInfoItemCell.h */, 049FB2252EC3136D00FAB05D /* KBPersonInfoItemCell.m */, + 049FB2272EC31BB000FAB05D /* KBChangeNicknamePopView.h */, + 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */, ); path = V; sourceTree = ""; @@ -1436,6 +1441,7 @@ 04FC95E52EB220B5007BD342 /* UIColor+Extension.m in Sources */, 048908E02EBF73DC00FABA60 /* MySkinVC.m in Sources */, 048908F22EC047FD00FABA60 /* KBShopHeadView.m in Sources */, + 049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */, 048908EC2EBF849300FABA60 /* KBSkinTagsContainerCell.m in Sources */, 049FB2172EC20A6600FAB05D /* BMLongPressDragCellCollectionView.m in Sources */, 0477BDF02EBB76E30055D639 /* HomeSheetVC.m in Sources */, diff --git a/keyBoard/Class/Me/V/KBChangeNicknamePopView.h b/keyBoard/Class/Me/V/KBChangeNicknamePopView.h new file mode 100644 index 0000000..a846395 --- /dev/null +++ b/keyBoard/Class/Me/V/KBChangeNicknamePopView.h @@ -0,0 +1,32 @@ +// +// KBChangeNicknamePopView.h +// keyBoard +// +// Created by Codex on 2025/11/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// 修改昵称弹窗自定义视图(用于 LSTPopView) +/// - Masonry 布局 +/// - 子控件懒加载 +/// - 中文注释 +@interface KBChangeNicknamePopView : UIView + +/// 保存按钮回调,返回输入的昵称 +@property (nonatomic, copy, nullable) void (^saveHandler)(NSString *nickname); +/// 关闭按钮回调 +@property (nonatomic, copy, nullable) void (^closeHandler)(void); + +/// 预填充的昵称 +@property (nonatomic, copy) NSString *prefillNickname; + +/// 让输入框成为第一响应者 +- (void)focusInput; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/keyBoard/Class/Me/V/KBChangeNicknamePopView.m b/keyBoard/Class/Me/V/KBChangeNicknamePopView.m new file mode 100644 index 0000000..04d8db6 --- /dev/null +++ b/keyBoard/Class/Me/V/KBChangeNicknamePopView.m @@ -0,0 +1,183 @@ +// +// KBChangeNicknamePopView.m +// keyBoard +// +// Created by Codex on 2025/11/11. +// + +@import UIKit; +#import "KBChangeNicknamePopView.h" +#import + +@interface KBChangeNicknamePopView () + +// 白底圆角卡片容器 +@property (nonatomic, strong) UIView *cardView; +// 标题 +@property (nonatomic, strong) UILabel *titleLabel; +// 右上角下拉箭头样式的关闭按钮 +@property (nonatomic, strong) UIButton *closeButton; +// 输入框外层灰色圆角背景 +@property (nonatomic, strong) UIView *fieldBg; +// 输入框 +@property (nonatomic, strong) UITextField *textField; +// 保存按钮 +@property (nonatomic, strong) UIButton *saveButton; + +@end + +@implementation KBChangeNicknamePopView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + self.backgroundColor = UIColor.clearColor; // 半透明背景由 LSTPopView 控制 + [self buildUI]; + [self makeConstraints]; + } + return self; +} + +#pragma mark - Public + +- (void)setPrefillNickname:(NSString *)prefillNickname { + _prefillNickname = [prefillNickname copy]; + self.textField.text = prefillNickname; +} + +- (void)focusInput { [self.textField becomeFirstResponder]; } + +#pragma mark - Actions + +- (void)onTapClose { + if (self.closeHandler) self.closeHandler(); +} + +- (void)onTapSave { + NSString *name = self.textField.text ?: @""; + // 简单去除首尾空格 + name = [name stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]; + if (self.saveHandler) self.saveHandler(name); +} + +#pragma mark - UI + +- (void)buildUI { + [self addSubview:self.cardView]; + [self.cardView addSubview:self.titleLabel]; + [self.cardView addSubview:self.closeButton]; + [self.cardView addSubview:self.fieldBg]; + [self.fieldBg addSubview:self.textField]; + [self.cardView addSubview:self.saveButton]; +} + +- (void)makeConstraints { + [self.cardView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self); + }]; + + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.cardView).offset(20); + make.top.equalTo(self.cardView).offset(18); + }]; + + [self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.titleLabel); + make.right.equalTo(self.cardView).offset(-16); + make.width.height.mas_equalTo(36); + }]; + + [self.fieldBg mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.cardView).offset(16); + make.right.equalTo(self.cardView).offset(-16); + make.top.equalTo(self.titleLabel.mas_bottom).offset(18); + make.height.mas_equalTo(56); + }]; + + [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.fieldBg).insets(UIEdgeInsetsMake(0, 12, 0, 12)); + }]; + + [self.saveButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.cardView).offset(16); + make.right.equalTo(self.cardView).offset(-16); + make.bottom.equalTo(self.cardView).offset(-18); + make.height.mas_equalTo(56); + }]; +} + +#pragma mark - Lazy UI + +- (UIView *)cardView { + if (!_cardView) { + _cardView = [UIView new]; + _cardView.backgroundColor = UIColor.whiteColor; + _cardView.layer.cornerRadius = 18.0; + _cardView.layer.masksToBounds = YES; + } + return _cardView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [UILabel new]; + _titleLabel.text = @"Change The Nickname"; + _titleLabel.textColor = [UIColor blackColor]; + _titleLabel.font = [UIFont systemFontOfSize:22 weight:UIFontWeightBold]; + } + return _titleLabel; +} + +- (UIButton *)closeButton { + if (!_closeButton) { + _closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; + _closeButton.backgroundColor = [UIColor colorWithWhite:1 alpha:0.95]; + _closeButton.layer.cornerRadius = 18.0; _closeButton.layer.masksToBounds = YES; + _closeButton.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.05].CGColor; + _closeButton.layer.shadowOpacity = 1.0; _closeButton.layer.shadowRadius = 4.0; _closeButton.layer.shadowOffset = CGSizeMake(0, 1); + UIImage *img = nil; + if (@available(iOS 13.0, *)) img = [UIImage systemImageNamed:@"chevron.down"]; // 下拉箭头 + [_closeButton setImage:img forState:UIControlStateNormal]; + if (!img) { [_closeButton setTitle:@"∨" forState:UIControlStateNormal]; } + [_closeButton setTitleColor:[UIColor colorWithWhite:0.3 alpha:1] forState:UIControlStateNormal]; + _closeButton.tintColor = [UIColor colorWithWhite:0.3 alpha:1]; + [_closeButton addTarget:self action:@selector(onTapClose) forControlEvents:UIControlEventTouchUpInside]; + _closeButton.accessibilityLabel = @"关闭"; + } + return _closeButton; +} + +- (UIView *)fieldBg { + if (!_fieldBg) { + _fieldBg = [UIView new]; + _fieldBg.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0]; + _fieldBg.layer.cornerRadius = 12.0; _fieldBg.layer.masksToBounds = YES; + } + return _fieldBg; +} + +- (UITextField *)textField { + if (!_textField) { + _textField = [[UITextField alloc] init]; + _textField.clearButtonMode = UITextFieldViewModeWhileEditing; + _textField.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; + _textField.textColor = [UIColor blackColor]; + _textField.placeholder = @"Please Enter The Modified Nickname"; + } + return _textField; +} + +- (UIButton *)saveButton { + if (!_saveButton) { + _saveButton = [UIButton buttonWithType:UIButtonTypeCustom]; + [_saveButton setTitle:@"Save" forState:UIControlStateNormal]; + [_saveButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; + _saveButton.titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold]; + _saveButton.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0]; + _saveButton.layer.cornerRadius = 28.0; _saveButton.layer.masksToBounds = YES; // 胶囊按钮 + [_saveButton addTarget:self action:@selector(onTapSave) forControlEvents:UIControlEventTouchUpInside]; + } + return _saveButton; +} + +@end + diff --git a/keyBoard/Class/Me/VC/KBPersonInfoVC.m b/keyBoard/Class/Me/VC/KBPersonInfoVC.m index 3f86d53..e3c62f2 100644 --- a/keyBoard/Class/Me/VC/KBPersonInfoVC.m +++ b/keyBoard/Class/Me/VC/KBPersonInfoVC.m @@ -14,6 +14,8 @@ #import #import "KBPersonInfoItemCell.h" #import +#import "LSTPopView.h" +#import "KBChangeNicknamePopView.h" @interface KBPersonInfoVC () @@ -107,7 +109,37 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // 示例:点击昵称/性别执行操作;用户 ID 行点击不处理(有复制按钮) if (indexPath.row == 0) { - // TODO: 昵称编辑 + // 昵称编辑 -> 弹窗 + CGFloat width = MIN(KB_SCREEN_WIDTH - 48, 360); + KBChangeNicknamePopView *content = [[KBChangeNicknamePopView alloc] initWithFrame:CGRectMake(0, 0, width, 230)]; + content.prefillNickname = self.items.firstObject[@"value"] ?: @""; + + LSTPopView *pop = [LSTPopView initWithCustomView:content + parentView:self.view + popStyle:LSTPopStyleSmoothFromBottom + dismissStyle:LSTDismissStyleScale]; + pop.bgColor = [[UIColor blackColor] colorWithAlphaComponent:0.4]; + pop.hemStyle = LSTHemStyleCenter; // 居中 + pop.isClickBgDismiss = YES; // 点击背景关闭 + pop.isAvoidKeyboard = YES; // 规避键盘 + pop.avoidKeyboardSpace = 10; + + __weak typeof(self) weakSelf = self; + __weak typeof(pop) weakPop = pop; + content.closeHandler = ^{ [weakPop dismiss]; }; + content.saveHandler = ^(NSString *nickname) { + if (nickname.length > 0) { + // 更新第一行展示 + NSMutableArray *m = [weakSelf.items mutableCopy]; + NSMutableDictionary *d0 = [m.firstObject mutableCopy]; + d0[@"value"] = nickname; m[0] = d0; weakSelf.items = m; + [weakSelf.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; + } + [weakPop dismiss]; + }; + + [pop pop]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [content focusInput]; }); } else if (indexPath.row == 1) { // TODO: 性别选择 }