Xcode 从另一个类缩放MkMapView
我在xib中设计了一个带有UITableView*myTable和MKMapView*myMap的ViewController,但是表委托/数据源和映射委托位于另一个类中,名为SubClass。当我按下ViewController中的一个按钮时,子类将解析来自xml远程文件的tablecells latitude和longitude中的子类,现在我想在每次选择myTable的行时将myMap缩放到这个坐标系中:嗯,我找不到一种方法来调用这个zoom from子类。这是我的简化代码: ViewController.hXcode 从另一个类缩放MkMapView,xcode,uitableview,mkmapview,Xcode,Uitableview,Mkmapview,我在xib中设计了一个带有UITableView*myTable和MKMapView*myMap的ViewController,但是表委托/数据源和映射委托位于另一个类中,名为SubClass。当我按下ViewController中的一个按钮时,子类将解析来自xml远程文件的tablecells latitude和longitude中的子类,现在我想在每次选择myTable的行时将myMap缩放到这个坐标系中:嗯,我找不到一种方法来调用这个zoom from子类。这是我的简化代码: ViewCo
// 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;
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???
好了,剩下的代码都可以用了!我可以看到ViewController中的*myMap加载了一些在子类中声明的注释,*myTable加载了在子类中解析的纬度和经度填充的单元格;我还可以看到在string1和string2中传递的正确经度和纬度,但是当我选择单个表格单元格时,我没有看到myMap缩放,我认为我使用了错误的方法。你能帮我一下吗?
loadMap
不应该返回self
,只有init方法应该这样做。
在buttonPressed
中,分配一个新的子类,对其执行一些操作,然后分配另一个子类并调用其loadMap
函数。最后一行应该是[子类加载映射:myMap]
,但是每次按下该按钮时,您还需要重新考虑分配一个新的子类
我认为你真的走错了方向。为什么您需要一个子类(顺便说一句,这个名字很糟糕,它没有说明它的用途)?它延伸到哪一类?如果ViewController具有MKMapView,则通常由它向地图发出命令。我可以理解您对tableview有一个单独的datasoucre,但其他的都没有。如果你让VC有自己的表和映射委托,你会简化很多事情
如果您真的想在代码中包含一个子类,那么应该在buttonPressed的第一行创建的实例上调用loadMap
- (void)buttonPressed:(id)sender {
subClassIstance = [[SubClass alloc] init];
myTable.delegate = SubClass;
myTable.dataSource = SubClass;
[myTable reloadData];
[subClassIstance loadMap:myMap];
}
你的地图看起来像
- (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;
}
初始化函数示例:
- (id)initiWithMapView: (MKMapView)* mapView
{
self = [super init];
if(self)
{
theMap = mapView;
theMap.delegate = self;
[self loadValues];
....
}
return self;
}
如果您使用此选项,您不必一直设置映射委托或返回self,您可以在每个函数中使用map(如您的答案中所声明的)。好吧,我为感兴趣的人找到了一个简单的解决方案:首先,我在我的子类.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;
在didSelectRowAtIndexPath中,我已将*theMap作为zoomTheMap方法的mapView参数传递:
- (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方法没有改变,现在,“神奇地”,每次我按下表中的一行时,VC xib中设计的*myMap(但在子类中带有delegate)就会放大到存储在单元格中的坐标:
- (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;
}
也许这不是一种“优雅”的方式,但它现在起作用了!;=) 谢谢你Craig,这里的obv“ViewController”和“SubClass”是表示我的类的通用名称,而不是代码中使用的真实名称。我还使用-(id)loadMap(MKMapView)mapView,然后使用[return self]从ViewController中使用loadMap:myMap调用此方法,但我知道这是一种复杂的方法:我将重新考虑在VC中编写map委托..啊,我现在得到了子类名称。我关于loadMap返回self的观点仍然站得住脚。我将更新上面的答案,向您展示您可以做的两个改进。是的,您编辑的答案与我的代码类似,但如果在-(id)loadMap:(MKMapView*)mapView方法中,我不会写“return self”;XCode给出“警告:控件到达非void函数的末尾”,这是因为我忘了告诉您更改loadmap的声明以不返回任何内容。我现在已经修复了这个问题,并添加了一个init函数。你的代码到处都是。您不需要在编写的每个函数上返回
self
。就在调用哪个函数时,它需要一个引用供以后使用。如果将函数声明为-(void)…
而不是-(id)…
,则可以删除返回self
行。然后,不要每次都设置委托。在初始化期间执行一次。最后,如果在初始化过程中也设置了theMap
,则无需将其传递到zoomTheMap,它只需使用theMap
。谢谢Craig,我还根据您的建议“清理”了我的代码……;=)
- (id)loadMap:(MKMapView *)mapView
{
if (self) {
mapView.delegate = self;
theMap = mapView; // NEW CODE !!!
// 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 :theMap]; // NEW CODE !!!
}
- (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;
}