কোনও এমকেম্যাপভিউ বা ইউআইবিউবভিউ অবজেক্টগুলিতে ছোঁয়া ইভেন্টগুলিকে কীভাবে আটকাবেন?


96

আমি কী ভুল করছি তা নিশ্চিত নই তবে আমি কোনও MKMapViewবস্তুর ছোঁয়া দেওয়ার চেষ্টা করি । নিম্নলিখিত ক্লাসটি তৈরি করে আমি এটি সাবক্লাস করেছি:

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

@interface MapViewWithTouches : MKMapView {

}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event;   

@end

এবং বাস্তবায়ন:

#import "MapViewWithTouches.h"
@implementation MapViewWithTouches

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event {

    NSLog(@"hello");
    //[super touchesBegan:touches   withEvent:event];

}
@end

তবে দেখে মনে হচ্ছে আমি যখন এই ক্লাসটি ব্যবহার করি তখন কনসোলটিতে কিছুই দেখতে পাই না:

MapViewWithTouches *mapView = [[MapViewWithTouches alloc] initWithFrame:self.view.frame];
[self.view insertSubview:mapView atIndex:0];

আমি কি ভুল করছি কোন ধারণা?

উত্তর:


147

এটি অর্জনের জন্য আমি যে সর্বোত্তম উপায়টি খুঁজে পেয়েছি তা হ'ল জেচার রিকগনিজার with অন্যান্য উপায়গুলি প্রচুর হ্যাকিশ প্রোগ্রামিংয়ের সাথে জড়িত রয়েছে যা অ্যাপল এর কোডটিকে অসম্পূর্ণভাবে ডুপ্লিকেট করে, বিশেষত মাল্টিটুচের ক্ষেত্রে।

আমি যা করি তা এখানে: একটি অঙ্গভঙ্গি সনাক্তকারী কার্যকর করুন যা প্রতিরোধ করা যায় না এবং যা অন্যান্য অঙ্গভঙ্গি সনাক্তকারীদের আটকাতে পারে না। এটিকে মানচিত্রের দৃশ্যে যুক্ত করুন এবং তারপরে আপনার অভিনব রূপে অঙ্গভঙ্গি সনাক্তকারীের ছোঁড়াবেগান, ছোঁয়া মোড ইত্যাদি ব্যবহার করুন।

কোনও এমকেম্যাপভিউয়ের অভ্যন্তরে কোনও ট্যাপ কীভাবে সনাক্ত করবেন (কৌশলগুলি স্যানস)

WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
        self.lockedOnUserLocation = NO;
};
[mapView addGestureRecognizer:tapInterceptor];

ওয়াইল্ডকার্ডেস্টেকার সনাক্তকারী

//
//  WildcardGestureRecognizer.h
//  Copyright 2010 Floatopian LLC. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef void (^TouchesEventBlock)(NSSet * touches, UIEvent * event);

@interface WildcardGestureRecognizer : UIGestureRecognizer {
    TouchesEventBlock touchesBeganCallback;
}
@property(copy) TouchesEventBlock touchesBeganCallback;


@end

ওয়াইল্ডকার্ডেস্টচারআর সনাক্তকারী.এম

//
//  WildcardGestureRecognizer.m
//  Created by Raymond Daly on 10/31/10.
//  Copyright 2010 Floatopian LLC. All rights reserved.
//

#import "WildcardGestureRecognizer.h"


@implementation WildcardGestureRecognizer
@synthesize touchesBeganCallback;

-(id) init{
    if (self = [super init])
    {
        self.cancelsTouchesInView = NO;
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (touchesBeganCallback)
        touchesBeganCallback(touches, event);
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)reset
{
}

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
{
}

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
    return NO;
}

- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
{
    return NO;
}

@end

সুইফট 3

let tapInterceptor = WildCardGestureRecognizer(target: nil, action: nil)
tapInterceptor.touchesBeganCallback = {
    _, _ in
    self.lockedOnUserLocation = false
}
mapView.addGestureRecognizer(tapInterceptor)

ওয়াইল্ডকার্ডগাস্টারআরকগনিজার.সুইফ্ট

import UIKit.UIGestureRecognizerSubclass

class WildCardGestureRecognizer: UIGestureRecognizer {

    var touchesBeganCallback: ((Set<UITouch>, UIEvent) -> Void)?

