我尝试使用核心数据模型类作为我的自定义注释,但不知何故,viewForAnnotation永远不会被调用。
这是我的视图控制器,它包含所有核心数据片段以及我如何实现委托方法
#import "SkyCastViewController.h"
#import "AppDelegate.h"
#import "Pixel-Swift.h"
#import "Photo+Annotation.h"
static NSString* const NavigationBarTitleFontName = @"Avenir-Heavy";
static CGFloat const NavigationBarTitleFontSize = 17;
static NSString* const MapViewReuseIdentifier = @"AnnotationViweIden";
@interface SkyCastViewController () <MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) NSArray* photos;
@property (strong, nonatomic) UIManagedDocument* document;
@end
@implementation SkyCastViewController
- (void) viewDidLoad{
[super viewDidLoad];
[self updateUI];
self.mapView.delegate = self;
}
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSURL* docsDir = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
if(docsDir){
NSURL* url = [docsDir URLByAppendingPathComponent:@"storage"];
self.document = [[UIManagedDocument alloc] initWithFileURL: url];
if(self.document.documentState != UIDocumentStateNormal){
if([[NSFileManager defaultManager] fileExistsAtPath: url.path]){
//the document exists, open it
[self.document openWithCompletionHandler:^(BOOL success){
if(success){
[self documentInit];
}
}];
}else{
//the document does not exist, create one
[self.document saveToURL:url forSaveOperation: UIDocumentSaveForCreating completionHandler:^(BOOL success){
//post a notification that document is ready
if(success){
NSLog(@"saveToURL succeed");
}else{
NSLog(@"saveToURL falied");
}
}];
}
}
}
}
// document ready observer
- (void) documentInit{
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext* context = self.document.managedObjectContext;
NSError* error;
//fetch objects
NSFetchRequest* request = [[NSFetchRequest alloc] initWithEntityName:@"User"];
request.fetchBatchSize = 10;
request.fetchLimit = 100;
NSString* nameAttr = @"name";
NSString* nameValue = @"Kesong Xie";
request.predicate = [NSPredicate predicateWithFormat:@"%K like %@", nameAttr, nameValue];
NSArray* users = [context executeFetchRequest:request error: &error];
if(error != nil){
NSLog(@"%@", error.localizedDescription);
}else{
if([users count] > 0){
for(User* user in users){
self.photos = (NSArray<Photo<MKAnnotation>*>*)user.photo.allObjects;
[self.mapView addAnnotations:self.photos];
}
}
}
NSLog(@"%@", self.photos);
// [self.mapView showAnnotations: self.photos animated: YES];
});
}
//MARK: - UPATE UI
- (void) updateUI{
[self.navigationController.navigationBar setBarTintColor: [UIColor blackColor]];
UIFont* titleFont = [UIFont fontWithName: NavigationBarTitleFontName size: NavigationBarTitleFontSize];
[self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName: titleFont, NSForegroundColorAttributeName: [UIColor whiteColor]}];
}
- (UIStatusBarStyle) preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
//MARK: - MKMapViewDelegate
-(MKAnnotationView*) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
NSLog(@"called from viewForAnnotation");
if([annotation isKindOfClass:[ MKUserLocation class]]){
return nil;
}
MKAnnotationView* annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier: MapViewReuseIdentifier];
if(!annotationView){
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:MapViewReuseIdentifier];
}else{
annotationView.annotation = annotation;
}
UIImage* shot = [[UIImage alloc] initWithContentsOfFile:@"shot3"];
annotationView.image = shot;
annotationView.frame = CGRectMake(0, 0, 60, 60);
annotationView.clipsToBounds = YES;
return annotationView;
}
@end
现在控制台上的唯一输出是
Pixel[1832:440548] (
"<Pixel.Photo: 0xa03a400> (entity: Photo; id: 0x17e905f0 <x-coredata://FB9198FE-57D1-4C88-945B-0B04D49821C0/Photo/p42> ; data: {\n latitude = \"32.88831721994364\";\n longitude = \"-117.2413945199151\";\n thumbnailData = nil;\n time = nil;\n title = \"Beach Walking\";\n whoTook = \"0xa040660 <x-coredata://FB9198FE-57D1-4C88-945B-0B04D49821C0/User/p10>\";\n})",
"<Pixel.Photo: 0xa039440> (entity: Photo; id: 0xa038b40 <x-coredata://FB9198FE-57D1-4C88-945B-0B04D49821C0/Photo/p43> ; data: {\n latitude = \"32.88831721994364\";\n longitude = \"-117.2413945199151\";\n thumbnailData = nil;\n time = nil;\n title = \"Aerial Shots of Sedona Arizona\";\n whoTook = \"0xa040660 <x-coredata://FB9198FE-57D1-4C88-945B-0B04D49821C0/User/p10>\";\n})"
)
答案 0 :(得分:0)
请您分享一下您的viewController代码,因为根据您的代码共享,我可以假设您的MapView在此代码之后启动。
if(error != nil){
NSLog(@"%@", error.localizedDescription);
}else{
if([users count] > 0){
for(User* user in users){
self.photos = (NSArray<Photo<MKAnnotation>*>*)user.photo.allObjects;
[self.mapView addAnnotations:self.photos];
}
}
}
NSLog(@"%@", self.photos);
因为在您的控制台中,这些行在您加载MapView后立即打印
2016-12-09 16:19:42.101997 Pixel[1646:397556] viewForAnnotation called
2016-12-09 16:19:42.102120 Pixel[1646:397556] annotation is the MKUserLocation
这些行应在 CoreData 结果
之前打印答案 1 :(得分:0)
我想我明白为什么我现在无法装入我的别针。这条线
self.photos = (NSArray<Photo<MKAnnotation>*>*)user.photo.allObjects;
尝试将所有photo(MKAnnotation)
分配给photos
属性,但由于核心数据的错误,实际的“数据”在您访问之前不可用。
解决方案:
创建一个名为MKAnnotation
的新PhotoAnnotation
类
这是这个类的代码
的 PhotoAnnotation.h 强>
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface PhotoAnnotation : NSObject
@property (nonatomic) CLLocationCoordinate2D coordinate;
@property (strong, nonatomic) NSString* thumbnailUrl;
- (id) initWithThumbnailUrl:(CLLocationCoordinate2D)coordinate url: (NSString*) thumbnailUrl;
@end
<强> ## PhotoAnnotation.m 强>
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import "PhotoAnnotation.h"
@interface PhotoAnnotation() <MKAnnotation>
@end
@implementation PhotoAnnotation
- (id) initWithThumbnailUrl:(CLLocationCoordinate2D)coordinate url: (NSString*) thumbnailUrl{
self = [super init];
if(self){
self.coordinate = coordinate;
self.thumbnailUrl = thumbnailUrl;
}
return self;
}
@end
像这样分配MKAnnotation
for(User* user in users){
self.photos = [[NSMutableArray alloc] init];
for(Photo* photo in user.photo){
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(photo.latitude, photo.longitude);
PhotoAnnotation* myAnnotation = [[PhotoAnnotation alloc]initWithThumbnailUrl: location url: photo.thumbnailUrl];
[self.photos insertObject:myAnnotation atIndex:0];
}
}
这会在地图上成功创建自定义MKAnnotation!