我有一个简单的自定义表视图单元格,它有一个标签和一个文本字段。在情节提要中如下所示:
我想在用户单击单元格中的任何位置时显示键盘,包括他们是否单击标签。我99%确定实现这一点的方法是在单击单元格时调用becomeFirstResponse der。
这是我的简单ViewController:
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView setEstimatedRowHeight:44.0f];
[self.tableView setRowHeight:UITableViewAutomaticDimension];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"custom"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
BOOL firstResponder = [cell becomeFirstResponder];
}
以及我的自定义表视图单元格:
#import "CustomTableViewCell.h"
@implementation CustomTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (BOOL) canBecomeFirstResponder {
return YES;
}
- (BOOL) becomeFirstResponder {
return [self.textField becomeFirstResponder];
}
@end
我验证了成为第一响应者被调用,但是返回的是假的。我错过了什么?
正如 @alex-i 在此处的评论中指出的那样思考:
当文本字段在成为第一响应者的同时从视图/窗口层次结构中短暂删除时,也会出现此[文本字段未成为第一响应者](例如,重新加载保存该文本字段的UITableView或UICollectionView)。
这将发生在选择上。
您可以通过以下操作将UIMapGestureRecognizer添加到tableView,而不是使用didSelectRowAtIndexPath:
- (IBAction)tap:(UITapGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
BOOL firstResponder = [cell becomeFirstResponder];
}
它将成为第一响应者。
如果有人需要一个快速的替代方案:您可以将外部UIViews与插座集合连接起来。在每个UIViewController类上,您都可以在下面调用一次。因此,当触摸外部框时,editfield将使用键盘激活。您也可以将其应用于您的标签。(通过禁用标签的用户交互)
@IBOutlet var outerBoxes:[UIView]!
override func viewDidLoad() {
super.viewDidLoad();
for outerBox in outerBoxes { outerBox.respondForEditBox() };
...
但是一旦你有了这个代码:
extension UIView {
func respondForEditBox() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIView.focusOnEditBox));
self.addGestureRecognizer(tap);
}
func focusOnEditBox() {
for sview in self.subviews {
if sview is UITextField {
sview.becomeFirstResponder();
}
}
}
}
灵感来自 @Esqarrouth 在关闭 iOS 键盘上的回答,通过使用 Swift 触摸任何地方