UITableViewCell
内嵌UITextField
,我们想要在列表中输入编辑内容。
1. UKInputTableViewCell
UKInputTableViewCell
包含一个标题栏和一个输入框,用来接收输入内容
typedef void(^InputChangeBlock)(NSString *);
@interface UKInputTableViewCell : UITableViewCell
// 输入框内容回调
@property(nonatomic, copy) InputChangeBlock inputChange;
@property(nonatomic, strong) UILabel *titleLabel;
@property(nonatomic, strong) UITextField *contentTextField;
// 设置标题栏和输入框提示
- (void)setTitle:(NSString *)title hint:(NSString *)hint;
// 设置输入框内容
- (void)setDetail:(NSString *)detail;
@end
@implementation UKInputTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self setupInitialUI];
}
return self;
}
- (void)setTitle:(NSString *)title hint:(NSString *)hint {
self.titleLabel.text = title;
NSDictionary *attrs = @{
NSForegroundColorAttributeName : [UIColor darkGrayColor]
};
NSAttributedString *attrText = [[NSAttributedString alloc] initWithString:hint attributes:attrs];
[self.contentTextField setAttributedPlaceholder:attrText];
}
- (void)setDetail:(NSString *)detail {
self.contentTextField.text = detail;
}
- (void)setupInitialUI {
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.textColor = [UIColor blackColor];
[_titleLabel setFont:[UIFont systemFontOfSize:17]];
}
return _titleLabel;
}
- (UITextField *)contentTextField {
if (!_contentTextField) {
_contentTextField = [[UITextField alloc] init];
_contentTextField.textColor = [UIColor blackColor];
[_contentTextField setFont:[UIFont systemFontOfSize:15]];
[_contentTextField addTarget:self action:@selector(onInputTextChanged:) forControlEvents:UIControlEventEditingChanged];
}
return _contentTextField;
}
- (void)onInputTextChanged:(UITextField *)textField {
if (self.inputChange) {
self.inputChange(textField.text);
}
}
@end
在UIViewController
里面我们对表格设置内容
#pragma mark - UITableViewDataSource -
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 120;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UKInputTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId" forIndexPath:indexPath];
__weak __typeof(self) weakSelf = self;
if (indexPath.row == 0) {
[cell setTitle:@"姓名" hint:@"请输入姓名"];
[cell setDetail:self.name];
cell.inputChange = ^(NSString * text) {
weakSelf.name = text;
};
} else if (indexPath.row == 1) {
[cell setTitle:@"地址" hint:@"请输入地址"];
[cell setDetail:self.address];
cell.inputChange = ^(NSString * text) {
weakSelf.address = text;
};
} else if (indexPath.row == 2) {
[cell setTitle:@"邮编" hint:@"请输入邮编"];
[cell setDetail:self.zipcode];
cell.inputChange = ^(NSString * text) {
weakSelf.zipcode = text;
};
} else if (indexPath.row == 3) {
[cell setTitle:@"邮箱" hint:@"请输入邮箱"];
[cell setDetail:self.email];
cell.inputChange = ^(NSString * text) {
weakSelf.email = text;
};
} else if (indexPath.row == 4) {
[cell setTitle:@"电话" hint:@"请输入电话"];
[cell setDetail:self.mobile];
cell.inputChange = ^(NSString * text) {
weakSelf.mobile = text;
};
}
return cell;
}
显示如下
2. 软键盘遮挡问题
在iOS UITextField控件里面我们已经讨论过底部UITextField被软键盘遮挡问题,在这里我们遇到了一个新问题,就是如何确定UITextField
的位置。
- (void)keyboardDidShow:(NSNotification *)notification {
// 获取键盘位置
NSDictionary *userinfo = [notification userInfo];
NSValue *value = [userinfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardFrame = [value CGRectValue];
// 在UITableView里面寻找当前编辑的UITextField
UITableViewCell *cell = [self firstResponderCell];
if (cell) {
CGFloat tableTop = kStatusBarHeight + 50;
// cell的位置必须减掉表格偏移量
CGFloat cellMaxY = CGRectGetMaxY(cell.frame) - self.tableView.contentOffset.y + tableTop;
CGFloat bottomHeight = self.view.frame.size.height - cellMaxY;
CGFloat distance = bottomHeight - 10.0 - keyboardFrame.size.height;
if (distance < 0) {
[UIView animateWithDuration:0.5 animations:^{
//将视图的Y坐标向上移动offset个单位,以使下面腾出地方用于软键盘的显示
self.view.frame = CGRectMake(0.0f, distance, self.view.frame.size.width, self.view.frame.size.height);
}];
}
}
}
- (UITableViewCell *)firstResponderCell {
for (UITableViewCell *cell in self.tableView.visibleCells) {
if ([cell isKindOfClass:[UKInputTableViewCell class]]) {
UKInputTableViewCell *visibleCell = (UKInputTableViewCell *)cell;
if (visibleCell.contentTextField.isFirstResponder) {
return cell;
}
}
}
return nil;
}
3. 软键盘隐藏
软键盘弹出后会一直存在,在iOS UITextField控件里面我们已经讨论过两种隐藏软键盘的方式。但UITableView
会拦截点击事件,所以我们需要自定义一个UITableView
,并重写hitTest:withEvent
方法。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
id view = [super hitTest:point withEvent:event];
if (!([view isKindOfClass:[UITextView class]] || [view isKindOfClass:[UITextField class]])) {
[self endEditing:YES];
}
return view;
}
效果如下