简体   繁体   English

iOS - 当我将方法移动到另一个类时,MKMapView Overlay将不会呈现

[英]iOS - MKMapView Overlay won't render when I move methods to another class

Working on cleaning up my code so I can render different overlays of trails atop an MKMapView apple map, depending... 正在努力清理我的代码,以便我可以在MKMapView苹果地图上面渲染不同的路径叠加,具体取决于......

Currently I have an apple map coming up and I can get a specific overlay trail image rendered (over an MKMapView object) when I use two methods -addOverlayTo: and mapView:rendererForOverlay - within my view controller class "ParkMapVC". 目前我有一张苹果地图,当我在视图控制器类“ParkMapVC”中使用两个方法-addOverlayTo:和mapView:rendererForOverlay时,我可以获得一个特定的叠加轨迹图像(通过MKMapView对象)。 When I move those two methods to another more generic class "ParkMapOverlay" - an NSObject inheriting class, I can get the "addOverlayTo:" method I message directly to execute, but not the mapView:rendererForOverlay method. 当我将这两个方法移动到另一个更通用的类“ParkMapOverlay” - 一个NSObject继承类时,我可以直接执行“addOverlayTo:”方法,而不是mapView:rendererForOverlay方法。

I didn't directly message mapView:rendererForOverlay in the original (working) version, but from following the debugger, it seemed it was triggered by my addOverlayTo: method - I think by the object returned - though I'm not entirely clear or sure about that. 我没有直接在原始(工作)版本中直接发送mapView:rendererForOverlay消息,但是从调试器开始,它似乎是由我的addOverlayTo:方法触发的 - 我想通过返回的对象 - 虽然我不完全清楚或确定关于那个。

This works: 这有效:

    //  ParkMapVC.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "ParkMap.h"
#import "ParkMapVC.h"
@interface ParkMapVC : UIViewController <MKMapViewDelegate>{
}
@property (strong, nonatomic) IBOutlet MKMapView *hikeMap;
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (nonatomic, strong) ParkMap *park;
+ (ParkMapVC *) sharedParkMapVC;
- (void)addOverlayTo :(ParkMap*) thePark;
@end
#import "ParkMapVC.h"
#import "ParkMap.h"
#import "ParkMapOverlay.h"
#import "ParkMapOverlayView.h"
@interface ParkMapVC ()
@end
//*************
@implementation ParkMapVC
+ (ParkMapVC *) sharedParkMapVC {
    static ParkMapVC *sharedParkMapVC;
    @synchronized (self) {
        if (!sharedParkMapVC) {
            sharedParkMapVC = [[ParkMapVC alloc] init ];

        }
    return sharedParkMapVC;
    }

}
 - (void)viewDidLoad
{
    [super viewDidLoad];
    self.park = [[ParkMap alloc] initWithFilename:@"EdgewoodVer2"]; // plist
    // define region for apple map
     self.mapView.region = [self.park defineMapRegion:self.park];
    [self addOverlayTo:_park];
}
#pragma mark - Add methods
- (void)addOverlayTo :(ParkMap*) thePark{
    ParkMapOverlay *overlay = [[ParkMapOverlay alloc]          
                                       initWithPark:self.park];
    [self.mapView addOverlay:overlay];
}
#pragma mark - Map View delegate
// This should go to ParkMapOverlay 8.5.15
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {

        UIImage *overlayEdgewoodImage = [UIImage
            imageNamed:@"EDGEoverlay_park_Cropped"];

        ParkMapOverlayView *overlayView = [[ParkMapOverlayView alloc] initWithOverlay:overlay overlayImage:overlayEdgewoodImage];

        return overlayView;

  }

@end

What does not work : 什么行不通:

At this point - I moved the two methods - addOverlayTo: and mapView:rendererForOverlay- out to the class "ParkMapOverlay". 此时 - 我将两个方法 - addOverlayTo:和mapView:rendererForOverlay- out移动到类“ParkMapOverlay”。 I changed the way I was messaging addOverlayTo and it does execute from within the "ParkMapOverlay" class. 我改变了我的消息传递方式addOverlayTo ,它确实从“ParkMapOverlay”类中执行 However, based on debugger breakpoints, I can see that the mapView:rendererForOverlay method is not messaged , and indeed the overlay is not rendered. 但是,根据调试器断点,我可以看到mapView:rendererForOverlay方法没有消息 ,实际上覆盖层没有呈现。 I just see my apple map displayed in the view. 我只是看到我的苹果地图显示在视图中。

