Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Touch Coordinates from a Singleton

Hi I am using the below snippets to get X and Y coordinates of touch and name of ViewController in a given class:

- (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);
}

Initially I wanted to do it only for two ViewControllers but now I want to do it for all the classes. Do I have to write these snippets in every class to do the needful or can I use a singleton instance?

This is my Singleton class code:

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

EDIT after bounty: As suggested, I have used an UIViewController (say MagicViewController) in my Framework and have written touch gesture tracking snippets in that controller. I have taken the framework to my client and asked him to make all his classes a subclass of my 'MagicViewController', in order to store his touch data without him having to write any other code (of course, he will have to add our framework) as Embedded binary in his app. But he is not willing to make his classes a subclass of 'MagicViewController'. Is there any other way to achieve this purpose?I have seen some guys like appanalytics.io, appsee.io track touch data without having to write any code.

like image 280
Vamshi Krishna Avatar asked Aug 25 '16 02:08

Vamshi Krishna


3 Answers

Common functionality belongs in a base class. Write your own custom view controller class called MyViewController (or some other useful name), have it extend UIViewController, and put your common view controller code into that class.

Then have all of your actual view controller classes extend MyViewController instead of UIViewController. This way all of your view controllers will have all of the common functionality added to your base class.

Your singleton class would have nothing to do with this.

like image 55
rmaddy Avatar answered Oct 22 '22 19:10

rmaddy


Just create an extension of UIViewController and let your client (answering after the EDIT) import your library header where this extension is imported. Once that is done, every View Controller will have the methods below:

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
 }
}

EDIT: The above is in Swift. In your case for Obj-C you can create a Category of UIViewController like the below:

@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
like image 3
TechSeeko Avatar answered Oct 22 '22 21:10

TechSeeko


This can be achieved with method swizzling. No subclass needed.

Method swizzling is the process of changing the implementation of an existing selector. It’s a technique made possible by the fact that method invocations in Objective-C can be changed at runtime, by changing how selectors are mapped to underlying functions in a class’s dispatch table. check: http://nshipster.com/method-swizzling/

like image 1
rafaperez Avatar answered Oct 22 '22 21:10

rafaperez