触摸从 UITableViewController 开始

发布于 2024-11-14 17:15:12 字数 282 浏览 4 评论 0原文

我在 UITableViewController 子类中定义此方法:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    NSLog(@"touch began");
}

但它没有被触发。 UIViewController 是 UIResponder 的子类,所以它应该可以工作,对吧? 谢谢

I am defining this method in my UITableViewController subclass:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    NSLog(@"touch began");
}

but it's not being triggered. UIViewController is a subclass of UIResponder so it should work, right?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

囍笑 2024-11-21 17:15:12

如果您尝试关闭 UITableViewController 中的键盘,一个不错的解决方案是在 tableView 委托的 didSelectRowAtIndexPath 方法中调用 resignFirstResponder 。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [myTextField resignFirstResponder];

    // Rest of your actual didSelectRowAtIndexPath code ...
}

If you are trying to dismiss a keyboard in a UITableViewController, a decent solution is to call resignFirstResponder in the tableView delegate's didSelectRowAtIndexPath method.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [myTextField resignFirstResponder];

    // Rest of your actual didSelectRowAtIndexPath code ...
}
三岁铭 2024-11-21 17:15:12

是的,那绝对应该有效。

确保为此控制器对应的视图设置“用户交互启用”。

如果视图是从 nib/xib 加载的,请确保将文件所有者设置为适当的类名,并且将文件所有者的 view 出口连接到正确的视图。

更新:我也看到了这种行为,使用使用基于导航的应用程序模板构建的应用程序,但使用基于视图的应用程序模板,它可以按预期工作。

我认为在导航控制器的情况下,嵌入视图控制器中的表视图会在视图控制器之前获取事件。请参阅 UIView 参考(强调矿):

视图控制器本身
UIResponder 类的后代
并插入响应者中
托管根视图之间的链
及其超级视图,通常
属于不同的观点
控制器。 如果视图控制器的视图不处理事件
视图控制器本身有这个选项
在通过之前处理事件
事件沿着超级视图。

这意味着视图有第一次机会处理该事件,如果有的话,视图控制器将无法获取它。

不太清楚你想要完成什么,所以我不确定要提供什么解决方案。

Yep, that should definitely work.

Make sure User Interaction Enabled is set for the view this controller corresponds to.

If the view is loaded from a nib/xib, make sure File's Owner is set to be the appropriate class name, and File's Owner's view outlet is connected to proper the view.

Update: I see this behavior as well, using an app built with the Nav-based App template, but with a View-based App template, it works as expected.

I think that in the case of a Navigation Controller, the table view embedded in the view controller is getting the event before the view controller does. See the UIView reference (emphasis mine):

View controllers are themselves
descendants of the UIResponder class
and are inserted into the responder
chain between the managed root view
and its superview, which typically
belongs to a different view
controller. If the view controller’s view does not handle an event, the
view controller itself has the option
of handling the event before passing
the event along to the superview.

This implies that the view has the first chance to handle the event, and if it does, the view controller won't get it.

Not exactly clear what you're trying to accomplish, so I'm not sure what solution to offer.

初相遇 2024-11-21 17:15:12

我刚刚遇到了与原始帖子完全相同的问题。我通过创建 UITableView 的子类并覆盖“touchesBegan”方法解决了这个问题。我还创建了一个协议,以便 UITableView 可以调用 UITableViewController 上的方法,这最终是我想要处理“touchesBegan”事件的地方。

这是 UITableView 子类型的标题:

@protocol AGSTableViewDelegate;

@interface AGSTableView : UITableView
@property (nonatomic, weak) id<AGSTableViewDelegate> agsDelegate;
@end

@protocol AGSTableViewDelegate<NSObject>
-(void)tableViewTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end

和实现:

@implementation AGSTableView

@synthesize agsDelegate;

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{    
    [super touchesBegan:touches withEvent:event];

    if (agsDelegate)
        [agsDelegate tableViewTouchesBegan:touches withEvent:event];
}
@end

