0

xibで設計されたUITableView*myTableおよびMKMapView*myMapを備えたViewControllerがありますが、テーブルデリゲート/データソースとマップデリゲートはSubClassという名前の別のクラスにあります。ViewControllerのボタンを押すと、サブクラスはxmlリモートファイルからテーブルセルの緯度と経度を解析します。myTableの行を選択するたびに、myMapをこの座標にズームしたいと思います。方法が見つかりません。このズームをFROMサブクラスと呼びます。これは、単純化した私のコードです。

ViewController.h

// ViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "SubClass.h"

@interface ViewController : UIViewController {
    IBOutlet UITableView *myTable;
    IBOutlet MKMapView *myMap;
    SubClass *subClassIstance;
}

- (void)buttonPressed:(id)sender
@property (nonatomic, retain) IBOutlet MKMapView *myMap;

ViewController.m

// in ViewController.m

- (void)buttonPressed:(id)sender {
    subClassIstance = [[SubClass alloc] init];
    myTable.delegate = SubClass;
    myTable.dataSource = SubClass;
    [myTable reloadData];

    subClassIstance = [[SubClass alloc] loadMap:myMap];
}

SubClass.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface SubClass : NSObject <UITableViewDataSource, UITableViewDelegate, MKMapViewDelegate> {
}

- (void)loadValues;
- (id)loadMap:(MKMapView *)mapView;
- (id)zoomTheMap:(NSMutableString *)string1 :(NSMutableString *)string2 :(MKMapView *)mapView; // IS IT RIGHT???

SubClass.m

- (id)init{
    self = [super init];
 if ( self != nil ) {
     [self loadValues];
 }
    return self;
}

- (void)loadValues {

  // CODE TO PARSE VALUES OF LONGITUDE AND LATITUDE TO PASS IN THE TABLE CELLS
 latitudeFromLoadValues = // NSMutableString parsed value from a xml remote file
 longitudeFromLoadValues = // NSMutableStringparsed value from a xml remote file
}

- (id)loadMap:(MKMapView *)mapView
{
    if (self) {
    mapView.delegate = self; // CODE TO LOAD ANNOTATIONS AND OTHER STUFF. IT WORKS!
    }
    return self;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
latitudeFromLoadValues = [dataParsed objectAtIndex:indexPath.row];
longitudeFromLoadValues = [data2Parsed objectAtIndex:indexPath.row];
[self zoomTheMap:latitudeFromLoadValues :longitudefromLoadValues :???]; // IS IT CORRECT? WHAT IS THE RIGHT *MKMAPVIEW?
}

- (id)zoomTheMap:(NSMutableString *)string1 :(NSMutableString *)string2 :(MKMapView *)mapView {

    NSLog(@"%@",string1);
    NSLog(@"%@",string2);

    MKCoordinateRegion region;
    region.center.latitude = [string1 floatValue];
    region.center.longitude = [string2 floatValue];
    region.span.latitudeDelta = 2.0;
    region.span.longitudeDelta = 2.0;

    // I KNOW, I HAVE TO CALL myMap from ViewController! But with an istance?

    mapView.delegate = self;
    mapView.region = region;    

    return self;
}

さて、残りのコードは機能します!SubClassで宣言されたいくつかの注釈がロードされたViewControllerの*myMapと、SubClassで解析された緯度と経度が入力されたセルがロードされた*myTableを見ることができます。string1とstring2で渡された正しい経度と緯度も確認できますが、単一のテーブルセルを選択すると、myMapのズームが表示されないため、間違った方法を使用していると思います。助けてもらえますか?

4

2 に答える 2

1

loadMap戻るべきではありませんself。initメソッドだけがそれを行う必要があります。buttonPressed新しいサブクラスを割り当てる場合は、それにいくつかの処理を行ってから、別のサブクラスを割り当ててその関数を呼び出しますloadMap。最後の行はである必要があり[subClassIstance loadMap:myMap]ますが、そのボタンが押されるたびに新しいサブクラスを割り当てることも再検討する必要があります。

