iOS - 当我将方法移动到另一个类

时间:2015-08-05 19:52:44

标签: ios objective-c iphone overlay

继续清理我的代码,以便我可以在MKMapView苹果地图的顶部渲染不同的路径叠加层,具体取决于......

目前我有一张苹果地图,当我使用两种方法-addOverlayTo:和mapView:rendererForOverlay - 我的视图控制器类" ParkMapVC&时,我可以获得一个特定的叠加轨迹图像(在MKMapView对象上) #34 ;.当我将这两种方法移动到另一个更通用的类" ParkMapOverlay" - 一个NSObject继承类,我可以获取" addOverlayTo:"方法I直接执行消息,但不是mapView:rendererForOverlay方法。

我没有在原始(工作)版本中直接发送mapView:rendererForOverlay消息,但是从调试器开始,它似乎是由我的addOverlayTo:方法触发的 - 我想通过返回的对象 - 虽然我&#39 ;我不完全清楚或确定。

这有效:

    //  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移到了类&#34; ParkMapOverlay&#34;。我改变了我的消息传递方式 addOverlayTo ,并且确实执行来自&#34; ParkMapOverlay&#34;类。但是,根据调试器断点,我可以看到 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中找到了一个参考文献&#34;在地图中添加叠加层&#34;配方,说&#34;必须在将MKOverlay添加到MkMapView&#34;之前指定OverlayRenderer方法。我不确定这意味着什么 - 除非它与我在发送addOverlayTo:方法消息之前我分配init的ParkMapOverlay对象的对象有关?
  5. 谢谢。 LRS

1 个答案:

答案 0 :(得分:1)

ActorDmapView:rendererForOverlay:协议的方法。

在新的<MKMapViewDelegate>方法中,您正在初始化新的MKMapView对象,但未将ParkMapOverlay对象设置为该地图视图的委托。这就是为什么addOverlayTo:没有被调用的原因。

尝试将其设置为mapView:rendererForOverlay:

还要注意内存管理:MKMapView的mapView.delegate = self是一个弱属性,即它不保留其委托,所以你必须确保保留你的ParkMapOverlay对象。

当前保留应该正确发生,因为您在一个类中同时具有覆盖功能和delegate方法,因此通过mapView:rendererForOverlay:将该类添加为覆盖可确保保留该对象,但这是一个副作用你的设计要注意它。