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

View File

@@ -13,8 +13,9 @@
#import "KBPersonInfoVC.h"
#import <Masonry/Masonry.h>
#import "KBPersonInfoItemCell.h"
#import <PhotosUI/PhotosUI.h>
@interface KBPersonInfoVC () <UITableViewDelegate, UITableViewDataSource>
@interface KBPersonInfoVC () <UITableViewDelegate, UITableViewDataSource, PHPickerViewControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
//
@property (nonatomic, strong) BaseTableView *tableView; //
@@ -25,13 +26,13 @@
@property (nonatomic, strong) UIButton *editBadge; //
@property (nonatomic, strong) UILabel *modifyLabel; // Modify
// 退
@property (nonatomic, strong) UIView *footerView;
@property (nonatomic, strong) UIView *logoutBg;
// 退
@property (nonatomic, strong) UIButton *logoutBtn;
//
@property (nonatomic, copy) NSArray<NSDictionary *> *items; // {title,value,arrow,copy}
// JPEG
@property (nonatomic, strong) NSData *avatarJPEGData;
@end
@@ -56,9 +57,22 @@
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 10);
}];
// &
//
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
@@ -101,9 +115,7 @@
#pragma mark - Actions
- (void)onTapAvatarEdit {
//
}
- (void)onTapAvatarEdit { [self presentImagePicker]; }
- (void)onTapLogout {
// 退
@@ -141,14 +153,18 @@
}];
[self.editBadge mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.height.mas_equalTo(24);
make.centerX.equalTo(self.avatarView.mas_right).offset(-8);
make.centerY.equalTo(self.avatarView.mas_bottom).offset(-8);
make.centerX.equalTo(self.avatarView.mas_right).offset(-15);
make.centerY.equalTo(self.avatarView.mas_bottom).offset(-15);
}];
[self.modifyLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.avatarView.mas_bottom).offset(10);
make.centerX.equalTo(hv);
}];
//
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapAvatarEdit)];
[self.avatarView addGestureRecognizer:tap];
_headerView = hv;
}
return _headerView;
@@ -177,14 +193,9 @@
- (UIButton *)editBadge {
if (!_editBadge) {
_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;
UIImage *img = nil;
if (@available(iOS 13.0, *)) img = [UIImage systemImageNamed:@"pencil"]; //
UIImage *img = [UIImage imageNamed:@"myperson_edit_icon"];
[_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];
}
return _editBadge;
@@ -194,54 +205,98 @@
if (!_modifyLabel) {
_modifyLabel = [UILabel new];
_modifyLabel.text = @"Modify";
_modifyLabel.textColor = [UIColor blackColor];
_modifyLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_modifyLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
}
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 {
if (!_logoutBtn) {
_logoutBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_logoutBtn setTitle:@"Log Out" forState:UIControlStateNormal];
[_logoutBtn setTitleColor:[UIColor colorWithRed:0.85 green:0.15 blue:0.11 alpha:1.0] forState:UIControlStateNormal];
_logoutBtn.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
[_logoutBtn setTitleColor:[UIColor colorWithHex:0xFF0000] forState:UIControlStateNormal];
_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];
}
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

View File

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