এমকেএনোটেশনভিউয়ের জন্য কলআউট বুদবুদ কীভাবে কাস্টমাইজ করবেন?


88

আমি বর্তমানে ম্যাপকিট নিয়ে কাজ করছি এবং আটকে আছি।

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

আমার ধারণাটি ছিল আমার মধ্যে সিলেক্ট অ্যানোটেশন / অনির্দিষ্টকেন্দ্রিকরণকে ওভাররাইড করা MKMapViewDelegateএবং তারপরে আমার কাস্টম টীকাগুলি ভিউতে একটি কল করে আমার নিজস্ব কাস্টম ভিউ আঁকুন। এটি কাজ করে, তবে কেবল তখনই আমার কাস্টম টিকা দেখুন শ্রেণিতে canShowCalloutসেট করা YESহয়। আমার কাছে এই সেটটি থাকলে এই পদ্ধতিগুলি কল করা হয় না NO(যা আমি চাই, যাতে ডিফল্ট কলআউট বুদ্বুদ আঁকেনি)। সুতরাং ব্যবহারকারী আমার মানচিত্রে আমার বিন্দুটি স্পর্শ করেছেন কিনা তা জানার কোনও উপায় নেই (এটি নির্বাচিত) বা কোনও বিন্দু স্পর্শ করেছে যা আমার টীকাগুলির দর্শনের অংশ নয় (এটি অপছন্দ করেছে) ডিফল্ট কলআউট বুদ্বুদ ভিউ প্রদর্শিত না হয়ে।

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

কোনও পরামর্শ? আমি কি স্পষ্ট কিছু মিস করছি?


এই লিঙ্কটি কাজ করে না, তবে এখানে একই পোস্টটি খুঁজে পেয়েছে -> কাস্টম মানচিত্র টীকাকরণ কলআউটগুলি তৈরি করা - পর্ব 1
ফেডার মিকা

4
আপনি একটি দ্রুত ডেমো জন্য এই প্রকল্পটি উল্লেখ করতে পারেন । github.com/akshay1188/ কাস্টমঅনোটেশন একটি চলমান ডেমোতে উপরের উত্তরগুলির সংকলন।
akshay1188

উত্তর:


54

এর থেকেও সহজ সমাধান রয়েছে।

একটি কাস্টম তৈরি করুন UIView(আপনার কলআউটটির জন্য)।

তারপরে একটি সাবক্লাস তৈরি করুন MKAnnotationViewএবং নীচে ওভাররাইড করুন setSelected:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    if(selected)
    {
        //Add your custom view to self...
    }
    else
    {
        //Remove your custom view...
    }
}

বুম, কাজ শেষ।


8
হাই ট্যাপক্যান্ডি! প্রথমে, আপনার সমাধানের জন্য ধন্যবাদ। এটি কাজ করে, কিন্তু যখন কোনও ভিউ লোড হয় (আমি এটি একটি নিব ফাইল থেকে করছি) বোতামগুলি কাজ করে না। তাদের সঠিকভাবে কাজ করার জন্য আমি কী করতে পারি ?? ধন্যবাদ
ফ্রেড

এই সমাধানের সরলতা পছন্দ!
এরিক ব্রোটো

6
হুঁ - এটি কাজ করে না! এটি মানচিত্রের টীকা প্রতিস্থাপন (যেমন পিন) কলআউট "বুদবুদ" নয়।
প্যাপিলনউকে

4
এটি কাজ করবে না। এমকেএনোটেশনভিউয়ের মানচিত্রের ভিউতে কোনও রেফারেন্স নেই তাই কাস্টম কলআউট যুক্ত করার সাথে আপনার বেশ কয়েকটি সমস্যা রয়েছে। উদাহরণস্বরূপ আপনি জানেন না যে এটিকে সাবউভিউ হিসাবে যুক্ত করা অফস্ক্রিন হবে কিনা।
ক্যামেরন লোয়েল পামার