Here is the code: //Within ParkMapVC I altered overlay to message the new class ParkMapOverlay 这是代码://在ParkMapVC中我改变了覆盖层以消息新类ParkMapOverlay

  [super viewDidLoad];
    self.park = [[ParkMap alloc] initWithFilename:@"EdgewoodVer2"]; 
    ParkMapOverlay *theOverlay = [[ParkMapOverlay alloc]init];

    self.mapView.region = [self.park defineMapRegion:self.park];
    self.mapView = [theOverlay addOverlayTo:_park ];

// Then I commented out the original two methods, moving the code to ParkMapOverlay 

//  ParkMapOverlay.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@class ParkMap;
@interface ParkMapOverlay : NSObject <MKOverlay, MKMapViewDelegate>
- (instancetype)initWithPark:(ParkMap *)park;
- (MKMapView *)addOverlayTo :(ParkMap*) thePark;
@end

//  ParkMapOverlay.m
#import "ParkMapOverlay.h"
#import "ParkMapOverlayView.h" 
#import "ParkMap.h"
@implementation ParkMapOverlay
@synthesize coordinate;
@synthesize boundingMapRect;
- (instancetype)initWithPark:(ParkMap *)park {
    self = [super init];
    if (self) {
        boundingMapRect = park.overlayBoundingMapRect;
        coordinate = park.midCoordinate;
    }

    return self;
}
- (MKMapView *)addOverlayTo :(ParkMap*) thePark
{
     ParkMapOverlay *overlay = [[ParkMapOverlay alloc]      initWithPark:thePark];
     MKMapView *mapView = [[MKMapView alloc] init];
    [mapView addOverlay:overlay];

    return mapView;

}
#pragma mark - Map View delegate


- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
           UIImage *overlayEdgewoodImage = [UIImage
                                      imageNamed:@"EDGEoverlay_park_Cropped"];

        ParkMapOverlayView *overlayView = [[ParkMapOverlayView alloc] initWithOverlay:overlay overlayImage:overlayEdgewoodImage];

        return overlayView;

    }
@end

What I wonder about - 我想知道的是什么 -

  1. The methods were originally in a ViewController class, now they are in a class that is an NSObject child 这些方法最初位于ViewController类中,现在它们位于一个NSObject子类中
  2. Because I don't entirely understand how the MKOverlayRenderer is invoked originally, there is something I need to know about that has to be done to trigger that now 因为我不完全理解MKOverlayRenderer最初是如何被调用的,所以我需要知道的是必须要做的就是现在要触发它
  3. Something about the way I now message the addOverlayTo: method in my viewDidLoad method in ParkMapVC is tripping me up 关于我现在在ParkMapVC的viewDidLoad方法中向addOverlayTo:方法发送消息的方式让我感到沮丧
  4. I found a reference in Xamarin in the "Add an Overlay to a Map" recipe, that says "The OverlayRenderer method must be assigned to prior to adding the MKOverlay to the MkMapView". 我在Xamarin的“添加叠加到地图”配方中找到了一个参考,其中说“必须在将MKOverlay添加到MkMapView之前指定OverlayRenderer方法”。 I'm not sure what this means - unless it has to do with the object that ParkMapOverlay object I alloc init before I message the addOverlayTo: method ? 我不确定这意味着什么 - 除非它与我在发送addOverlayTo:方法之前我分配init的ParkMapOverlay对象的对象有关?

Thank you. 谢谢。 LRS LRS

mapView:rendererForOverlay: is a method of <MKMapViewDelegate> protocol. mapView:rendererForOverlay:<MKMapViewDelegate>协议的方法。

In your new addOverlayTo: method you are initializing new MKMapView object but are not setting your ParkMapOverlay object as that map view's delegate. 在新的addOverlayTo:方法中,您正在初始化新的MKMapView对象,但未将ParkMapOverlay对象设置为该地图视图的委托。 This is why mapView:rendererForOverlay: is not called. 这就是为什么不调用mapView:rendererForOverlay:原因。

Try to set it like mapView.delegate = self . 尝试将其设置为mapView.delegate = self

Also be careful with memory management: MKMapView's delegate is a weak property ie it does not retain its delegate so you must be sure to keep your ParkMapOverlay object retained. 还要注意内存管理:MKMapView的delegate是一个弱属性,即它不保留其委托,所以你必须确保保留你的ParkMapOverlay对象。

Currently retain should happen correctly because you have both overlay functionality and mapView:rendererForOverlay: method in one class so that adding that class as overlay via -[MKMapView addOverlay:] ensures that object is retained but that is a side-effect of your design so be aware of it. 当前保留应该正确发生,因为你在一个类中同时具有覆盖功能和mapView:rendererForOverlay:方法,以便通过-[MKMapView addOverlay:]将该类添加为覆盖,确保保留对象,但这是你设计的副作用,所以要意识到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM