iOS UITableViewCell内嵌UITextField

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;
}

显示如下
iOS UITableViewCell内嵌UITextField_第1张图片

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;
}

效果如下

iOS UITableViewCell内嵌UITextField_第2张图片

你可能感兴趣的:(IOS,应用,ios,UITableViewCell,UITextField)