【问题标题】:UITableView - resign first responder on outside touchUITableView - 辞去外部接触的第一响应者
【发布时间】:2012-08-04 15:32:56
【问题描述】:

我有一个带有关联 UITableViewController 的 UITableView。但是,我已经修改了表格,使其也有一个带有文本字段子视图的视图。

与往常一样,我希望键盘在用户点击“完成”(简单)以及触摸屏幕上除文本字段以外的任何其他位置(困难、卡住!)时消失。

实现这一点的正常方法是将类更改为 UIControl,以便它可以处理操作......但我不能为我的 UITableView/UITableViewController 组合执行此操作。

我该如何解决这个问题?

【问题讨论】:

    标签: ios xcode cocoa-touch uitableview


    【解决方案1】:

    您可以通过将UITapGestureRecognizer 添加到您的视图来处理用户触摸。
    例如,如果您不想在 tableView 中启用行选择,请致电 self.tableView.allowsSelection = NO;
    但是,如果您仍想检测用户触摸,请在您的 tableView(或 tableView.superview)中添加 UITapGestureRecognizer
    如果您实施UIGestureRecognizerDelegate,您可以拥有更多控制权,这样您就可以检测然后选择女巫触摸接收而不是女巫。
    为此,只需将此代码添加到您的UITableViewController

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.tableView.allowsSelection = NO;
    
        UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped:)];
        tgr.delegate = self;
        [self.tableView addGestureRecognizer:tgr]; // or [self.view addGestureRecognizer:tgr];
        [tgr release];
    }    
    
    - (void)viewTapped:(UITapGestureRecognizer *)tgr
    {
        NSLog(@"view tapped");  
        // remove keyboard
    }
    

    //这是可选的,它让你选择接收女巫触摸,例如这里我正在检查用户是否点击了一个文本字段

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        if ([touch.view isKindOfClass:[UITextField class]]) {
            NSLog(@"User tapped on UITextField");
        }
        return YES; // do whatever u want here
    }
    

    【讨论】:

    • 这很好用。唯一看起来奇怪的是我不得不在 textField 上调用 resignFirstResponder 而不是在通常可以清除键盘的视图上调用。
    • 你通常在 textField 上调用 resignFirstResponder 而不是视图,但如果你真的想要视图的东西(可能不是)你可以调用 [self.view endEditing],我相信这也会做诡计...
    • 正如@Matt Rees 在另一个线程 (stackoverflow.com/a/11142038/285853) 上所指出的,您需要设置 tapGesture.cancelsTouchesInView = NO;如果您希望其他视图继续像往常一样接收触摸。
    • 如果添加 tgr.delegate = self,还需要将 viewController 声明为 UIGestureRecognizerDelegate
    【解决方案2】:

    通常的做法是在键盘视图后面放置一个自定义 UIButton(它仅在 uitextfield 开始编辑时才可见),当用户点击屏幕时,他实际上点击了该按钮,相关的选择器可以退出第一响应者。

    -(void) closeKeyboard:(UIButton *) b {
        [self.view endEditing:YES]; //assuming self is your top view controller.
        [b setHidden:YES];  
    }
    

    使用 endEditing 更好,因为它会遍历所有子视图并查找当前的第一响应者。

    【讨论】:

    • 这是否意味着他们无法轻松单击文本字段本身,例如选择和移动光标?
    • 如果您将此按钮放在 uitextfield 下,那么不,它不会
    • 赞成将我指向endEditing: 方法。如果单击菜单按钮,我想关闭键盘。这很容易。
    【解决方案3】:

    在启用 ARC 的情况下使用分配中断

    只需将以下内容添加到 viewController

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    {
        //where text field is a @property (nonatomic,retain) IBOutlet to your textfield
        [textField resignFirstResponder]; 
    }
    

    【讨论】:

      【解决方案4】:

      当点击一行时,didSelectRowAtIndexPath 被调用。如果点击位于行内的文本字段,则调用文本字段委托。

      所以除了你的完成按钮方法之外,在didSelectRowAtIndexPath 中添加一个检查作为第一响应者的文本字段并要求它辞职。假设选中的 indexPath 不是文本字段的行。

      【讨论】:

      • 我不希望表格中的行是可选的。所以我认为这种方法行不通。
      • 设置选择颜色等于 cellForRowAtIndexpath 中的背景颜色。在 didSelectRowAtIndexPath 中立即取消选择任何选定的行。效果应该是你所追求的
      猜你喜欢
      • 1970-01-01
      • 2012-05-17
      • 2011-04-07
      • 2017-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多