@ পেপিলনউকে আপনার কলআউটটির ফ্রেমের উপর নিয়ন্ত্রণ রয়েছে। এটি পিনটি প্রতিস্থাপন করছে না, এটি এটির উপরে প্রদর্শিত হচ্ছে। আপনি যখন এটিকে একটি সংক্ষিপ্তসার হিসাবে যুক্ত করেন তখন এর অবস্থানটি সামঞ্জস্য করুন।
বেন প্যাকার্ড

40

বিশদক্যালআউটএকসেসরিভিউ

পুরানো দিনগুলিতে এটি একটি ব্যথা ছিল তবে অ্যাপল এটি সমাধান করেছে, কেবল এমকেএনোটেশনভিউতে ডক্স পরীক্ষা করুন

view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.detailCalloutAccessoryView = UIImageView(image: UIImage(named: "zebra"))

সত্যিই, এটি। যে কোনও ইউআইভিউ নেয়।


কোনটি ব্যবহার করা ভাল?
সত্যম

13

@ ট্যাপক্যান্ডির জমকালো সহজ উত্তর থেকে অবিরত, আপনি যদি নিজের বুদ্বুদকে ডিফল্ট হিসাবে একইভাবে প্রাণবন্ত করতে চান তবে আমি এই অ্যানিমেশন পদ্ধতিটি তৈরি করেছি:

- (void)animateIn
{   
    float myBubbleWidth = 247;
    float myBubbleHeight = 59;

    calloutView.frame = CGRectMake(-myBubbleWidth*0.005+8, -myBubbleHeight*0.01-2, myBubbleWidth*0.01, myBubbleHeight*0.01);
    [self addSubview:calloutView];

    [UIView animateWithDuration:0.12 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^(void) {
        calloutView.frame = CGRectMake(-myBubbleWidth*0.55+8, -myBubbleHeight*1.1-2, myBubbleWidth*1.1, myBubbleHeight*1.1);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.1 animations:^(void) {
            calloutView.frame = CGRectMake(-myBubbleWidth*0.475+8, -myBubbleHeight*0.95-2, myBubbleWidth*0.95, myBubbleHeight*0.95);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.075 animations:^(void) {
                calloutView.frame = CGRectMake(-round(myBubbleWidth/2-8), -myBubbleHeight-2, myBubbleWidth, myBubbleHeight);
            }];
        }];
    }];
}

এটা তোলে মোটামুটি জটিল দেখায়, কিন্তু যতদিন আপনার কলআউট বুদ্বুদ বিন্দু কেন্দ্রে-নীচে ডিজাইন করা হয়েছে, আপনি শুধু প্রতিস্থাপন করতে সক্ষম হওয়া উচিত myBubbleWidthএবং myBubbleHeightকাজ করার জন্য এটি জন্য আপনার নিজের আকার সঙ্গে। এবং মনে রাখবেন যে আপনার সাবভিউগুলিতে তাদের autoResizeMaskসম্পত্তিটি 63 এ সেট করা আছে (যেমন "সমস্ত") যাতে তারা অ্যানিমেশনে সঠিকভাবে স্কেল করে।

: -জয়


বিটিডব্লিউ, আপনি সামগ্রীর যথাযথ স্কেলিং পেতে ফ্রেমের পরিবর্তে স্কেল সম্পত্তিতে অ্যানিমেশন করতে পারেন।
আকুলাস

সিজিআরেক্টমেক ব্যবহার করবেন না। সিজি ট্রান্সফর্ম ব্যবহার করুন।
ক্যামেরন লোয়েল পামার

@ ককুলাস - আমি মনে করি আমি এটি প্রথম চেষ্টা করেছি, তবে আইওএসে 4 এর বিষয়গুলি রেন্ডারিং করেছিলাম তবে এটি সম্ভবত কারণ হতে পারে কারণ আমি ব্যবহার করছিলাম না CABasicAnimation... মনে রাখার অনেক আগেই! আমি জানি আমার পাশাপাশি ওয়াই সম্পত্তিটিও প্রাণবন্ত করতে হবে, কেননা অফসেটের কারণে।
jowie