    override init(target: Any?, action: Selector?) {
        super.init(target: target, action: action)
        self.cancelsTouchesInView = false
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        touchesBeganCallback?(touches, event)
    }

    override func canPrevent(_ preventedGestureRecognizer: UIGestureRecognizer) -> Bool {
        return false
    }

    override func canBePrevented(by preventingGestureRecognizer: UIGestureRecognizer) -> Bool {
        return false
    }
}

4
"লকঅন ইউজারলোকেশন" কিসের জন্য?
jowie

এটি আমার আবেদনের জন্য নির্দিষ্ট একটি বহিরাগত পরিবর্তনশীল। এটি সিস্টেমটি স্বয়ংক্রিয়ভাবে বর্তমান অবস্থানে মানচিত্রটি কেন্দ্র করে কিনা তা ট্র্যাক করে রাখে
gonzojive

এটি নিখুঁত সমাধান। আমার একটি স্পষ্টতা দরকার: পদ্ধতিতে "- (শূন্য) টাচবেগান: (এনএসএসেট *) স্পর্শ করে ইভেন্ট: (ইউআইইভেন্ট *) ইভেন্ট", কোডটি ব্যবহার করার উদ্দেশ্য কী: যদি (স্পর্শব্যাগনক্যালব্যাক) টাচস বিগানক্যালব্যাক (স্পর্শ, ইভেন্ট);
সত্যম

4
এটি বেশিরভাগ অংশের জন্য দুর্দান্ত কাজ করে তবে আমি এটির সাথে একটি সমস্যা পেয়েছি। যদি আপনার ওয়েব ভিউতে এইচটিএমএল videoনিয়ন্ত্রণের সাথে একটি এইচটিএমএল 5 ট্যাগ থাকে তবে অঙ্গভঙ্গি সনাক্তকারী ব্যবহারকারীকে নিয়ন্ত্রণগুলি ব্যবহার করতে সক্ষম হতে বাধা দেবে। আমি এটির জন্য একটি কাজের সন্ধান করছি কিন্তু এখনও এটি খুঁজে পাইনি।
ব্রায়ান ইরেস

ভাগ করার জন্য আপনাকে ধন্যবাদ। মানচিত্রের দৃশ্যের সাথে ব্যবহারকারীর ইন্টারঅ্যাকশনগুলি ট্র্যাক করার জন্য উপযুক্ত প্রতিনিধি পদ্ধতিটি কেন আমার বাইরে নয় তবে এটি ভালভাবে কাজ করে।
জাস্টিন ড্রিসকল

29

একদিন পিজ্জা, চিৎকারের পরে অবশেষে সমাধানটি পেলাম! খুব ঝরঝরে!

পিটার, আমি উপরে আপনার কৌশলটি ব্যবহার করেছি এবং শেষ পর্যন্ত এমকেমেপভিউয়ের সাথে নিখুঁতভাবে কাজ করে এমন একটি সমাধান পেতে এটি কিছুটা সামান্য টুইট করেছিলাম এবং ইউআইউইউভিউউউয়ের সাথেও কাজ করা উচিত

MKTouchAppDelegate.h

#import <UIKit/UIKit.h>
@class UIViewTouch;
@class MKMapView;

@interface MKTouchAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    UIViewTouch *viewTouch;
    MKMapView *mapView;
}
@property (nonatomic, retain) UIViewTouch *viewTouch;
@property (nonatomic, retain) MKMapView *mapView;
@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

MKTouchAppDelegate.m

#import "MKTouchAppDelegate.h"
#import "UIViewTouch.h"
#import <MapKit/MapKit.h>

@implementation MKTouchAppDelegate

@synthesize window;
@synthesize viewTouch;
@synthesize mapView;


- (void)applicationDidFinishLaunching:(UIApplication *)application {

    //We create a view wich will catch Events as they occured and Log them in the Console
    viewTouch = [[UIViewTouch alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];

    //Next we create the MKMapView object, which will be added as a subview of viewTouch
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    [viewTouch addSubview:mapView];

    //And we display everything!
    [window addSubview:viewTouch];
    [window makeKeyAndVisible];


}


- (void)dealloc {
    [window release];
    [super dealloc];
}


@end

ইউআইভিউউউ টু

#import <UIKit/UIKit.h>
@class UIView;

@interface UIViewTouch : UIView {
    UIView *viewTouched;
}
@property (nonatomic, retain) UIView * viewTouched;

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

@end

ইউআইভিউউটিউচ.এম

#import "UIViewTouch.h"
#import <MapKit/MapKit.h>

@implementation UIViewTouch
@synthesize viewTouched;

//The basic idea here is to intercept the view which is sent back as the firstresponder in hitTest.
//We keep it preciously in the property viewTouched and we return our view as the firstresponder.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"Hit Test");
    viewTouched = [super hitTest:point withEvent:event];
    return self;
}