最后,来自 UITableViewController 的代码片段:

@interface AGSWasteUpdateTableController ()<AGSTableViewDelegate>
@end

- (void)viewDidLoad
{
    AGSTableView *tableView = (AGSTableView *)[self tableView];
    tableView.agsDelegate = self;
}

-(void)tableViewTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [yourTextField resignFirstResponder];
}

希望这会有所帮助......

I just ran into the exact issue as the original posting. I got around the issue by creating a subclass of UITableView and overriding the "touchesBegan" method. I also created a protocol so the UITableView could call a method on the UITableViewController, which is ultimately where I wanted to handle the "touchesBegan" event.

Here is the header for UITableView subtype:

@protocol AGSTableViewDelegate;

@interface AGSTableView : UITableView
@property (nonatomic, weak) id<AGSTableViewDelegate> agsDelegate;
@end

@protocol AGSTableViewDelegate<NSObject>
-(void)tableViewTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end

And implementation:

@implementation AGSTableView

@synthesize agsDelegate;

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{    
    [super touchesBegan:touches withEvent:event];

    if (agsDelegate)
        [agsDelegate tableViewTouchesBegan:touches withEvent:event];
}
@end

And finally, the code fragments from UITableViewController:

@interface AGSWasteUpdateTableController ()<AGSTableViewDelegate>
@end

- (void)viewDidLoad
{
    AGSTableView *tableView = (AGSTableView *)[self tableView];
    tableView.agsDelegate = self;
}

-(void)tableViewTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [yourTextField resignFirstResponder];
}

Hope this helps...

倾`听者〃 2024-11-21 17:15:12

Swift 版本,因为我刚刚遇到了这个问题:

import UIKit

class BubbleTouchesTableView: UITableView {

    // Designed to bubble up touches from a UITableView

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        self.nextResponder()?.touchesBegan(touches, withEvent: event)
    }

    override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
        super.touchesCancelled(touches, withEvent: event)
        self.nextResponder()?.touchesCancelled(touches, withEvent: event)
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        self.nextResponder()?.touchesEnded(touches, withEvent: event)
    }

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        self.nextResponder()?.touchesMoved(touches, withEvent: event)
    }

}

Swift Version because I just had this very issue:

import UIKit

class BubbleTouchesTableView: UITableView {

    // Designed to bubble up touches from a UITableView

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        self.nextResponder()?.touchesBegan(touches, withEvent: event)
    }

    override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
        super.touchesCancelled(touches, withEvent: event)
        self.nextResponder()?.touchesCancelled(touches, withEvent: event)
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        self.nextResponder()?.touchesEnded(touches, withEvent: event)
    }

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        self.nextResponder()?.touchesMoved(touches, withEvent: event)
    }

}
猫九 2024-11-21 17:15:12

您需要将触摸传递到响应者链。我们可以通过子类化 UITableView 并覆盖 TouchBegan(以及其他需要的),然后将触摸沿着响应者链传递到 UITableViewController 来实现这一点。

UITableViewTouch.h:

#import <UIKit/UIKit.h>

@interface UITableViewTouch : UITableView

@end

UITableViewTouch.m:

#import "UITableViewTouch.h"

@implementation UITableViewTouch

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    [[self nextResponder] touchesCancelled:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [[self nextResponder] touchesEnded:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    [[self nextResponder] touchesMoved:touches withEvent:event];
}

@end

You need to pass the touches up the responder chain. We can do this by subclassing UITableView and overriding touchesBegan (and others if needed) and then passing the touches up the responder chain to the UITableViewController.

UITableViewTouch.h:

#import <UIKit/UIKit.h>

@interface UITableViewTouch : UITableView

@end

UITableViewTouch.m:

#import "UITableViewTouch.h"

@implementation UITableViewTouch

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    [[self nextResponder] touchesCancelled:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [[self nextResponder] touchesEnded:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    [[self nextResponder] touchesMoved:touches withEvent:event];
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文