@ ক্যামেরনলওয়েলপালমার - কেন ব্যবহার CGRectMakeকরবেন না ?
jowie

@ জোভি কারণ সিনট্যাক্সটি ভাল, এবং আপনার কোডের যাদু মানগুলি এড়িয়ে চলে। সিজিএফাইনট্রান্সফর্মমেকস্কেল (1.1f, 1.1f); 110% দ্বারা বাক্সটি বাড়ানো স্পষ্ট। আপনি যেভাবে গিয়েছিলেন এটি কার্যকর হতে পারে তবে এটি সুন্দর নয়।
ক্যামেরন লোয়েল পামার

8

এটি আমার জন্য সেরা সমাধান হিসাবে পাওয়া গেছে। আপনার নিজস্ব কাস্টমাইজেশন করতে আপনাকে কিছু সৃজনশীলতা ব্যবহার করতে হবে

আপনার MKAnnotationViewসাবক্লাসে, আপনি ব্যবহার করতে পারেন

- (void)didAddSubview:(UIView *)subview{
    int image = 0;
    int labelcount = 0;
    if ([[[subview class] description] isEqualToString:@"UICalloutView"]) {
        for (UIView *subsubView in subview.subviews) {
            if ([subsubView class] == [UIImageView class]) {
                UIImageView *imageView = ((UIImageView *)subsubView);
                switch (image) {
                    case 0:
                        [imageView setImage:[UIImage imageNamed:@"map_left"]];
                        break;
                    case 1:
                        [imageView setImage:[UIImage imageNamed:@"map_right"]];
                        break;
                    case 3:
                        [imageView setImage:[UIImage imageNamed:@"map_arrow"]];
                        break;
                    default:
                        [imageView setImage:[UIImage imageNamed:@"map_mid"]];
                        break;
                }
                image++;
            }else if ([subsubView class] == [UILabel class]) {
                UILabel *labelView = ((UILabel *)subsubView);
                switch (labelcount) {
                    case 0:
                        labelView.textColor = [UIColor blackColor];
                        break;
                    case 1:
                        labelView.textColor = [UIColor lightGrayColor];
                        break;

                    default:
                        break;
                }
                labelView.shadowOffset = CGSizeMake(0, 0);
                [labelView sizeToFit];
                labelcount++;
            }
        }
    }
}

এবং যদি এটি subviewহয় UICalloutViewতবে আপনি এটির সাথে এবং এর ভিতরে কী আছে তা ঘুরিয়ে নিতে পারেন।


4
ইউআইসিএলআউটভিউ কোনও পাবলিক ক্লাস না হওয়ায় সাবউভিউটি ইউআইসিএলআউটভিউ কিনা তা আপনি কীভাবে পরীক্ষা করতে পারেন।
মনিশ আহুজা

if ([[[subview class] description] isEqualToString:@"UICalloutView"]) আমি মনে করি এর থেকে আরও ভাল উপায় আছে তবে এটি কাজ করে।
16 ււ

মনীশ যেমন বলেছিল যেহেতু এটি নিয়ে আপনার কোনও সমস্যা আছে, এটি একটি প্রাইভেট ক্লাস।
ড্যানিয়েল

সম্ভবত তারা কলআউটভিউগুলির জন্য ইউআইভিউ কাঠামো পরিবর্তন করেছে। এটি ব্যবহার করে এমন অ্যাপটি আমি আপগ্রেড করেছি না, তাই আপনি নিজেরাই: P
ււ

6

আমারও একই সমস্যা ছিল। এই বিষয়টিতে ব্লগ পোস্টগুলির একটি গুরুতর বিষয় রয়েছে এই ব্লগে http://spitzkoff.com/craig/?p=81

