从单例获取触摸坐标

7

您好,我正在使用以下代码片段来获取给定类中触摸的X和Y坐标以及ViewController的名称:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self.view];
    NSLog(@"Began: %@ X location: %0.2f", NSStringFromClass([self class]), point.x);
    NSLog(@"Began: %@ Y location: %0.2f", NSStringFromClass([self class]), point.y);
}

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self.view];
    NSLog(@"Ended:%@ X location: %0.2f", NSStringFromClass([self class]), point.x);
    NSLog(@"Ended:%@ Y Location: %0.2f", NSStringFromClass([self class]), point.y);
}

最初我只想在两个视图控制器中执行此操作,但现在我希望在所有类中都执行。我必须在每个类中编写这些片段才能做到这一点吗?还是可以使用单例实例?

这是我的单例类代码:

QuestionAlert.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface QuestionAlert : NSObject
+(id)sharedManager;
@end

QuestionAlert.m

#import "QuestionAlert.h"

@implementation QuestionAlert

+(id)sharedManager{
    static QuestionAlert *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
    //defines a static variable sharedMyManager and is initialised only once in sharedManager
}


-(id)init{
    if(self = [super init]){
        //initialisations
    }
    return self;
}

-(void)dealloc{
    //should never be called but here just for clarity
}
@end

赏金后编辑:如建议所述,我在我的框架中使用了一个UIViewController(假设为MagicViewController),并在该控制器中编写了触摸手势跟踪代码片段。我已将框架提供给客户,并要求他将所有类都作为'MagicViewController'的子类,以便在不需要编写任何其他代码的情况下存储他的触摸数据(当然,他必须添加我们的框架)作为应用程序中的嵌入式二进制文件。但是他不愿意让他的类成为'MagicViewController'的子类。有没有其他方法实现这个目的?我看到一些像appanalytics.io、appsee.io这样的人可以跟踪触摸数据而无需编写任何代码。


2
使用基类。 - rmaddy
嘿@rmaddy,感谢您的及时回复。作为一个初学者,您能详细解释一下吗? - Vamshi Krishna
另一种拦截触摸事件的方法是在UIWindow级别捕获它们。 - Aris
3个回答

3

通用功能应该放在一个基类中。编写自己的自定义视图控制器类,称为MyViewController(或其他有用的名称),让它扩展UIViewController,并将通用视图控制器代码放入该类中。

然后,让所有实际的视图控制器类扩展MyViewController而不是UIViewController。这样,所有的视图控制器都将拥有添加到基类的通用功能。

您的单例类与此无关。


正在处理中。会尽快回复。 - Vamshi Krishna
这个很好用。但我的最终目标是将这个片段导出为静态库或Cocoa Touch框架,以便我可以在其他应用程序中使用它来跟踪触摸坐标。使用基类无法满足我的目的。 - Vamshi Krishna
为什么你的库中不能有一个基类?可以在其他应用程序中使用该库,并使所有应用程序都使用基类。 - rmaddy
完成。目前已点赞但未标记。有没有办法通过一个单例实例而不是所有视图控制器子类化'MyViewController'来跟踪触摸坐标的库?类似于AppAnalytics和Appsee所做的那样? - Vamshi Krishna

3

只需创建UIViewController的一个扩展,并让客户端在导入包含此扩展的库标头之后使用。完成此操作后,每个视图控制器都将具有以下方法:

extension UIViewController {
 override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent)
 {
   //The Swift implementation you need to execute in all UIViewController instances
 }

 override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent)
 {
   //The Swift implementation you need to execute in all UIViewController instances
 }
}
编辑:以上是用Swift编写的。对于使用Obj-C的情况,您可以创建一个UIViewController类别,如下所示:
@interface UIViewController (TouchesAdditions)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
@end

@implementation UIViewController (TouchesAdditions)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self.view];
    NSLog(@"Began: %@ X location: %0.2f", NSStringFromClass([self class]), point.x);
    NSLog(@"Began: %@ Y location: %0.2f", NSStringFromClass([self class]), point.y);
}

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self.view];
    NSLog(@"Ended:%@ X location: %0.2f", NSStringFromClass([self class]), point.x);
    NSLog(@"Ended:%@ Y Location: %0.2f", NSStringFromClass([self class]), point.y);
}
@end

'MagicViewController'的扩展?我该怎么做? - Vamshi Krishna
如果MagicViewController是UIViewController类型,则可以在MagicViewController.swift中添加扩展。扩展必须扩展像UIViewController这样的本地类型,以便您的客户无需更改任何内容,而不是扩展MagicViewController,因为该类对于客户的开发人员不可用也不可访问。 - TechSeeko
你打算用哪种语言来回答这个问题?!? - Wain
我应该把这个代码片段放在哪里?是在MagicViewController中吗? - Vamshi Krishna
嘿!看起来它正在工作。给我一些时间。我会回复你的 :) - Vamshi Krishna
显示剩余5条评论

1
这可以通过方法混淆来实现,无需子类。方法混淆是改变现有选择器实现的过程。这是一种技术,由于Objective-C中的方法调用可以在运行时更改,因此可以通过更改选择器在类的分发表中映射到底层函数的方式来实现。参考:http://nshipster.com/method-swizzling/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接