无法使用 MapKit 中的核心数据模型类添加注释



我试图将核心数据模型类用作我的自定义注释,但是以某种方式从未调用ViewForantation。

这是我的视图控制器,其中包含所有核心数据段以及我如何实现委托方法

#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})"
)

您可以分享您的ViewController代码

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 结果

之前打印

我想我明白为什么我现在无法加载我的PIN。线

 self.photos = (NSArray<Photo<MKAnnotation>*>*)user.photo.allObjects;

试图将所有photo(MKAnnotation)分配给photos属性,但是由于核心数据的故障,直到您访问它才可用。

解决方案:创建一个名为PhotoAnnotation的新MKAnnotation类这是此类的代码 fothantation.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

## fothantotation.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!

最新更新