Files
keyboard/keyBoard/Class/Me/V/KBGenderPickerPopView.m
2025-11-11 15:55:52 +08:00

234 lines
8.5 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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