在输入另一个单元格后,如何在单元格中启用禁用的文本字段?
How do I enable a disabled textfield in a cell after typing in another one?
我有一个包含三个单元格的 table 视图控制器,每个单元格都有一个用户定义的文本字段:
-国家
-状态(禁用)
-城市(已禁用)
如何在用户输入 "Country" 后启用 "State" 文本字段?
主要问题是我正在使用一个名为 "Field" 的模型,它有一个名为 "depends" 的 属性,它显示了另一个字段的 ID,该字段不能是空。
我的自定义 table 视图单元格有一个 属性 "Field"。
如果我使用 "textfieldDidBeginEditing()",我只能访问单元格内的文本字段,而不能访问 "Field" 属性。
我所有的单元格都是动态创建的。
项目在Objective-C。
很简单,这是你的步骤
- 将 textfield.delegate 设置为您的 UIViewController
- 实现 UITextFieldDelegate 方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
- 如果需要检查文本长度
使用以下代码获取您想要启用的下一个单元格:
UITableViewCell *thisCell = [textView superCell];
NSIndexPath *thisIndexPath = [tableView indexPathForCell:thisCell];
NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:thisIndexPath.row inSection:thisIndexPath.section];
UITableViewCell *nextCell = [tableView cellForRowAtIndexPath: nextIndexPath];
为 nextCell
中的文本字段调用 becomeFirstResponder
您需要使用以下方法创建一个 UIView 类别,上面的代码才能正常工作
- (UITableViewCell *)superCell {
UIView *cell = self;
do {
cell = cell.superview;
} while( ![cell isKindOfClass:[UITableViewCell class]] && cell != nil );
return (UITableViewCell *)cell;
}
有一个按钮:
-(IBAction) continueButton: (UIButton*) sender{
//check if the state textfield is not empty in order to proceed
if(![self.stateTextfield.text isEqualToString: @""]){
self.cityTextfield.enabled = YES;
}
}
四处逛逛很简单,但不是很干净。
更新
- 使用普通的视图控制器。
- 将容器视图拖到视图控制器中,以允许捕获数据的 table 视图的大小。
- 删除自动生成的View Controller,拖一个Table View Controller到storyboard上,嵌入到Container View中(ctrl + drag and select embed in选项)
- 将此 table 视图设置为静态。
- 拖一个TableView(notTableViewController)到ViewController.
- Ctrl + 从 TableView 拖动到 View Controller 图标并设置数据源和委托。这将允许数据加载到 table 视图。
现在这应该可以解决加载数据的任何问题,因为数据将加载到动态 table 视图中,而静态 table 视图将保持不变(如果这对您来说是一个可行的选择) .这样您就可以将文本字段连接到视图控制器并访问它们的属性。
如果您需要任何帮助或者这不是一个好的解决方案,请告诉我。
使用 UITextFieldDelegate 的 textFielShouldBeginEditing 方法
声明
SWIFT
optional func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool
OBJECTIVE-C
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
示例-
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//do state button enabled task here
}
简短:
对于像您这样的简短列表(table 视图可以将所有单元格放在屏幕上),保留对所有三个字段的引用就足够了:
// Your model
@interface AddressStorageModel : NSObject
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* state;
@property (strong, nonatomic) NSString* city;
@end
// Your cell
@interface FieldTableCell : UITableViewCell
@property (readonly, nonatomic) UITextField* textField;
@end
// Your view controller implementation
@implementation ViewController
{
__weak UITextField* _countryField;
__weak UITextField* _stateField;
__weak UITextField* _cityField;
AddressStorageModel* _addressStorage;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.textField.delegate = self;
switch (indexPath.row) {
case 0: // Country
_countryField = cell.textField;
break;
case 1: // State
_stateField = cell.textField;
break;
case 2: // City
_cityField = cell.textField;
break;
}
return cell;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// Validate somehow and move cursor to next field:
if (textField.text.length) {
UITextField* nextTextField = [self p_textFieldNextTo:textField];
[nextTextField setEnabled:YES];
[nextTextField becomeFirstResponder];
}
}
- (UITextField *)p_textFieldNextTo:(UITextField *)textField
{
if (textField == _countryField)
return _stateField;
else if (textField == _stateField)
return _cityField;
return _countryField;
}
- (void)completeButtonAction:(id)sender
{
_addressStorage.country = _countryField.text;
_addressStorage.state = _stateField.text;
_addressStorage.city = _cityField.text;
}
更复杂...但更简单以便将来支持
但是如果您打算增加字段的数量,您应该以这种方式实现您的代码:
// Your model
@interface AddressField : NSObject
@property (strong, nonatomic) NSString* title;
@property (strong, nonatomic) NSString* value;
@property (strong, nonatomic) AddressField* dependency;
@property (strong, nonatomic) NSIndexPath* indexPath;
@end
// Your cell
@protocol FieldTableCellDelegate <NSObject>
@required
- (void)fieldCellDidEndEditing:(FieldTableCell*)cell;
@end
@interface FieldTableCell : UITableViewCell <UITextFieldDelegate>
@property (readonly, weak, nonatomic) AddressField* addressField;
@property (weak, nonatomic) id<FieldTableCellDelegate> delegate;
- (void)configureForField:(AddressField *)field;
- (void)startEditing;
@end
@implementation ViewController
{
NSArray * _fields; // I left to your discretion how to create fields and assign dependencies
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _fields.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.delegate = self;
AddressField * field = _fields[indexPath.row];
field.indexPath = indexPath;
[cell configureForField:field];
return cell;
}
- (void)fieldCellDidEndEditing:(FieldTableCell *)cell
{
typeof(self) __weak weakSelf = self;
[UIView animateWithDuration:0.25
animations:^{
[weakSelf.tableView scrollToRowAtIndexPath:cell.addressField.dependency.indexPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:NO];
}
completion:^(BOOL finished) {
FieldTableCell* nextCell = (FieldTableCell*)[weakSelf.tableView cellForRowAtIndexPath:cell.addressField.dependency.indexPath];
[nextCell startEditing];
}];
}
@end
@implementation FieldTableCell
{
UITextField* _inputField;
}
- (void)configureForField:(AddressField *)field
{
_addressField = field;
_inputField.text = field.value;
_inputField.placeholder = field.title;
// do all other configurations...
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField.text.length > 0) {
_addressField.value = textField.text;
[_delegate fieldCellDidEndEditing:self];
}
}
- (void)startEditing
{
[_inputField becomeFirstResponder];
}
@end
我有一个包含三个单元格的 table 视图控制器,每个单元格都有一个用户定义的文本字段: -国家 -状态(禁用) -城市(已禁用)
如何在用户输入 "Country" 后启用 "State" 文本字段?
主要问题是我正在使用一个名为 "Field" 的模型,它有一个名为 "depends" 的 属性,它显示了另一个字段的 ID,该字段不能是空。
我的自定义 table 视图单元格有一个 属性 "Field"。
如果我使用 "textfieldDidBeginEditing()",我只能访问单元格内的文本字段,而不能访问 "Field" 属性。
我所有的单元格都是动态创建的。
项目在Objective-C。
很简单,这是你的步骤
- 将 textfield.delegate 设置为您的 UIViewController
- 实现 UITextFieldDelegate 方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
- 如果需要检查文本长度
使用以下代码获取您想要启用的下一个单元格:
UITableViewCell *thisCell = [textView superCell]; NSIndexPath *thisIndexPath = [tableView indexPathForCell:thisCell]; NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:thisIndexPath.row inSection:thisIndexPath.section]; UITableViewCell *nextCell = [tableView cellForRowAtIndexPath: nextIndexPath];
为
nextCell
中的文本字段调用 becomeFirstResponder
您需要使用以下方法创建一个 UIView 类别,上面的代码才能正常工作
- (UITableViewCell *)superCell {
UIView *cell = self;
do {
cell = cell.superview;
} while( ![cell isKindOfClass:[UITableViewCell class]] && cell != nil );
return (UITableViewCell *)cell;
}
有一个按钮:
-(IBAction) continueButton: (UIButton*) sender{
//check if the state textfield is not empty in order to proceed
if(![self.stateTextfield.text isEqualToString: @""]){
self.cityTextfield.enabled = YES;
}
}
四处逛逛很简单,但不是很干净。
更新
- 使用普通的视图控制器。
- 将容器视图拖到视图控制器中,以允许捕获数据的 table 视图的大小。
- 删除自动生成的View Controller,拖一个Table View Controller到storyboard上,嵌入到Container View中(ctrl + drag and select embed in选项)
- 将此 table 视图设置为静态。
- 拖一个TableView(notTableViewController)到ViewController.
- Ctrl + 从 TableView 拖动到 View Controller 图标并设置数据源和委托。这将允许数据加载到 table 视图。
现在这应该可以解决加载数据的任何问题,因为数据将加载到动态 table 视图中,而静态 table 视图将保持不变(如果这对您来说是一个可行的选择) .这样您就可以将文本字段连接到视图控制器并访问它们的属性。
如果您需要任何帮助或者这不是一个好的解决方案,请告诉我。
使用 UITextFieldDelegate 的 textFielShouldBeginEditing 方法
声明
SWIFT
optional func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool
OBJECTIVE-C
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
示例-
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//do state button enabled task here
}
简短:
对于像您这样的简短列表(table 视图可以将所有单元格放在屏幕上),保留对所有三个字段的引用就足够了:
// Your model
@interface AddressStorageModel : NSObject
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* state;
@property (strong, nonatomic) NSString* city;
@end
// Your cell
@interface FieldTableCell : UITableViewCell
@property (readonly, nonatomic) UITextField* textField;
@end
// Your view controller implementation
@implementation ViewController
{
__weak UITextField* _countryField;
__weak UITextField* _stateField;
__weak UITextField* _cityField;
AddressStorageModel* _addressStorage;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.textField.delegate = self;
switch (indexPath.row) {
case 0: // Country
_countryField = cell.textField;
break;
case 1: // State
_stateField = cell.textField;
break;
case 2: // City
_cityField = cell.textField;
break;
}
return cell;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// Validate somehow and move cursor to next field:
if (textField.text.length) {
UITextField* nextTextField = [self p_textFieldNextTo:textField];
[nextTextField setEnabled:YES];
[nextTextField becomeFirstResponder];
}
}
- (UITextField *)p_textFieldNextTo:(UITextField *)textField
{
if (textField == _countryField)
return _stateField;
else if (textField == _stateField)
return _cityField;
return _countryField;
}
- (void)completeButtonAction:(id)sender
{
_addressStorage.country = _countryField.text;
_addressStorage.state = _stateField.text;
_addressStorage.city = _cityField.text;
}
更复杂...但更简单以便将来支持
但是如果您打算增加字段的数量,您应该以这种方式实现您的代码:
// Your model
@interface AddressField : NSObject
@property (strong, nonatomic) NSString* title;
@property (strong, nonatomic) NSString* value;
@property (strong, nonatomic) AddressField* dependency;
@property (strong, nonatomic) NSIndexPath* indexPath;
@end
// Your cell
@protocol FieldTableCellDelegate <NSObject>
@required
- (void)fieldCellDidEndEditing:(FieldTableCell*)cell;
@end
@interface FieldTableCell : UITableViewCell <UITextFieldDelegate>
@property (readonly, weak, nonatomic) AddressField* addressField;
@property (weak, nonatomic) id<FieldTableCellDelegate> delegate;
- (void)configureForField:(AddressField *)field;
- (void)startEditing;
@end
@implementation ViewController
{
NSArray * _fields; // I left to your discretion how to create fields and assign dependencies
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _fields.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.delegate = self;
AddressField * field = _fields[indexPath.row];
field.indexPath = indexPath;
[cell configureForField:field];
return cell;
}
- (void)fieldCellDidEndEditing:(FieldTableCell *)cell
{
typeof(self) __weak weakSelf = self;
[UIView animateWithDuration:0.25
animations:^{
[weakSelf.tableView scrollToRowAtIndexPath:cell.addressField.dependency.indexPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:NO];
}
completion:^(BOOL finished) {
FieldTableCell* nextCell = (FieldTableCell*)[weakSelf.tableView cellForRowAtIndexPath:cell.addressField.dependency.indexPath];
[nextCell startEditing];
}];
}
@end
@implementation FieldTableCell
{
UITextField* _inputField;
}
- (void)configureForField:(AddressField *)field
{
_addressField = field;
_inputField.text = field.value;
_inputField.placeholder = field.title;
// do all other configurations...
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField.text.length > 0) {
_addressField.value = textField.text;
[_delegate fieldCellDidEndEditing:self];
}
}
- (void)startEditing
{
[_inputField becomeFirstResponder];
}
@end