//Then, when an event is fired, we log this one and then send it back to the viewTouched we kept, and voilà!!! :)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Began");
    [viewTouched touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Moved");
    [viewTouched touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Ended");
    [viewTouched touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Cancelled");
}

@end

আমি আশা করি যে আপনাকে কিছু সাহায্য করবে!

চিয়ার্স


14
ভাল লাগল ছোট পরামর্শ: আপনার নিজের ক্লাসের নাম UI উপসর্গ দিয়ে এড়ানো উচিত। অ্যাপল কোনও শ্রেণীর উপসর্গ হিসাবে এনএস বা ইউআই ব্যবহার করে নিরস্ত করে / হতাশ করে, কারণ এগুলি কোনও অ্যাপল শ্রেণির সাথে সংঘর্ষ ঘটতে পারে (এমনকি এটি একটি ব্যক্তিগত শ্রেণি হলেও)।
ড্যানিয়েল ডিকিসন

আরে ড্যানিয়েল, আপনি ঠিক বলেছেন, আমিও ভেবেছিলাম! উপরের আমার উত্তরটি সম্পূর্ণ করতে, আমাকে কিছুটা সতর্কতা যুক্ত করতে দিন: আমার উদাহরণটি ধরে নিই যে কেবলমাত্র একটি অবজেক্ট ভিউ আছে, যা সমস্ত ইভেন্ট গ্রাস করছে। তবে এটি সত্য নয়। আপনার মানচিত্রের উপরে আপনার কিছু টিকা থাকতে পারে এবং তারপরে আমার কোডটি আর কাজ করবে না। ১০০% কাজ করার জন্য, আপনাকে প্রতিটি হিট টেস্টের জন্য সেই নির্দিষ্ট ইভেন্টের সাথে সম্পর্কিত ভিউটি মনে রাখতে হবে (এবং অবশেষে এটি প্রকাশিত হবে যখন টাচ এন্ডড বা স্পর্শকেনসেল্ড ট্রিগার হয় তখন আপনাকে শেষ ইভেন্টগুলির ট্র্যাক রাখার প্রয়োজন হবে না ...)।
মার্টিন

4
খুব কার্যকর কোড, ধন্যবাদ মার্টিন! আমি ভাবছিলাম যে আপনি এটি প্রয়োগের পরে মানচিত্রটিকে চিমটি-জুম করার চেষ্টা করেছেন? আমার জন্য যখন আমি এটি মূলত একই কোডটি ব্যবহার করে কাজ করেছিলাম তখন উপরে যে সমস্ত কিছু রয়েছে তা মানচিত্রের জিমিং বাদ দেওয়া বাদ দিয়ে কাজ করবে বলে মনে হয়েছিল। কারো কোন ধারণা আছে?
আদম আলেকজান্ডার

আরে আদম, আমারও এই সীমাবদ্ধতা আছে এবং আমি সত্যিই বুঝতে পারি না কেন! এটা সত্যিই বিরক্তিকর। আপনি যদি সমাধান খুঁজে পান তবে আমাকে জানান! থেক্স
মার্টিন

ঠিক আছে, আমি এটিকে ভোট দিয়েছি কারণ এটি প্রাথমিকভাবে আমার সমস্যা সমাধানের জন্য উপস্থিত হয়েছিল। যাহোক...! কাজ করার জন্য আমি বহু-স্পর্শ পাচ্ছি বলে মনে হচ্ছে না। এটি হ'ল, যদিও আমি সরাসরি স্পর্শবেগান এবং স্পর্শগুলি মুভিড অব টাউচড (স্পর্শে অন্তর্ভুক্ত করি আমার), আমি চিমটি ইশারায় মানচিত্রটি জুম করতে পারি না। (অবিরত ...)
অলি

24
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleGesture:)];   
tgr.numberOfTapsRequired = 2;
tgr.numberOfTouchesRequired = 1;
[mapView addGestureRecognizer:tgr];
[tgr release];


- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
        return;

    CGPoint touchPoint = [gestureRecognizer locationInView:mapView];
    CLLocationCoordinate2D touchMapCoordinate = [mapView convertPoint:touchPoint toCoordinateFromView:mapView];

    //.............
}

4
আমি নিশ্চিত নই কেন এটি শীর্ষ উত্তর নয়। নিখুঁতভাবে কাজ করে বলে মনে হচ্ছে এবং এটি আরও সহজ।
Elsurudo

12

একজন এমকেম্যাপভিউয়ের জন্য আসল কার্যক্ষম সমাধানটি অঙ্গভঙ্গি স্বীকৃতি সহকারে!

আমি যখন আমি মানচিত্রটি টেনে আনি বা জুম করতে চিমটি দিয়ে থাকি তখন আমি নিজের অবস্থানটিতে মানচিত্রের কেন্দ্রের আপডেট করা বন্ধ করতে চাইতাম।

সুতরাং, মানচিত্রের ভিউতে আপনার অঙ্গভঙ্গি সনাক্তকারী তৈরি করুন এবং যুক্ত করুন:

- (void)viewDidLoad {

    ...

    // Add gesture recognizer for map hoding
    UILongPressGestureRecognizer *longPressGesture = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressAndPinchGesture:)] autorelease];
    longPressGesture.delegate = self;
    longPressGesture.minimumPressDuration = 0;  // In order to detect the map touching directly (Default was 0.5)
    [self.mapView addGestureRecognizer:longPressGesture];

    // Add gesture recognizer for map pinching
    UIPinchGestureRecognizer *pinchGesture = [[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressAndPinchGesture:)] autorelease];
    pinchGesture.delegate = self;
    [self.mapView addGestureRecognizer:pinchGesture];

    // Add gesture recognizer for map dragging
    UIPanGestureRecognizer *panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)] autorelease];
    panGesture.delegate = self;
    panGesture.maximumNumberOfTouches = 1;  // In order to discard dragging when pinching
    [self.mapView addGestureRecognizer:panGesture];
}

দেখুন UIGestureRecognizer ক্লাস রেফারেন্স সমস্ত উপলব্ধ অঙ্গভঙ্গি শনাক্তকারী দেখতে।

যেহেতু আমরা প্রতিনিধিটিকে স্ব হিসাবে সংজ্ঞায়িত করেছি, আমাদের প্রোটোকল ইউআইজিস্টচাররনকনাইজারডেলিগেট বাস্তবায়ন করতে হবে:

typedef enum {
    MapModeStateFree,                    // Map is free
    MapModeStateGeolocalised,            // Map centred on our location
    MapModeStateGeolocalisedWithHeading  // Map centred on our location and oriented with the compass
} MapModeState;

@interface MapViewController : UIViewController <CLLocationManagerDelegate, UIGestureRecognizerDelegate> {
    MapModeState mapMode;
}

@property (nonatomic, retain) IBOutlet MKMapView *mapView;
...

এবং মেথোড অঙ্গভঙ্গি সনাক্তকারীকে ওভাররাইড করুন: অঙ্গভঙ্গি সনাক্তকারীকে একই সাথে সনাক্ত করা উচিত উইথ অঙ্গভঙ্গিপরিচয়কারী: যদি আমি সঠিক বুঝতে পারি তবে এক সাথে একাধিক অঙ্গভঙ্গিগুলি স্বীকৃতি দেওয়ার জন্য:

// Allow to recognize multiple gestures simultaneously (Implementation of the protocole UIGestureRecognizerDelegate)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

এখন সেই পদ্ধতিগুলি লিখুন যা আমাদের অঙ্গভঙ্গি সনাক্তকারীদের দ্বারা ডাকা হবে:

// On map holding or pinching pause localise and heading
- (void)handleLongPressAndPinchGesture:(UIGestureRecognizer *)sender {
    // Stop to localise and/or heading
    if (sender.state == UIGestureRecognizerStateBegan && mapMode != MapModeStateFree) {
        [locationManager stopUpdatingLocation];
        if (mapMode == MapModeStateGeolocalisedWithHeading) [locationManager stopUpdatingHeading];
    }
    // Restart to localise and/or heading
    if (sender.state == UIGestureRecognizerStateEnded && mapMode != MapModeStateFree) {
        [locationManager startUpdatingLocation];
        if (mapMode == MapModeStateGeolocalisedWithHeading) [locationManager startUpdatingHeading];
    }
}

