我现在试图这样做几天,在阅读了大量试图这样做的人的消息之后,我仍然无法UITextField
在我的一些人中完全工作UITableViewCells
,就像在这个例子中一样:
要么我的表单工作,但文本不可见(虽然我将其颜色设置为蓝色),当我点击它时键盘在场上,我无法正确实现键盘事件.我尝试了一些来自Apple的例子(主要是UICatalog
,有一个类似的控件),但它仍然无法正常工作.
有人可以帮我(和所有的人试图实现这种控制)和后一个简单实现的UITextField
一个UITableViewCell
,工作正常?
试试吧.对我来说就像一个魅力(在iPhone设备上).我将此代码用于登录屏幕一次.我将表视图配置为包含两个部分.你当然可以摆脱部分条件.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease]; cell.accessoryType = UITableViewCellAccessoryNone; if ([indexPath section] == 0) { UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)]; playerTextField.adjustsFontSizeToFitWidth = YES; playerTextField.textColor = [UIColor blackColor]; if ([indexPath row] == 0) { playerTextField.placeholder = @"example@gmail.com"; playerTextField.keyboardType = UIKeyboardTypeEmailAddress; playerTextField.returnKeyType = UIReturnKeyNext; } else { playerTextField.placeholder = @"Required"; playerTextField.keyboardType = UIKeyboardTypeDefault; playerTextField.returnKeyType = UIReturnKeyDone; playerTextField.secureTextEntry = YES; } playerTextField.backgroundColor = [UIColor whiteColor]; playerTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support playerTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support playerTextField.textAlignment = UITextAlignmentLeft; playerTextField.tag = 0; //playerTextField.delegate = self; playerTextField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right [playerTextField setEnabled: YES]; [cell.contentView addSubview:playerTextField]; [playerTextField release]; } } if ([indexPath section] == 0) { // Email & Password Section if ([indexPath row] == 0) { // Email cell.textLabel.text = @"Email"; } else { cell.textLabel.text = @"Password"; } } else { // Login button section cell.textLabel.text = @"Log in"; } return cell; }
结果如下所示:
这是一个在iOS6/7/8/9下看起来不错的解决方案.
更新2016-06-10:这仍适用于iOS 9.3.3
感谢您的支持,现在可以通过https://github.com/fulldecent/FDTextFieldTableViewCell访问CocoaPods/Carthage/SPM
基本上我们把库存UITableViewCellStyleValue1
和主食UITextField
放在detailTextLabel
应该的位置.这为我们提供了所有场景的自动放置:iOS6/7/8/9,iPhone/iPad,图像/无图像,附件/无附件,纵向/横向,1x/2x/3x.
注意:这是使用故事板与UITableViewCellStyleValue1
名为"word" 的类型单元格.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { cell = [tableView dequeueReusableCellWithIdentifier:@"word"]; cell.detailTextLabel.hidden = YES; [[cell viewWithTag:3] removeFromSuperview]; textField = [[UITextField alloc] init]; textField.tag = 3; textField.translatesAutoresizingMaskIntoConstraints = NO; [cell.contentView addSubview:textField]; [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:cell.textLabel attribute:NSLayoutAttributeTrailing multiplier:1 constant:8]]; [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1 constant:8]]; [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1 constant:-8]]; [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:cell.detailTextLabel attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]]; textField.textAlignment = NSTextAlignmentRight; textField.delegate = self; return cell; }
以下是我如何实现这一目标:
TextFormCell.h
#import#define CellTextFieldWidth 90.0 #define MarginBetweenControls 20.0 @interface TextFormCell : UITableViewCell { UITextField *textField; } @property (nonatomic, retain) UITextField *textField; @end
TextFormCell.m
#import "TextFormCell.h" @implementation TextFormCell @synthesize textField; - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithReuseIdentifier:reuseIdentifier]) { // Adding the text field textField = [[UITextField alloc] initWithFrame:CGRectZero]; textField.clearsOnBeginEditing = NO; textField.textAlignment = UITextAlignmentRight; textField.returnKeyType = UIReturnKeyDone; [self.contentView addSubview:textField]; } return self; } - (void)dealloc { [textField release]; [super dealloc]; } #pragma mark - #pragma mark Laying out subviews - (void)layoutSubviews { CGRect rect = CGRectMake(self.contentView.bounds.size.width - 5.0, 12.0, -CellTextFieldWidth, 25.0); [textField setFrame:rect]; CGRect rect2 = CGRectMake(MarginBetweenControls, 12.0, self.contentView.bounds.size.width - CellTextFieldWidth - MarginBetweenControls, 25.0); UILabel *theTextLabel = (UILabel *)[self textLabel]; [theTextLabel setFrame:rect2]; }
它可能看起来有点冗长,但它的确有效!
别忘了设置代表!
试试这个吧.它也可以处理滚动,您可以重复使用单元格,而无需删除之前添加的子视图.
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{ return 10; } - (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:@"Cell"]; if( cell == nil) cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease]; cell.textLabel.text = [[NSArray arrayWithObjects:@"First",@"Second",@"Third",@"Forth",@"Fifth",@"Sixth",@"Seventh",@"Eighth",@"Nineth",@"Tenth",nil] objectAtIndex:indexPath.row]; if (indexPath.row % 2) { UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 21)]; textField.placeholder = @"Enter Text"; textField.text = [inputTexts objectAtIndex:indexPath.row/2]; textField.tag = indexPath.row/2; textField.delegate = self; cell.accessoryView = textField; [textField release]; } else cell.accessoryView = nil; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } - (BOOL)textFieldShouldEndEditing:(UITextField *)textField { [inputTexts replaceObjectAtIndex:textField.tag withObject:textField.text]; return YES; } - (void)viewDidLoad { inputTexts = [[NSMutableArray alloc] initWithObjects:@"",@"",@"",@"",@"",nil]; [super viewDidLoad]; }
这应该不难.为表创建单元格时,将UITextField对象添加到单元格的内容视图中
UITextField *txtField = [[UITextField alloc] initWithFrame....] ... [cell.contentView addSubview:txtField]
将UITextField的委托设置为self(即viewcontroller)为文本字段指定标记,以便您可以识别在委托方法中编辑的文本字段.当用户点击文本字段时,键盘应弹出.我让它像这样工作.希望能帮助到你.
[cell.contentView bringSubviewToFront:textField]
每次我的细胞出现时,我都会通过调用一种方法来避免这种情况,但后来我发现了这种相对简单的技术:
cell.accessoryView = textField;
似乎没有相同的背景覆盖问题,并且它自己(有点)对齐.此外,textLabel自动截断以避免溢出(或在其下),这很方便.
Xcode 8.2.1,Swift 3
在UITableViewCell中创建UITextField并将UITextField编辑功能委托给ViewController
class ViewController
import UIKit protocol TextFieldInTableViewCellDelegate: class { func textField(editingDidBeginIn cell:TextFieldInTableViewCell) func textField(editingChangedInTextField newText: String, in cell: TextFieldInTableViewCell) } class TextFieldInTableViewCell: UITableViewCell { private(set) weak var textField: UITextField? private(set) weak var descriptionLabel: UILabel? weak var delegate: TextFieldInTableViewCellDelegate? override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupSubviews() } private func setupSubviews() { let stackView = UIStackView() stackView.distribution = .fill stackView.alignment = .leading stackView.spacing = 8 contentView.addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false stackView.topAnchor.constraint(equalTo: topAnchor, constant: 6).isActive = true stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -6).isActive = true stackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 16).isActive = true stackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -16).isActive = true let label = UILabel() label.text = "Label" stackView.addArrangedSubview(label) descriptionLabel = label let textField = UITextField() textField.textAlignment = .left textField.placeholder = "enter text" textField.setContentHuggingPriority(.fittingSizeLevel, for: .horizontal) stackView.addArrangedSubview(textField) textField.addTarget(self, action: #selector(textFieldValueChanged(_:)), for: .editingChanged) textField.addTarget(self, action: #selector(editingDidBegin), for: .editingDidBegin) self.textField = textField stackView.layoutSubviews() selectionStyle = .none let gesture = UITapGestureRecognizer(target: self, action: #selector(didSelectCell)) addGestureRecognizer(gesture) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } } extension TextFieldInTableViewCell { @objc func didSelectCell() { textField?.becomeFirstResponder() } @objc func editingDidBegin() { delegate?.textField(editingDidBeginIn: self) } @objc func textFieldValueChanged(_ sender: UITextField) { if let text = sender.text { delegate?.textField(editingChangedInTextField: text, in: self) } } }
class TextFieldInTableViewCell
import UIKit class ViewController: UIViewController { private weak var tableView: UITableView? override func viewDidLoad() { super.viewDidLoad() setupTableView() } } extension ViewController { func setupTableView() { let tableView = UITableView(frame: .zero) tableView.register(TextFieldInTableViewCell.self, forCellReuseIdentifier: "TextFieldInTableViewCell") view.addSubview(tableView) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = UITableView.automaticDimension tableView.tableFooterView = UIView() self.tableView = tableView tableView.dataSource = self let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:))) tableView.addGestureRecognizer(gesture) } } extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldInTableViewCell") as! TextFieldInTableViewCell cell.delegate = self return cell } } extension ViewController: TextFieldInTableViewCellDelegate { func textField(editingDidBeginIn cell: TextFieldInTableViewCell) { if let indexPath = tableView?.indexPath(for: cell) { print("textfield selected in cell at \(indexPath)") } } func textField(editingChangedInTextField newText: String, in cell: TextFieldInTableViewCell) { if let indexPath = tableView?.indexPath(for: cell) { print("updated text in textfield in cell as \(indexPath), value = \"\(newText)\"") } } }
协议TextFieldInTableViewCellDelegate
import UIKit protocol TextFieldInTableViewCellDelegate: class { func textField(editingDidBeginIn cell:TextFieldInTableViewCell) func textField(editingChangedInTextField newText: String, in cell: TextFieldInTableViewCell) } class TextFieldInTableViewCell: UITableViewCell { private(set) weak var textField: UITextField? private(set) weak var descriptionLabel: UILabel? weak var delegate: TextFieldInTableViewCellDelegate? override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupSubviews() } private func setupSubviews() { let stackView = UIStackView() stackView.distribution = .fill stackView.alignment = .leading stackView.spacing = 8 contentView.addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false stackView.topAnchor.constraint(equalTo: topAnchor, constant: 6).isActive = true stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -6).isActive = true stackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 16).isActive = true stackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -16).isActive = true let label = UILabel() label.text = "Label" stackView.addArrangedSubview(label) descriptionLabel = label let textField = UITextField() textField.textAlignment = .left textField.placeholder = "enter text" textField.setContentHuggingPriority(.fittingSizeLevel, for: .horizontal) stackView.addArrangedSubview(textField) textField.addTarget(self, action: #selector(textFieldValueChanged(_:)), for: .editingChanged) textField.addTarget(self, action: #selector(editingDidBegin), for: .editingDidBegin) self.textField = textField stackView.layoutSubviews() selectionStyle = .none let gesture = UITapGestureRecognizer(target: self, action: #selector(didSelectCell)) addGestureRecognizer(gesture) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } } extension TextFieldInTableViewCell { @objc func didSelectCell() { textField?.becomeFirstResponder() } @objc func editingDidBegin() { delegate?.textField(editingDidBeginIn: self) } @objc func textFieldValueChanged(_ sender: UITextField) { if let text = sender.text { delegate?.textField(editingChangedInTextField: text, in: self) } } }
Main.storyboard
import UIKit class ViewController: UIViewController { private weak var tableView: UITableView? override func viewDidLoad() { super.viewDidLoad() setupTableView() } } extension ViewController { func setupTableView() { let tableView = UITableView(frame: .zero) tableView.register(TextFieldInTableViewCell.self, forCellReuseIdentifier: "TextFieldInTableViewCell") view.addSubview(tableView) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = UITableView.automaticDimension tableView.tableFooterView = UIView() self.tableView = tableView tableView.dataSource = self let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:))) tableView.addGestureRecognizer(gesture) } } extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldInTableViewCell") as! TextFieldInTableViewCell cell.delegate = self return cell } } extension ViewController: TextFieldInTableViewCellDelegate { func textField(editingDidBeginIn cell: TextFieldInTableViewCell) { if let indexPath = tableView?.indexPath(for: cell) { print("textfield selected in cell at \(indexPath)") } } func textField(editingChangedInTextField newText: String, in cell: TextFieldInTableViewCell) { if let indexPath = tableView?.indexPath(for: cell) { print("updated text in textfield in cell as \(indexPath), value = \"\(newText)\"") } } }