This commit is contained in:
2025-11-11 15:13:43 +08:00
parent 17b8bf2bfd
commit e34288ae56
6 changed files with 145 additions and 78 deletions

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -21,7 +21,7 @@
// //
@property (nonatomic, strong) UIButton *copyBtn; @property (nonatomic, strong) UIButton *copyBtn;
// 线 // 线
@property (nonatomic, strong) UIView *line; // 线线
// layoutSubviews mask // layoutSubviews mask
@property (nonatomic, assign) UIRectCorner cornerRecord; @property (nonatomic, assign) UIRectCorner cornerRecord;
@end @end
@@ -38,7 +38,6 @@
[self.cardView addSubview:self.valueLabel]; [self.cardView addSubview:self.valueLabel];
[self.cardView addSubview:self.arrowView]; [self.cardView addSubview:self.arrowView];
[self.cardView addSubview:self.copyBtn]; [self.cardView addSubview:self.copyBtn];
[self.cardView addSubview:self.line];
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) { [self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView).offset(16); make.left.equalTo(self.contentView).offset(16);
@@ -70,20 +69,15 @@
make.right.equalTo(self.arrowView.mas_left).offset(-8); make.right.equalTo(self.arrowView.mas_left).offset(-8);
}]; }];
[self.line mas_makeConstraints:^(MASConstraintMaker *make) { // 线
make.left.equalTo(self.cardView).offset(16);
make.right.equalTo(self.cardView).offset(-16);
make.bottom.equalTo(self.cardView);
make.height.mas_equalTo(0.5);
}];
} }
return self; return self;
} }
- (void)layoutSubviews { - (void)layoutSubviews {
[super layoutSubviews]; [super layoutSubviews];
// // 12 0
self.cardView.layer.cornerRadius = 12.0; self.cardView.layer.cornerRadius = (self.cornerRecord != 0 ? 12.0 : 0.0);
// corner mask // corner mask
if (self.cornerRecord != 0 && !CGRectIsEmpty(self.cardView.bounds)) { if (self.cornerRecord != 0 && !CGRectIsEmpty(self.cardView.bounds)) {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.cardView.bounds UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.cardView.bounds
@@ -100,7 +94,6 @@
- (void)prepareForReuse { - (void)prepareForReuse {
[super prepareForReuse]; [super prepareForReuse];
self.arrowView.hidden = YES; self.copyBtn.hidden = YES; self.arrowView.hidden = YES; self.copyBtn.hidden = YES;
self.line.hidden = NO;
} }
- (void)configWithTitle:(NSString *)title - (void)configWithTitle:(NSString *)title
@@ -126,15 +119,12 @@
UIRectCorner corners = 0; UIRectCorner corners = 0;
if (isTop && isBottom) { if (isTop && isBottom) {
corners = UIRectCornerAllCorners; corners = UIRectCornerAllCorners;
self.line.hidden = YES;
} else if (isTop) { } else if (isTop) {
corners = UIRectCornerTopLeft | UIRectCornerTopRight; corners = UIRectCornerTopLeft | UIRectCornerTopRight;
self.line.hidden = NO;
} else if (isBottom) { } else if (isBottom) {
corners = UIRectCornerBottomLeft | UIRectCornerBottomRight; corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
self.line.hidden = YES; // 线
} else { } else {
corners = 0; self.line.hidden = NO; corners = 0;
} }
// 使 // 使
@@ -149,7 +139,7 @@
if (!_cardView) { if (!_cardView) {
_cardView = [UIView new]; _cardView = [UIView new];
_cardView.backgroundColor = UIColor.whiteColor; _cardView.backgroundColor = UIColor.whiteColor;
_cardView.layer.cornerRadius = 12.0; _cardView.layer.cornerRadius = 0.0; // layoutSubviews
_cardView.layer.masksToBounds = YES; // _cardView.layer.masksToBounds = YES; //
} }
return _cardView; return _cardView;
@@ -158,7 +148,7 @@
- (UILabel *)titleLabel { - (UILabel *)titleLabel {
if (!_titleLabel) { if (!_titleLabel) {
_titleLabel = [UILabel new]; _titleLabel = [UILabel new];
_titleLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0]; _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular]; _titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular];
} }
return _titleLabel; return _titleLabel;
@@ -167,7 +157,7 @@
- (UILabel *)valueLabel { - (UILabel *)valueLabel {
if (!_valueLabel) { if (!_valueLabel) {
_valueLabel = [UILabel new]; _valueLabel = [UILabel new];
_valueLabel.textColor = [UIColor blackColor]; _valueLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_valueLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _valueLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
_valueLabel.textAlignment = NSTextAlignmentRight; _valueLabel.textAlignment = NSTextAlignmentRight;
[_valueLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [_valueLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
@@ -230,13 +220,7 @@
return _copyBtn; return _copyBtn;
} }
- (UIView *)line { // 线
if (!_line) {
_line = [UIView new];
_line.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
}
return _line;
}
#pragma mark - Event #pragma mark - Event

View File

@@ -13,8 +13,9 @@
#import "KBPersonInfoVC.h" #import "KBPersonInfoVC.h"
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
#import "KBPersonInfoItemCell.h" #import "KBPersonInfoItemCell.h"
#import <PhotosUI/PhotosUI.h>
@interface KBPersonInfoVC () <UITableViewDelegate, UITableViewDataSource> @interface KBPersonInfoVC () <UITableViewDelegate, UITableViewDataSource, PHPickerViewControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
// //
@property (nonatomic, strong) BaseTableView *tableView; // @property (nonatomic, strong) BaseTableView *tableView; //
@@ -25,13 +26,13 @@
@property (nonatomic, strong) UIButton *editBadge; // @property (nonatomic, strong) UIButton *editBadge; //
@property (nonatomic, strong) UILabel *modifyLabel; // Modify @property (nonatomic, strong) UILabel *modifyLabel; // Modify
// 退 // 退
@property (nonatomic, strong) UIView *footerView;
@property (nonatomic, strong) UIView *logoutBg;
@property (nonatomic, strong) UIButton *logoutBtn; @property (nonatomic, strong) UIButton *logoutBtn;
// //
@property (nonatomic, copy) NSArray<NSDictionary *> *items; // {title,value,arrow,copy} @property (nonatomic, copy) NSArray<NSDictionary *> *items; // {title,value,arrow,copy}
// JPEG
@property (nonatomic, strong) NSData *avatarJPEGData;
@end @end
@@ -56,9 +57,22 @@
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 10); make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 10);
}]; }];
// & //
self.tableView.tableHeaderView = self.headerView; self.tableView.tableHeaderView = self.headerView;
self.tableView.tableFooterView = self.footerView;
// 退
[self.view addSubview:self.logoutBtn];
[self.logoutBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-12);
make.height.mas_equalTo(56);
}];
//
UIEdgeInsets inset = self.tableView.contentInset;
inset.bottom = 56 + 24; // +
self.tableView.contentInset = inset;
} }
#pragma mark - UITableView #pragma mark - UITableView
@@ -101,9 +115,7 @@
#pragma mark - Actions #pragma mark - Actions
- (void)onTapAvatarEdit { - (void)onTapAvatarEdit { [self presentImagePicker]; }
//
}
- (void)onTapLogout { - (void)onTapLogout {
// 退 // 退
@@ -141,14 +153,18 @@
}]; }];
[self.editBadge mas_makeConstraints:^(MASConstraintMaker *make) { [self.editBadge mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.height.mas_equalTo(24); make.width.height.mas_equalTo(24);
make.centerX.equalTo(self.avatarView.mas_right).offset(-8); make.centerX.equalTo(self.avatarView.mas_right).offset(-15);
make.centerY.equalTo(self.avatarView.mas_bottom).offset(-8); make.centerY.equalTo(self.avatarView.mas_bottom).offset(-15);
}]; }];
[self.modifyLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.modifyLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.avatarView.mas_bottom).offset(10); make.top.equalTo(self.avatarView.mas_bottom).offset(10);
make.centerX.equalTo(hv); make.centerX.equalTo(hv);
}]; }];
//
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapAvatarEdit)];
[self.avatarView addGestureRecognizer:tap];
_headerView = hv; _headerView = hv;
} }
return _headerView; return _headerView;
@@ -177,14 +193,9 @@
- (UIButton *)editBadge { - (UIButton *)editBadge {
if (!_editBadge) { if (!_editBadge) {
_editBadge = [UIButton buttonWithType:UIButtonTypeCustom]; _editBadge = [UIButton buttonWithType:UIButtonTypeCustom];
_editBadge.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0];
_editBadge.layer.cornerRadius = 12; _editBadge.layer.masksToBounds = YES; _editBadge.layer.cornerRadius = 12; _editBadge.layer.masksToBounds = YES;
UIImage *img = nil; UIImage *img = [UIImage imageNamed:@"myperson_edit_icon"];
if (@available(iOS 13.0, *)) img = [UIImage systemImageNamed:@"pencil"]; //
[_editBadge setImage:img forState:UIControlStateNormal]; [_editBadge setImage:img forState:UIControlStateNormal];
[_editBadge setTitle:(img ? @"" : @"✎") forState:UIControlStateNormal];
_editBadge.titleLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightBold];
[_editBadge setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
[_editBadge addTarget:self action:@selector(onTapAvatarEdit) forControlEvents:UIControlEventTouchUpInside]; [_editBadge addTarget:self action:@selector(onTapAvatarEdit) forControlEvents:UIControlEventTouchUpInside];
} }
return _editBadge; return _editBadge;
@@ -194,54 +205,98 @@
if (!_modifyLabel) { if (!_modifyLabel) {
_modifyLabel = [UILabel new]; _modifyLabel = [UILabel new];
_modifyLabel.text = @"Modify"; _modifyLabel.text = @"Modify";
_modifyLabel.textColor = [UIColor blackColor]; _modifyLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_modifyLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; _modifyLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
} }
return _modifyLabel; return _modifyLabel;
} }
- (UIView *)footerView {
if (!_footerView) {
CGFloat w = UIScreen.mainScreen.bounds.size.width;
UIView *fv = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 120)];
fv.backgroundColor = UIColor.clearColor;
[fv addSubview:self.logoutBg];
[self.logoutBg mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(fv).offset(16);
make.right.equalTo(fv).offset(-16);
make.top.equalTo(fv).offset(14);
make.height.mas_equalTo(56);
}];
[self.logoutBg addSubview:self.logoutBtn];
[self.logoutBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.logoutBg);
}];
_footerView = fv;
}
return _footerView;
}
- (UIView *)logoutBg {
if (!_logoutBg) {
_logoutBg = [UIView new];
_logoutBg.backgroundColor = UIColor.whiteColor;
_logoutBg.layer.cornerRadius = 12; _logoutBg.layer.masksToBounds = YES;
}
return _logoutBg;
}
- (UIButton *)logoutBtn { - (UIButton *)logoutBtn {
if (!_logoutBtn) { if (!_logoutBtn) {
_logoutBtn = [UIButton buttonWithType:UIButtonTypeSystem]; _logoutBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_logoutBtn setTitle:@"Log Out" forState:UIControlStateNormal]; [_logoutBtn setTitle:@"Log Out" forState:UIControlStateNormal];
[_logoutBtn setTitleColor:[UIColor colorWithRed:0.85 green:0.15 blue:0.11 alpha:1.0] forState:UIControlStateNormal]; [_logoutBtn setTitleColor:[UIColor colorWithHex:0xFF0000] forState:UIControlStateNormal];
_logoutBtn.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; _logoutBtn.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
_logoutBtn.backgroundColor = UIColor.whiteColor;
_logoutBtn.layer.cornerRadius = 12; _logoutBtn.layer.masksToBounds = YES;
[_logoutBtn addTarget:self action:@selector(onTapLogout) forControlEvents:UIControlEventTouchUpInside]; [_logoutBtn addTarget:self action:@selector(onTapLogout) forControlEvents:UIControlEventTouchUpInside];
} }
return _logoutBtn; return _logoutBtn;
} }
#pragma mark - Image Picker
- (void)presentImagePicker {
if (@available(iOS 14.0, *)) {
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
config.selectionLimit = 1; //
config.filter = [PHPickerFilter imagesFilter];
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:config];
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
} else {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
}
#pragma mark - PHPickerViewControllerDelegate
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14.0)) {
[picker dismissViewControllerAnimated:YES completion:nil];
PHPickerResult *first = results.firstObject; if (!first) return;
NSItemProvider *p = first.itemProvider;
if ([p canLoadObjectOfClass:UIImage.class]) {
__weak typeof(self) weakSelf = self;
[p loadObjectOfClass:UIImage.class completionHandler:^(__kindof id<NSItemProviderReading> _Nullable object, NSError * _Nullable error) {
UIImage *img = ([object isKindOfClass:UIImage.class] ? (UIImage *)object : nil);
if (!img) return;
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *compressed = [weakSelf kb_compressImage:img maxPixel:512 quality:0.85];
weakSelf.avatarView.image = compressed;
weakSelf.avatarJPEGData = UIImageJPEGRepresentation(compressed, 0.85);
});
}];
}
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
UIImage *img = info[UIImagePickerControllerEditedImage] ?: info[UIImagePickerControllerOriginalImage];
if (img) {
UIImage *compressed = [self kb_compressImage:img maxPixel:512 quality:0.85];
self.avatarView.image = compressed;
self.avatarJPEGData = UIImageJPEGRepresentation(compressed, 0.85);
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
/// maxPixel quality JPEG
- (UIImage *)kb_compressImage:(UIImage *)image maxPixel:(CGFloat)maxPixel quality:(CGFloat)quality {
if (!image) return nil;
maxPixel = MAX(64, maxPixel);
CGSize size = image.size;
CGFloat maxSide = MAX(size.width, size.height);
CGSize target = size;
if (maxSide > maxPixel) {
CGFloat scale = maxPixel / maxSide;
target = CGSizeMake(floor(size.width * scale), floor(size.height * scale));
}
UIGraphicsBeginImageContextWithOptions(target, YES, 1.0);
[image drawInRect:CGRectMake(0, 0, target.width, target.height)];
UIImage *scaled = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *jpeg = UIImageJPEGRepresentation(scaled ?: image, MIN(MAX(quality, 0.2), 0.95));
UIImage *result = [UIImage imageWithData:jpeg] ?: scaled ?: image;
return result;
}
@end @end

View File

@@ -20,5 +20,11 @@
<key>NSAllowsArbitraryLoads</key> <key>NSAllowsArbitraryLoads</key>
<true/> <true/>
</dict> </dict>
<!-- 相册权限:更换头像需要访问相册 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>更换头像需要访问您的相册</string>
<!-- 若未来需要保存图片到相册,可保留此项(当前仅选择不需要) -->
<key>NSPhotoLibraryAddUsageDescription</key>
<string>保存图片需要写入您的相册</string>
</dict> </dict>
</plist> </plist>