// On dragging gesture put map in free mode
- (void)handlePanGesture:(UIGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateBegan && mapMode != MapModeStateFree) [self setMapInFreeModePushedBy:sender];
}

এই সমাধান নিখুঁত! এখানে কিছু কুইকিজ: আপনি যদি ব্যবহার করে কোনও পদক্ষেপ গ্রহণ শেষ করেন তখন আপনি বাধা দিতে চান - (শূন্য) হ্যান্ডেললপ্রেসঅ্যান্ডপিনচজেষ্টার: (UIGestureRecognizer *) প্রেরক {যদি (সেন্ডার.স্টেট == UIGestureRecognizerStateEnded) {NSLog (@ "হ্যান্ডলঙ্গপ্রেস এন্ডপেইনচিন্ট) ; }}
আলেজান্দ্রো লুয়েঙ্গো

প্রতিনিধি <ইউআইজিস্টরআরকনাইজারডেলিগেট>
আলেজান্দ্রো

6

যদি কেউ আমার মতো একই ব্যবহার করার চেষ্টা করে থাকে: আমি যে বিন্দুতে ব্যবহারকারী ট্যাপ করি সেখানে একটি টীকা তৈরি করতে চেয়েছিলাম। তার জন্য আমি UITapGestureRecognizerসমাধানটি ব্যবহার করেছি :

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnMap:)];
[self.mapView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer setDelegate:self];

- (void)didTapOnMap:(UITapGestureRecognizer *)gestureRecognizer
{
    CGPoint point = [gestureRecognizer locationInView:self.mapView];
    CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
    .......
}

যাইহোক, didTapOnMap:যখন আমি টীকায় ট্যাপ করতাম এবং একটি নতুন তৈরি করা হত তখনও ডাকা হত। সমাধানটি বাস্তবায়ন UIGestureRecognizerDelegate:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([touch.view isKindOfClass:[MKAnnotationView class]])
    {
        return NO;
    }
    return YES;
}

এটি একটি দুর্দান্ত সমাধান! আপনি যদি কাস্টম ভিউ হিসাবে ব্যবহার করেন তবে এটি কাজ করছে না MKAnnotation। এই ক্ষেত্রে, আপনার ইশারার সনাক্তকারীকে ট্রিগার করার জন্য আরও একটি টীকাটির সাবভিউ থাকতে পারে। একটি সম্ভাব্য এমকেঅনোটেশনভিউ
KIDdAe

3

ইউআইউইউভিউভিউ-ভিত্তিক নিয়ন্ত্রণগুলির সাথে প্রায়শই যেমন করা হয় তেমন স্পর্শগুলি ধরার জন্য আপনার সম্ভবত একটি স্বচ্ছ দৃষ্টিভঙ্গি ওভারলে করতে হবে। মানচিত্রটি সরানো, কেন্দ্রিক, জুম করা ইত্যাদি ... যাতে বার্তাগুলি আপনার অ্যাপ্লিকেশনটিতে বুদ্বুদ হয়ে উঠছে না সেই জন্য মানচিত্রের ভিউ ইতিমধ্যে একটি স্পর্শ সহ কয়েকটি বিশেষ জিনিস তৈরি করেছে।

আমি ভাবতে পারি অন্য দুটি (UNTESTED) বিকল্প:

1) IB- র মাধ্যমে প্রথম প্রতিক্রিয়াকারীকে পদত্যাগ করুন এবং ফাইলের মালিককে ছোঁয়ায় সাড়া দেওয়ার জন্য এটি "ফাইলের মালিক" এ সেট করুন। আমি সন্দেহজনক যে এটি কাজ করবে কারণ এম কে ম্যাপভিউ এনএসবজেক্টকে প্রসারিত করে, ইউআইভিউয়ের উত্তর দেয় না ফলস্বরূপ স্পর্শ ইভেন্টগুলি আপনার কাছে প্রচার নাও পেতে পারে।