私はあなたが本当にこれについて間違った方法で行っていると思います。なぜサブクラスが必要なのですか(ひどい名前ですが、それが何のためにあるのかについては何も述べていません)?それはどのクラスを拡張しますか?ViewControllerにMKMapViewがある場合、通常はマップにコマンドを発行するものです。テーブルビュー用に別のデータソースがあることは理解できますが、残りは理解できません。VCを独自のテーブルとマップデリゲートにすると、作業が大幅に簡素化されます。

コードにサブクラスが本当に必要な場合は、buttonPressedの最初の行で作成したインスタンスでloadMapを呼び出す必要があります。

- (void)buttonPressed:(id)sender {
    subClassIstance = [[SubClass alloc] init];
    myTable.delegate = SubClass;
    myTable.dataSource = SubClass;
    [myTable reloadData];

    [subClassIstance loadMap:myMap];
}

そしてあなたのloadMapは次のようになります

- (void)loadMap:(MKMapView *)mapView
{
    mapView.delegate = self; 
}

ただし、それがすべてloadMapである場合は、そのための関数は必要ありません。buttonPressedにすべてを実行させることができます。

- (void)buttonPressed:(id)sender {
    subClassIstance = [[SubClass alloc] init];
    myTable.delegate = SubClass;
    myTable.dataSource = SubClass;
    [myTable reloadData];

    myMap.delegate = subClassIstance;
}

init関数の例:

- (id)initiWithMapView: (MKMapView)* mapView
{
    self = [super init];
    if(self)
    {
       theMap = mapView;
       theMap.delegate = self;
       [self loadValues];
       ....
    }
    return self;
 }

これを使用する場合、マップデリゲートを設定したり、常に自分自身を返す必要はなく、すべての関数で(回答で宣言されているように)theMapを使用できます。

于 2012-10-21T01:30:53.860 に答える
0

興味のある人のために、簡単な解決策を見つけました。最初に、SubClass.hで汎用のMKMapView * theMapを定義しました。これは、次のようになります。

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface SubClass : NSObject <UITableViewDataSource, UITableViewDelegate, 

MKMapViewDelegate> {
        MKMapView *theMap // NEW CODE!!!
    }

- (void)loadValues;
- (id)loadMap:(MKMapView *)mapView;
- (id)zoomTheMap:(NSMutableString *)string1 :(NSMutableString *)string2 :(MKMapView *)mapView;

loadMapメソッドで、* theMapをVCのSubClassIstanceによって呼び出されるmapView(ズームしたい* myMap)と比較したので、次のようになります。

- (id)loadMap:(MKMapView *)mapView
{
    if (self) {
    mapView.delegate = self; 
    theMap = mapView; // NEW CODE !!!

    // CODE TO LOAD ANNOTATIONS AND OTHER STUFF. IT WORKS!
    }
    return self;
}

didSelectRowAtIndexPathで、zoomTheMapメソッドのmapView引数として*theMapを渡しました。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
latitudeFromLoadValues = [dataParsed objectAtIndex:indexPath.row];
longitudeFromLoadValues = [data2Parsed objectAtIndex:indexPath.row];
[self zoomTheMap:latitudeFromLoadValues :longitudefromLoadValues :theMap]; // NEW CODE !!!
}

ZoomTheMapメソッドは変更されません。現在、「魔法のように」、テーブルの行を押すたびに、VCxibで設計された*myMap(ただし、サブクラスのデリゲートを使用)は、セルに格納されている座標にズームインします。

- (id)zoomTheMap:(NSMutableString *)string1 :(NSMutableString *)string2 :(MKMapView *)mapView {

    MKCoordinateRegion region;
    region.center.latitude = [string1 floatValue];
    region.center.longitude = [string2 floatValue];
    region.span.latitudeDelta = 2.0;
    region.span.longitudeDelta = 2.0;

    mapView.delegate = self; // here mapView is *theMap passed in didSelectRowAtIndexPath, AKA original mapView istance used to delegate *myMap in VC
    [mapView setRegion:region animated:YES];   

    return self;
}

「エレガント」な方法ではないかもしれませんが、今では機能します。; =)

于 2012-10-22T08:44:23.143 に答える