fix ui
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user