2) মানচিত্রের রাজ্যের পরিবর্তন হলে (যেমন একটি জুম হিসাবে) আপনি যখন ফাঁদ পেতে চান তবে নির্দিষ্ট ইভেন্টগুলি শোনার জন্য কেবল এমকেম্যাপভিউ ডেলেগেট প্রোটোকলটি প্রয়োগ করে। আমার কুণ্ডলীটি হ'ল এটি সহজেই কিছু মিথস্ক্রিয়া আটকাতে আপনার সেরা শট (মানচিত্রের উপর স্বচ্ছ দৃষ্টিভঙ্গির প্রয়োগের সংক্ষিপ্ত)। এম কে ম্যাপভিউতে মানচিত্রের প্রতিনিধি ( map.delegate = self) হিসাবে ভিউ কন্ট্রোলারকে আবাসন সেট করতে ভুলবেন না ।

শুভকামনা


এমকেম্যাপভিউ অবশ্যই ইউআইভিউ সাবক্লাস করে।
ড্যানিয়েল ডিকিসন

2

আমি পরীক্ষা-নিরীক্ষা করিনি, তবে ম্যাপকিট একটি ক্লাস ক্লাস্টারের আশেপাশে তৈরির একটি ভাল সুযোগ রয়েছে, এবং তাই এটি সাবক্লাসিং করা কঠিন এবং অকার্যকর।

আমি ম্যাপকিটকে একটি কাস্টম ভিউর একটি সংক্ষিপ্তসার তৈরি করার পরামর্শ দিচ্ছি, যা স্পর্শ ইভেন্টগুলিতে পৌঁছানোর আগে আপনাকে সেগুলি আটকাতে দেয়।


হ্যালো গ্রাহাম! আপনার সাহায্যের জন্য ধন্যবাদ! আপনার পরামর্শ মতো আমি যদি একটি সুপার কাস্টম ভিউ করি তবে কীভাবে আমি এমকেমেপভিউতে ইভেন্টগুলি ফরোয়ার্ড করতে পারি? কোন ধারণা?
মার্টিন

2

সুতরাং এটির সাথে ঘোরাঘুরির আধা দিন পরে আমি নিম্নলিখিতটি পেয়েছি:

  1. অন্য সবাই যেমন খুঁজে পেয়েছে, চিমটি দেওয়া কাজ করে না। আমি এমকেম্যাপভিউ এবং উপরিউক্ত পদ্ধতিটি উভয় উপক্লাসিংয়ের চেষ্টা করেছি (এটি বাধাগ্রস্ত করে)। এবং ফলাফল একই।
  2. স্ট্যানফোর্ড আইফোনের ভিডিওগুলিতে, অ্যাপলের একজন লোক বলেছেন যে আপনি টাচ অনুরোধগুলি (স্থানের বর্ণনায় উপরে বর্ণিত দুটি পদ্ধতি) যদি "স্থানান্তর" করেন তবে অনেকগুলি ইউআইকিট জিনিসগুলি প্রচুর ত্রুটি সৃষ্টি করবে এবং আপনি সম্ভবত এটি কাজ করতে পারবেন না।

  3. সমাধান : এখানে বর্ণিত হয়েছে: এমকেম্যাপভিউয়ের জন্য আইফোন টাচ ইভেন্টগুলি বাধা / হাইজ্যাক করা । মূলত আপনি ইভেন্টটি কোনও প্রতিক্রিয়াশীল হওয়ার আগেই "ধরা" দিন এবং সেখানে এটি ব্যাখ্যা করুন।


2

সুইফট ৩.০ এ

import UIKit
import MapKit

class CoordinatesPickerViewController: UIViewController {

    @IBOutlet var mapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(clickOnMap))
        mapView.addGestureRecognizer(tapGestureRecognizer)
    }

    @objc func clickOnMap(_ sender: UITapGestureRecognizer) {

        if sender.state != UIGestureRecognizerState.ended { return }
        let touchLocation = sender.location(in: mapView)
        let locationCoordinate = mapView.convert(touchLocation, toCoordinateFrom: mapView)
        print("Tapped at lat: \(locationCoordinate.latitude) long: \(locationCoordinate.longitude)")

    }

}

0

এমকেম্যাপভিউকে একটি কাস্টম ভিউর একটি উপদর্শন করুন এবং প্রয়োগ করুন

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

কাস্টম ভিউতে সাবউভিউয়ের পরিবর্তে স্ব ফিরে আসতে।


