234 lines
8.5 KiB
Objective-C
234 lines
8.5 KiB
Objective-C
//
|
||
// KBGenderPickerPopView.m
|
||
// keyBoard
|
||
//
|
||
// Created by Codex on 2025/11/11.
|
||
//
|
||
|
||
@import UIKit;
|
||
#import "KBGenderPickerPopView.h"
|
||
#import <Masonry/Masonry.h>
|
||
|
||
@interface KBGenderPickerPopView () <UIPickerViewDelegate, UIPickerViewDataSource>
|
||
|
||
// 白底圆角卡片容器
|
||
@property (nonatomic, strong) UIView *cardView;
|
||
// 标题
|
||
@property (nonatomic, strong) UILabel *titleLabel;
|
||
// 右上角关闭(下拉箭头)
|
||
@property (nonatomic, strong) UIButton *closeButton;
|
||
// 选择器
|
||
@property (nonatomic, strong) UIPickerView *picker;
|
||
// 选中区域的上/下分隔线(模拟系统选择线)
|
||
@property (nonatomic, strong) UIView *lineTop;
|
||
@property (nonatomic, strong) UIView *lineBottom;
|
||
// 保存按钮
|
||
@property (nonatomic, strong) UIButton *saveButton;
|
||
|
||
@end
|
||
|
||
@implementation KBGenderPickerPopView
|
||
|
||
- (instancetype)initWithFrame:(CGRect)frame {
|
||
if (self = [super initWithFrame:frame]) {
|
||
self.backgroundColor = UIColor.clearColor;
|
||
// 默认三项
|
||
_items = @[
|
||
@{ @"id": @"1", @"name": @"Male" },
|
||
@{ @"id": @"2", @"name": @"Female" },
|
||
@{ @"id": @"3", @"name": @"The Third Gender" },
|
||
];
|
||
[self buildUI];
|
||
[self makeConstraints];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
#pragma mark - Public
|
||
|
||
- (void)setItems:(NSArray<NSDictionary *> *)items {
|
||
_items = [items copy];
|
||
[self.picker reloadAllComponents];
|
||
[self syncSelection];
|
||
}
|
||
|
||
- (void)setSelectedId:(NSString *)selectedId {
|
||
_selectedId = [selectedId copy];
|
||
[self syncSelection];
|
||
}
|
||
|
||
- (void)syncSelection {
|
||
// 找到选中 id 对应的行(避免 __block,可直接用 indexOfObjectPassingTest)
|
||
NSInteger row = 0;
|
||
if (self.selectedId.length > 0) {
|
||
NSUInteger idx = [self.items indexOfObjectPassingTest:^BOOL(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
|
||
return [[obj objectForKey:@"id"] ?: @"" isEqualToString:self.selectedId];
|
||
}];
|
||
if (idx != NSNotFound) row = (NSInteger)idx;
|
||
}
|
||
if (row < (NSInteger)self.items.count) {
|
||
[self.picker selectRow:row inComponent:0 animated:NO];
|
||
}
|
||
[self.picker reloadAllComponents];
|
||
}
|
||
|
||
#pragma mark - Actions
|
||
|
||
- (void)onTapClose { if (self.closeHandler) self.closeHandler(); }
|
||
|
||
- (void)onTapSave {
|
||
NSInteger row = [self.picker selectedRowInComponent:0];
|
||
if (row >= 0 && row < (NSInteger)self.items.count) {
|
||
NSDictionary *sel = self.items[row];
|
||
if (self.saveHandler) self.saveHandler(sel);
|
||
}
|
||
}
|
||
|
||
#pragma mark - UI
|
||
|
||
- (void)buildUI {
|
||
[self addSubview:self.cardView];
|
||
[self.cardView addSubview:self.titleLabel];
|
||
[self.cardView addSubview:self.closeButton];
|
||
[self.cardView addSubview:self.picker];
|
||
[self.cardView addSubview:self.lineTop];
|
||
[self.cardView addSubview:self.lineBottom];
|
||
[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.titleLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
|
||
[self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
|
||
[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.picker mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.equalTo(self.cardView).offset(10);
|
||
make.right.equalTo(self.cardView).offset(-10);
|
||
make.top.equalTo(self.titleLabel.mas_bottom).offset(6);
|
||
make.bottom.equalTo(self.saveButton.mas_top).offset(0);
|
||
}];
|
||
// 选中区域分隔线放在 picker 上方
|
||
CGFloat rowH = 48;
|
||
[self.lineTop mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.right.equalTo(self.picker);
|
||
make.centerY.equalTo(self.picker).offset(-rowH/2.0);
|
||
make.height.mas_equalTo(1);
|
||
}];
|
||
[self.lineBottom mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.right.equalTo(self.picker);
|
||
make.centerY.equalTo(self.picker).offset(rowH/2.0);
|
||
make.height.mas_equalTo(1);
|
||
}];
|
||
[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(46);
|
||
}];
|
||
}
|
||
|
||
#pragma mark - Picker
|
||
|
||
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; }
|
||
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return self.items.count; }
|
||
|
||
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component { return 48.0; }
|
||
|
||
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
|
||
UILabel *label = (UILabel *)view;
|
||
if (![label isKindOfClass:UILabel.class]) {
|
||
label = [[UILabel alloc] init];
|
||
label.textAlignment = NSTextAlignmentCenter;
|
||
label.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold];
|
||
}
|
||
NSString *name = self.items[row][@"name"] ?: @"";
|
||
label.text = name;
|
||
BOOL selected = (row == [pickerView selectedRowInComponent:0]);
|
||
label.textColor = selected ? [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0]
|
||
: [UIColor colorWithWhite:0.65 alpha:1.0];
|
||
return label;
|
||
}
|
||
|
||
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
|
||
// 选中变化后刷新颜色
|
||
[pickerView reloadAllComponents];
|
||
}
|
||
|
||
#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 = @"Modify Gender";
|
||
_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;
|
||
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];
|
||
}
|
||
return _closeButton;
|
||
}
|
||
|
||
- (UIPickerView *)picker {
|
||
if (!_picker) {
|
||
_picker = [[UIPickerView alloc] init];
|
||
_picker.dataSource = self; _picker.delegate = self;
|
||
_picker.backgroundColor = UIColor.clearColor;
|
||
}
|
||
return _picker;
|
||
}
|
||
|
||
- (UIView *)lineTop {
|
||
if (!_lineTop) { _lineTop = [self makeLine]; }
|
||
return _lineTop;
|
||
}
|
||
- (UIView *)lineBottom {
|
||
if (!_lineBottom) { _lineBottom = [self makeLine]; }
|
||
return _lineBottom;
|
||
}
|
||
- (UIView *)makeLine { UIView *v = [UIView new]; v.backgroundColor = [UIColor colorWithWhite:0.88 alpha:1.0]; return v; }
|
||
|
||
- (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 = 23.0; _saveButton.layer.masksToBounds = YES;
|
||
[_saveButton addTarget:self action:@selector(onTapSave) forControlEvents:UIControlEventTouchUpInside];
|
||
}
|
||
return _saveButton;
|
||
}
|
||
|
||
@end
|