এখানে কেবল আপনাকে ব্যবহার MKMapViewDelegateকরে না এবং সাবক্লাসিং করে MKMapViewএবং বিদ্যমান কার্যকারিতা প্রসারিত করার চেষ্টা করাও আমার পক্ষে কার্যকর হয়নি।

আমি যেটা শেষ করেছিলাম তা হ'ল আমার নিজের তৈরি করা যা আমার নিজের CustomCalloutViewউপর রয়েছে MKMapView। আপনি যেভাবে চান এই দর্শনটিকে স্টাইল করতে পারেন।

আমার CustomCalloutViewএইর মতো একটি পদ্ধতি রয়েছে:


- (void) openForAnnotation: (id)anAnnotation
{
    self.annotation = anAnnotation;
    // remove from view
    [self removeFromSuperview];

    titleLabel.text = self.annotation.title;

    [self updateSubviews];
    [self updateSpeechBubble];

    [self.mapView addSubview: self];
}

এটি একটি MKAnnotationঅবজেক্ট নেয় এবং তার নিজস্ব শিরোনাম সেট করে, এরপরে এটি দুটি আরও পদ্ধতি বলে যেগুলি বেশ কুরুচিপূর্ণ যা কলআউট সামগ্রীর প্রস্থ এবং আকারকে সামঞ্জস্য করে এবং তারপরে স্পিচ বুদ্বুদকে সঠিক অবস্থানে আঁকেন।

অবশেষে দৃশ্যটি মানচিত্রের ভিউতে একটি সংক্ষিপ্তসার হিসাবে যুক্ত করা হয়েছে। এই সমাধানটির সমস্যাটি হ'ল মানচিত্রের ভিউ স্ক্রোল করা অবস্থায় কলআউটটি সঠিক অবস্থানে রাখা শক্ত। এই সমস্যাটি সমাধানের জন্য আমি কোনও অঞ্চল পরিবর্তনের জন্য মানচিত্রের দালালি পদ্ধতিতে কলআউটটি আড়াল করছি।

এই সমস্ত সমস্যাগুলি সমাধান করতে কিছুটা সময় নিয়েছিল, কিন্তু এখন কলআউটটি প্রায়শই সরকারীটির মতো আচরণ করে তবে এটি আমার নিজস্ব স্টাইলে রয়েছে।


আমি দ্বিতীয় যে: ইউআইসিএলআউটভিউ একটি বেসরকারী ক্লাস এবং এসডিকে সরকারীভাবে উপলব্ধ নয়। আপনার সেরা বাজি সাসাচের পরামর্শ অনুসরণ করা follow
জোপ্যাসক

হাই সাশা, আপনার জবাবের জন্য আমরা আপনাকে ধন্যবাদ জানাই। তবে, আমরা যে বর্তমান সমস্যাটি অনুভব করছি তা হ'ল পিনগুলি যে মানচিত্রে প্রদর্শিত হবে সেভাবে কীভাবে (x, y এবং ল্যাট বা দীর্ঘ নয়) পজিশন পাবেন, যাতে আমরা কলআউট দৃশ্যটি প্রদর্শন করতে পারি।
Zach

4
রূপান্তরকারী স্থানাঙ্কগুলি এম কে ম্যাপভিউয়ের দুটি ফাংশন দ্বারা সহজেই করা যায়: # - রূপান্তরকরণ সমন্বয়: টুয়েন্টটোটোভিউ: # - রূপান্তর পয়েন্ট: টু করর্ডিনেটফর্মভিউ:
সাসচা

5

মূলত এটির সমাধানের জন্য, আমাদের এগুলির একটি দরকার: ক) ডিফল্ট কলআউট বুদ্বুদটিকে আগত থেকে আটকাতে। খ) কোন টিকাটি ক্লিক করা হয়েছিল তা নির্ধারণ করুন।

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

দ্রষ্টব্য: আপনাকে এমকেএনোটেশনভিউয়ের জন্য টাচ ইভেন্টগুলি পরিচালনা করতে হবে এবং এমকেম্যাপভিউ নয়


3

আমি কেবল একটি পদ্ধতির সাথে হাজির, এখানে ধারণাটি is

  // Detect the touch point of the AnnotationView ( i mean the red or green pin )
  // Based on that draw a UIView and add it to subview.
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    CGPoint newPoint = [self.mapView convertCoordinate:selectedCoordinate toPointToView:self.view];
//    NSLog(@"regionWillChangeAnimated newPoint %f,%f",newPoint.x,newPoint.y);
    [testview  setCenter:CGPointMake(newPoint.x+5,newPoint.y-((testview.frame.size.height/2)+35))];
    [testview setHidden:YES];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    CGPoint newPoint = [self.mapView convertCoordinate:selectedCoordinate toPointToView:self.view];
//    NSLog(@"regionDidChangeAnimated newPoint %f,%f",newPoint.x,newPoint.y);
    [testview  setCenter:CGPointMake(newPoint.x,newPoint.y-((testview.frame.size.height/2)+35))];
    [testview setHidden:NO];
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 
{  
    NSLog(@"Select");
    showCallout = YES;
    CGPoint point = [self.mapView convertPoint:view.frame.origin fromView:view.superview];
    [testview setHidden:NO];
    [testview  setCenter:CGPointMake(point.x+5,point.y-(testview.frame.size.height/2))];
    selectedCoordinate = view.annotation.coordinate;
    [self animateIn];
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view 
{
    NSLog(@"deSelect");
    if(!showCallout)
    {
        [testview setHidden:YES];
    }
}

এখানে - টেস্টভিউ হ'ল UIViewআকারের 320x100 - শোক্যালআউটটি হল BOOL - [self animateIn];এমন ফাংশন যা অ্যানিমেশন পছন্দ করে UIAlertView


নির্বাচিত কর্ডিনেট কী নির্দিষ্ট করে? এটি কোন ধরণের অবজেক্ট?
প্রদীপ রেড্ডি কিপা

এটি CLLocationCoordinate2d অবজেক্ট।
কুমার

1

আপনি "" "এ টীকা নির্ধারণ করে টেক্সট সেট করে বামক্যালআউটভিউ ব্যবহার করতে পারেন"

উদাহরণ কোডের নীচে দয়া করে সন্ধান করুন:

pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if(pinView == nil){
    pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];       
}
CGSize sizeText = [annotation.title sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:12] constrainedToSize:CGSizeMake(150, CGRectGetHeight(pinView.frame))                                 lineBreakMode:UILineBreakModeTailTruncation];
pinView.canShowCallout = YES;    
UILabel *lblTitolo = [[UILabel alloc] initWithFrame:CGRectMake(2,2,150,sizeText.height)];
lblTitolo.text = [NSString stringWithString:ann.title];
lblTitolo.font = [UIFont fontWithName:@"HelveticaNeue" size:12];
lblTitolo.lineBreakMode = UILineBreakModeTailTruncation;
lblTitolo.numberOfLines = 0;
pinView.leftCalloutAccessoryView = lblTitolo;
[lblTitolo release];
annotation.title = @" ";            

4
এটি কিছুটা হলেও 'কাজ করবে' তবে সাধারণভাবে জিজ্ঞাসিত আরও সাধারণ প্রশ্নের উত্তর দেয় না এবং এটি অত্যন্ত হ্যাকিশ।
ক্যামেরন লোয়েল পামার

1

আমি আমার দুর্দান্ত এসএমক্যালআউটভিউয়ের কাঁটাচামচ ফেলেছি যা কলআউটগুলির জন্য একটি কাস্টম ভিউ সরবরাহ করে এবং নমনীয় প্রস্থ / উচ্চতাগুলিকে বেশ বেদনা ছাড়াই অনুমতি দেয়। এখনও কাজ করতে কিছু quirks, কিন্তু এটি এখনও পর্যন্ত কার্যকরী:

https://github.com/u10int/calloutview

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.