হ্যালো পিটার, আপনার উত্তরের জন্য ধন্যবাদ! তবে আমি মনে করি যে এটি করে এমকেম্যাপভিউ কোনও স্পর্শ ইভেন্ট পেতে সক্ষম হতে পারে না, তাই না? আমি কেবল ইভেন্টটি ধরার উপায় খুঁজছি এবং তারপরে এটি এমকেম্যাপভিউতে ফরোয়ার্ড করব।
মার্টিন

0

পিজা এবং চিৎকারের জন্য ধন্যবাদ - আপনি আমাকে প্রচুর সময় সাশ্রয় করেছেন।

বহুগুণে ছড়িয়ে ছিটিয়ে থাকা কাজ করবে।

viewTouch.multipleTouchEnabled = TRUE;

শেষের দিকে, আমি যখন স্পর্শটি ক্যাপচার করার প্রয়োজন ছিল তখন আমি ভিউগুলি সরিয়ে নিয়েছি (পিঞ্চজুমগুলির প্রয়োজনের চেয়ে বিভিন্ন সময়ে):

    [mapView removeFromSuperview];
    [viewTouch addSubview:mapView];
    [self.view insertSubview:viewTouch atIndex:0];

তবে লাইভ জুমিংয়ের সাথে কাজ করে না। এটি সর্বদা জুম আউট বলে মনে হয়।
রগ

0

আমি লক্ষ্য করেছি যে আপনি স্পর্শের নম্বর এবং অবস্থান ট্র্যাক করতে পারেন এবং একটি দৃশ্যে প্রতিটিটির অবস্থান পেতে পারেন:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Moved %d", [[event allTouches] count]);

 NSEnumerator *enumerator = [touches objectEnumerator];
 id value;

 while ((value = [enumerator nextObject])) {
  NSLog(@"touch description %f", [value locationInView:mapView].x);
 }
    [viewTouched touchesMoved:touches withEvent:event];
}

অন্য কেউ মানচিত্রের জুম স্তর আপডেট করতে এই মানগুলি ব্যবহার করার চেষ্টা করেছেন? এটি প্রারম্ভিক অবস্থানগুলি রেকর্ড করার বিষয় এবং তারপরে সমাপ্ত অবস্থানগুলি, আপেক্ষিক পার্থক্য গণনা করা এবং মানচিত্র আপডেট করার বিষয় হবে।

আমি মার্টিনের দেওয়া বেসিক কোডটি নিয়ে খেলছি, এবং দেখে মনে হচ্ছে এটি কার্যকর হবে ...


0

এখানে আমি একসাথে যা রেখেছি তা সিমুলেটারে চিমটি জুমগুলি অনুমতি দেয় (সত্যিকারের আইফোনটিতে চেষ্টা করেনি) তবে আমি মনে করি ঠিক আছে:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Began %d", [touches count]);
 reportTrackingPoints = NO;
 startTrackingPoints = YES;
    [viewTouched touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 if ([[event allTouches] count] == 2) {
  reportTrackingPoints = YES;
  if (startTrackingPoints == YES) {
   BOOL setA = NO;
   NSEnumerator *enumerator = [[event allTouches] objectEnumerator];
   id value;
   while ((value = [enumerator nextObject])) {
    if (! setA) {
     startPointA = [value locationInView:mapView];
     setA = YES;
    } else {
     startPointB = [value locationInView:mapView];
    }
   }
   startTrackingPoints = NO;
  } else {
   BOOL setA = NO;
   NSEnumerator *enumerator = [[event allTouches] objectEnumerator];
   id value;
   while ((value = [enumerator nextObject])) {
    if (! setA) {
     endPointA = [value locationInView:mapView];
     setA = YES;
    } else {
     endPointB = [value locationInView:mapView];
    }
   }
  }
 }
 //NSLog(@"Touch Moved %d", [[event allTouches] count]);
    [viewTouched touchesMoved:touches withEvent:event];
}

- (void) updateMapFromTrackingPoints {
 float startLenA = (startPointA.x - startPointB.x);
 float startLenB = (startPointA.y - startPointB.y);
 float len1 = sqrt((startLenA * startLenA) + (startLenB * startLenB));
 float endLenA = (endPointA.x - endPointB.x);
 float endLenB = (endPointA.y - endPointB.y);
 float len2 = sqrt((endLenA * endLenA) + (endLenB * endLenB));
 MKCoordinateRegion region = mapView.region;
 region.span.latitudeDelta = region.span.latitudeDelta * len1/len2;
 region.span.longitudeDelta = region.span.longitudeDelta * len1/len2;
 [mapView setRegion:region animated:YES];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 if (reportTrackingPoints) {
  [self updateMapFromTrackingPoints];
  reportTrackingPoints = NO;
 }


    [viewTouched touchesEnded:touches withEvent:event];
}

মূল ধারণাটি হ'ল ব্যবহারকারী যদি দুটি আঙুল ব্যবহার করে থাকেন তবে আপনি মানগুলি ট্র্যাক করেন। আমি স্টার্টপয়েন্টস এ এবং বিতে শুরু এবং শেষের পয়েন্টগুলি রেকর্ড করি তারপরে আমি বর্তমান ট্র্যাকিং পয়েন্টগুলি রেকর্ড করি, এবং যখন আমার স্পর্শএন্ডে সম্পন্ন হয়, তখন আমি যে পয়েন্টগুলি দিয়ে শুরু করি তার মধ্যে রেখার আপেক্ষিক দৈর্ঘ্য গণনা করার জন্য একটি রুটিন কল করতে পারি can , এবং সাধারণ হাইপোপেনিউস ক্যালক ব্যবহার করে আমি বিন্দুটির মধ্যবর্তী লাইনটি শেষ করি। তাদের মধ্যে অনুপাতটি জুম পরিমাণ: আমি অঞ্চলটি সেই পরিমাণ দিয়ে গুণ করি।

আশা করি এটি কারও কাজে লাগবে।


0

আমি মিস্টিকস্পাইরালের উত্তর থেকে "ওভারলে" স্বচ্ছ দৃষ্টিভঙ্গির ধারণা নিয়েছি এবং আমি যা অর্জন করার চেষ্টা করছি তার জন্য এটি পুরোপুরি কাজ করেছিল; দ্রুত এবং পরিষ্কার সমাধান।

সংক্ষেপে, আমার একটি কাস্টম ইউআইটিএবলভিউসেল ছিল (আইবিতে নকশা করা) বাম-হাতের এম কে ম্যাপভিউ এবং ডানদিকে কিছু ইউআইএলবেল রয়েছে। আমি কাস্টম সেলটি তৈরি করতে চেয়েছিলাম যাতে আপনি এটি যে কোনও জায়গায় স্পর্শ করতে পারেন এবং এটি একটি নতুন দর্শন নিয়ামককে ধাক্কা দেয়। তবে মানচিত্রের স্পর্শটি ইউআইটিএবলভিউসেলটিতে 'আপ' ছোঁয়া যায় না যতক্ষণ না আমি কেবল তার উপরে (আইবিতে) মানচিত্রের দৃশ্যের মতো একই আকারের একটি ইউআইভিউ যুক্ত করি এবং এর ব্যাকগ্রাউন্ডটিকে কোডে 'পরিষ্কার রঙ' না করে তোলে ( ভাববেন না আপনি ক্লিয়ার কালার আইবিতে সেট করতে পারবেন ??):

dummyView.backgroundColor = [UIColor clearColor];

ভেবেছিল এটি অন্য কাউকে সাহায্য করতে পারে; অবশ্যই যদি আপনি কোনও টেবিল ভিউ সেলের জন্য একই আচরণ অর্জন করতে চান।


"তবে মানচিত্রের স্পর্শটি ইউআইটিএবলভিউসেলটিতে 'আপ' ছোঁয়া যায়নি যতক্ষণ না আমি ঠিক তার ঠিক উপরে মানচিত্রের দৃশ্যের মতো একই আকারের একটি ইউআইভিউ যুক্ত করি" এটি সত্য নয়। মানচিত্রটি স্পর্শ করছে কারণ এর নিজস্ব ব্যবহারকারীর ইন্টারঅ্যাকশন যেমন স্ক্রোলিং ইত্যাদি etc. আপনি যদি মানচিত্রের সাথে ইন্টারঅ্যাক্ট করার পরিবর্তে সেলটিতে যদিও এটি সনাক্ত করতে চান তবে কেবল মানচিত্র সেট করুন isআইসেসরেক্টরইনবেসড = মিথ্যা আপনি কেবল সারণীতে ডিলেক্ট্রোলআউটআইডেক্সপথটি ব্যবহার করতে পারেন প্রতিনিধি দেখুন।
BROK3N S0UL
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.