2013-05-10 52 views
5

Tôi đang làm việc trên một dự án nhỏ hiển thị 7 loại chú thích khác nhau trên bản đồ. Chú thích của tôi được lấy từ một kết quả url trong mảng và tôi phân tích nó bằng cách sử dụng JSON. Tôi có rất nhiều chú thích và mọi thứ có vẻ tốt khi bản đồ tải. Sau khi phóng to và thu nhỏ, hình ảnh ghim thay đổi vì một lý do nào đó cho hình ảnh pin sai (một hình ảnh cụ thể, không rõ nguyên nhân).Chú thích MKMapview chú thích thay đổi hình ảnh pin động sau khi phóng to

Tôi chắc chắn rằng tôi đang thiếu thứ gì đó ở đây ... bạn có thể vui lòng trợ giúp :) không?

Dưới đây là một phần của mã của tôi, cho tôi biết nếu bạn cần nữa của nó:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{ 

static NSString *identifier; 

if(_mapView.tag==1){identifier = @"TurbulencePin";} 
if(_mapView.tag==2){identifier = @"IcingPin";} 
if(_mapView.tag==3){identifier = @"WindsPin";} 
if(_mapView.tag==4){identifier = @"TemperaturePin";} 
if(_mapView.tag==5){identifier = @"CloudsPin";} 
if(_mapView.tag==6){identifier = @"VisibilityPin";} 
if(_mapView.tag==7){identifier = @"MultiplePin";} 


if ([annotation isKindOfClass:[MKUserLocation class]]) 
    return nil; 

if ([annotation isKindOfClass:[Annotation class]]) { 

    CustomAnnotationView* annotationView = (CustomAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; 
    annotationView = nil; 

    if (annotationView == nil) { 

     annotationView = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; 
     annotationView.enabled = YES; 
     annotationView.canShowCallout = YES; 


     UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png",identifier]]; 
     annotationView.image = img; 

    } 
else 
    { 

     annotationView.annotation = annotation; 

    } 


    return annotationView; 

} 
return nil; 

} 

Cập nhật:

Dựa trên phản hồi của người khác, tôi đã sửa đổi mã cho cài đặt hình ảnh như sau:

Annotation *myCustomAnn = (Annotation *)annotation; 
NSString *imgName = myCustomAnn.imageName; 
UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%@Pin.png",imgName]]; 
annotationView.image = img; 

return annotationView; 

Plus, tôi re đã di chuyển số annotationView = nil;

Tuy nhiên, tôi không thể đặt tên hình ảnh trong chú thích.m làm giá trị được mã hóa cứng vì tôi cần hiển thị hình ảnh pin khác cho mỗi chú thích. Tôi chắc chắn rằng có một lời giải thích nhưng giá trị duy nhất mà tôi có thể nhận được từ chú thích.m bên dưới mapView: viewForAnnotation: là tọa độ chú thích (myCustomAnn.coordinate.latitudemyCustomAnn.coordinate.longitude), tôi không biết cách lấy các thuộc tính khác từ chú thích. m

các tính chất khác, chẳng hạn như tiêu đề, imgname vv trở lại như là null

+0

Loại chú thích này phải là thuộc tính của chú thích, không sử dụng thuộc tính 'tag' của bản đồ cho mục này. (Ngoài ra, "số nhận dạng" của bạn không cần tĩnh nếu bạn đang thiết lập nó theo chương trình.) Nhưng điều duy nhất tôi có thể tưởng tượng sẽ làm cho hình ảnh của pin thay đổi là nếu 'thẻ' đang thay đổi bằng cách nào đó. Tôi muốn đề nghị đăng nhập và xem những gì đang xảy ra (nhưng, tốt hơn, từ bỏ 'tag' và sử dụng một thuộc tính tùy chỉnh cho chú thích của bạn). – Rob

+0

Nhân tiện, tôi hy vọng bạn không có bảy bản đồ mở cùng một lúc. Và nếu bạn làm thế, không sử dụng '_mapView' (đó là một số ivar) nhưng thay vì sử dụng' mapView', tham số cho phương thức này. – Rob

+1

Bạn đã nói "không thể đặt tên hình ảnh trong chú thích.m ...". Chính xác. Bạn không nên làm điều đó trong chú thích.m. Trong chú thích của bạn.h bạn chỉ cần định nghĩa một thuộc tính mới cho 'imageName'. Sau đó, trong mã của bạn để tạo chú thích (bộ điều khiển xem của bạn?) Sau khi tạo chú thích, đó là nơi bạn đặt thuộc tính 'imageName' cho chú thích của bạn. Về các thuộc tính khác của bạn là null, câu hỏi đặt ra là liệu bạn có đặt các thuộc tính đó trong VC của bạn, nơi bạn đã thực hiện 'alloc' /' init' của đối tượng chú thích, nhưng trước khi bạn thực hiện cuộc gọi 'addAnnotation'. – Rob

Trả lời

0

Một vấn đề là viewForAnnotation đang xác định hình ảnh chính xác để hiển thị dựa trên biến thể hiện của lớp. Nói chung, số nhận dạng cho hình ảnh của chú thích sẽ là thuộc tính của chú thích tùy chỉnh, chứ không phải một số biến mẫu bên ngoài.

Trên hết, dường như chú thích đã được thêm vào bản đồ trước khi tất cả thuộc tính của chú thích được đặt. Bạn nên hoãn addAnnotation cho đến khi tất cả các thuộc tính của chú thích được đặt.

Hoặc, bạn có thể thêm chú thích vào NSMutableArray, chỉnh sửa chú thích khi bạn thấy phù hợp và chỉ thêm chú thích ở cuối cùng bằng cách sử dụng addAnnotations (lưu ý), chuyển mảng đó.

5

vấn đề chính là các mã trong viewForAnnotation được dựa vào các biến bên ngoài _mapView.tag để xác định xem chú thích.

Nó không an toàn khi giả sử khi nào và tần suất phương thức ủy quyền viewForAnnotation sẽ được gọi bằng bản đô.

Nếu chế độ xem của chú thích tùy thuộc vào các giá trị nhất định, tốt nhất là nên nhúng trực tiếp các giá trị đó vào chính đối tượng chú thích. Bằng cách này, trong phương thức ủy quyền viewForAnnotation, bạn có thể tham chiếu các giá trị chú thích cụ thể đó thông qua tham số annotation được chuyển đến phương thức. Các giá trị chú thích cụ thể đó nên được đặt khi tạo chú thích (trước khi gọi addAnnotation).

Đối với một số chi tiết và ví dụ, xem:

Một vấn đề riêng biệt là mã được thiết annotationView-nil sau khi gọi dequeueReusableAnnotationViewWithIdentifier mà đánh bại dequeue.


Ít nhất trong viewForAnnotation, mã sửa lại nơi mà nó xử lý các lớp Annotation có thể trông như thế này (không phải toàn bộ phương pháp - chỉ là một phần bên trong thứ hai if):

static NSString *identifier = @"ann"; 

CustomAnnotationView* annotationView = (CustomAnnotationView*)[mapView 
    dequeueReusableAnnotationViewWithIdentifier:identifier]; 

//annotationView = nil; // <-- remove this line 

if (annotationView == nil) 
{ 
    annotationView = [[CustomAnnotationView alloc] 
         initWithAnnotation:annotation 
         reuseIdentifier:identifier]; 
    annotationView.enabled = YES; 
    annotationView.canShowCallout = YES; 
} 
else 
{ 
    annotationView.annotation = annotation; 
} 

//MOVE the setting of the image to AFTER the dequeue/create 
//because the image property of the annotation view 
//is based on the annotation and we can update image in one place 
//after both the dequeue and create are done... 

//Get the image name from the annotation ITSELF 
//from a custom property (that you add/set) 
Annotation *myCustomAnn = (Annotation *)annotation; 

NSString *imgName = myCustomAnn.imageName; 
//imageName is the custom property you added/set 

UIImage *img = [UIImage imageNamed: 
        [NSString stringWithFormat:@"%@.png",imgName]]; 

annotationView.image = img; 

return annotationView; 
+1

Tôi đồng ý về việc sử dụng các thuộc tính chú thích. Tôi muốn bỏ phiếu cho tham số loại chú thích 'enum' thay vì tên của chuỗi, tho. Và cá nhân tôi không quan tâm đến việc OP sử dụng mã định danh chú thích tùy chỉnh cho từng loại chế độ xem chú thích (thay vì đặt lại thuộc tính 'image' bất kể bạn có hay không). Ngoài ra, tôi cho rằng thiết lập của OP là 'annotationView = nil' không phải là lỗi của anh ta, mà là một quá trình chẩn đoán có chủ ý để tạm thời lấy logic' dequeue ... 'ra khỏi vòng lặp, do đó đơn giản hóa vấn đề. – Rob

+0

@Rob, tôi đồng ý với tất cả các điểm của bạn. Mục đích chính của tôi là chỉ ra sự lạm dụng của biến bên ngoài. – Anna

+0

Đồng ý. Nó đặc biệt tò mò để tham khảo các '_mapView' ivar khi thực tế' mapView' đã được thông qua phương pháp. Nhìn lại, việc sử dụng thẻ 'là đáng lo ngại, không chỉ vì những lý do bạn chỉ ra chính xác, mà còn có nghĩa là anh ta có bảy bản đồ mở cùng một lúc (điều đó khiến tôi sử dụng tài nguyên hệ thống) . +1 – Rob

0

giải quyết bởi Rob

Vấn đề là tôi không thể tìm lại thuộc tính chú thích mà tôi đặt ở VC của mình. Lý do là tôi đã sử dụng lệnh [_mapView addAnnotation:ann];, trước khi tôi đặt tất cả các thuộc tính của chú thích. Điều đó nói rằng, bằng cách di chuyển dòng này đến phần cuối của thiết lập thuộc tính ban đầu chú thích, giải quyết vấn đề.

Cảm ơn tất cả các bạn và cảm ơn Rob! Tôi sẽ thử thách tiếp theo.

+0

Vì vậy, tín dụng sẽ được chuyển vào ROB! –

Các vấn đề liên quan