簡體   English   中英

iOS - 當我將方法移動到另一個類時,MKMapView Overlay將不會呈現

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

正在努力清理我的代碼,以便我可以在MKMapView蘋果地圖上面渲染不同的路徑疊加,具體取決於......

目前我有一張蘋果地圖,當我在視圖控制器類“ParkMapVC”中使用兩個方法-addOverlayTo:和mapView:rendererForOverlay時,我可以獲得一個特定的疊加軌跡圖像(通過MKMapView對象)。 當我將這兩個方法移動到另一個更通用的類“ParkMapOverlay” - 一個NSObject繼承類時,我可以直接執行“addOverlayTo:”方法,而不是mapView:rendererForOverlay方法。

我沒有直接在原始(工作)版本中直接發送mapView:rendererForOverlay消息,但是從調試器開始,它似乎是由我的addOverlayTo:方法觸發的 - 我想通過返回的對象 - 雖然我不完全清楚或確定關於那個。

這有效:

    //  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

什么行不通:

此時 - 我將兩個方法 - addOverlayTo:和mapView:rendererForOverlay- out移動到類“ParkMapOverlay”。 我改變了我的消息傳遞方式addOverlayTo ,它確實從“ParkMapOverlay”類中執行 但是,根據調試器斷點,我可以看到mapView:rendererForOverlay方法沒有消息 ,實際上覆蓋層沒有呈現。 我只是看到我的蘋果地圖顯示在視圖中。

這是代碼://在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

我想知道的是什么 -

  1. 這些方法最初位於ViewController類中,現在它們位於一個NSObject子類中
  2. 因為我不完全理解MKOverlayRenderer最初是如何被調用的,所以我需要知道的是必須要做的就是現在要觸發它
  3. 關於我現在在ParkMapVC的viewDidLoad方法中向addOverlayTo:方法發送消息的方式讓我感到沮喪
  4. 我在Xamarin的“添加疊加到地圖”配方中找到了一個參考,其中說“必須在將MKOverlay添加到MkMapView之前指定OverlayRenderer方法”。 我不確定這意味着什么 - 除非它與我在發送addOverlayTo:方法之前我分配init的ParkMapOverlay對象的對象有關?

謝謝。 LRS

mapView:rendererForOverlay:<MKMapViewDelegate>協議的方法。

在新的addOverlayTo:方法中,您正在初始化新的MKMapView對象,但未將ParkMapOverlay對象設置為該地圖視圖的委托。 這就是為什么不調用mapView:rendererForOverlay:原因。

嘗試將其設置為mapView.delegate = self

還要注意內存管理:MKMapView的delegate是一個弱屬性,即它不保留其委托,所以你必須確保保留你的ParkMapOverlay對象。

當前保留應該正確發生,因為你在一個類中同時具有覆蓋功能和mapView:rendererForOverlay:方法,以便通過-[MKMapView addOverlay:]將該類添加為覆蓋,確保保留對象,但這是你設計的副作用,所以要意識到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM