0

我的应用程序有一个带有 UIViewController 的 tabbarcontroller(FirstViewController-称之为 mapVC),带有一个 mapview 和一个 UITableViewController(SecondViewController-称之为 tableVC)。该应用程序从 Web 获取数据并将其放入 CD-db 中,每个 VC 执行对 db 的提取。每个实体都被命名为 Holiday(不要问),它有一个 lat 和 long 属性。

这是尝试将 mapVC 设置为 tableVC 的数据源的 UITabBarController 子类:

- (void)viewDidLoad{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    FirstViewController *mapVC;
    SecondViewController *tableVC;

    for(UIViewController *anyVC in self.viewControllers)
    {
        if([anyVC.class isKindOfClass:[SecondViewController class]]){
            tableVC = (SecondViewController *)anyVC;
        } else if ([anyVC.class isKindOfClass:[FirstViewController class]]){
            mapVC = (FirstViewController *)anyVC;
        }
    }

    tableVC.tableView.dataSource = mapVC;
    tableVC.tableView.delegate = mapVC;
}

以下是mapVC的相关部分:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "SecondViewController.h"

#define METERS_PER_MILE 2609.344

@interface FirstViewController : UIViewController <MKMapViewDelegate, UITableViewDataSource, UITableViewDelegate>{
    BOOL _doneInitialZoom;

}

@property (strong, nonatomic) IBOutlet MKMapView *_mapView;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *refreshButton;
@property (nonatomic, strong) NSString *entityName;
@property (strong, nonatomic) CLLocation *userLocation;

- (IBAction)refreshTapped:(id)sender;
-(void)showDetailView;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
@end

及其实施:

#import "FirstViewController.h"
#import "Holiday.h"
#import "MyLocation.h"
#import "SDCoreDataController.h"
#import "MyTabBarController.h"
#import "TableViewCell.h"

- (void)loadRecordsFromCoreData {
    [self.managedObjectContext performBlockAndWait:^{
        [self.managedObjectContext reset];
        NSError *error = nil;
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:self.entityName];
        [request setSortDescriptors:[NSArray arrayWithObject:
                                     [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES]]];
        self.farSiman = [self.managedObjectContext executeFetchRequest:request error:&error];

    }];
    NSLog(@"self.farSiman on launch = %@", self.farSiman);
}

- (void)plotStorePositions:(NSString *)responseString {

    for (id<MKAnnotation> annotation in _mapView.annotations) {
        [_mapView removeAnnotation:annotation];
    }

    NSLog(@"Dictionary is %@", self.farSiman);

    for (Holiday * holidayObject in self.farSiman) {

        NSString * latitude = holidayObject.latitude;
        NSString * longitude = holidayObject.longitude;
        NSString * storeDescription = holidayObject.name;
        NSString * address = holidayObject.address;


        CLLocationCoordinate2D coordinate;
        coordinate.latitude = latitude.doubleValue;
        coordinate.longitude = longitude.doubleValue;
        MyLocation *annotation = [[MyLocation alloc] initWithName:storeDescription address:address coordinate:coordinate distance:0];

        //
        CLLocation *pinLocation = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
        //[(MyLocation*)[view annotation] coordinate].latitude longitude:[(MyLocation*)[view annotation] coordinate].longitude]];

        self.userLocation = [[CLLocation alloc] initWithLatitude:self._mapView.userLocation.coordinate.latitude longitude:self._mapView.userLocation.coordinate.longitude];
        NSLog(@"PLOT>>userLocation is %@", userLocation);

        CLLocationDistance calculatedDistance = [pinLocation distanceFromLocation:self.userLocation];
        annotation.distance = calculatedDistance/1000;
        NSLog(@"PLOT>>Distance to pin %4.0f", annotation.distance);
        //

        [_mapView addAnnotation:annotation];

    }

}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [self.farSiman count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TableViewCell *cell = nil;

    // Check to see whether the normal table or search results table is being displayed and set the Candy object from the appropriate array
    NSLog(@"Already in CFRAIP");

    static NSString *CellIdentifier = @"HolidayCell";
    if (cell == nil) {
        cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        //cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;
    }
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    Holiday *holiday = [self.farSiman objectAtIndex:indexPath.row];
    cell.nameLabel.text = holiday.name;
    //cell.dateLabel.text = holiday.latitude;

    cell.dateLabel.text = [[self calculateDistanceForLat:[holiday.latitude doubleValue] Long:[holiday.longitude doubleValue]] stringValue];

    if (holiday.image != nil) {
        UIImage *image = [UIImage imageWithData:holiday.image];
        cell.imageView.image = image;
    } else {
        cell.imageView.image = nil;
    }
    return cell;
}

// Add new method above refreshTapped
- (NSNumber*)calculateDistanceForLat:(double)lati Long:(double)longi {
    double distancia;
    CLLocation *pinLocation = [[CLLocation alloc] initWithLatitude:lati longitude:longi];
    CLLocationDistance calculatedDistance = [pinLocation distanceFromLocation:self.userLocation];

    //test locations
    NSLog(@"pinLocations is %@, userLocation is %@", pinLocation, self.userLocation);

    distancia = calculatedDistance/1000;
    return [NSNumber numberWithDouble:distancia];
}

plotStoreLocations 方法是从 mapVC 工具栏中的 UIButton 调用的唯一方法。

至于tableVC(SecondViewController)

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface SecondViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate>

@property (nonatomic, strong) NSArray *dates;
@property (nonatomic, strong) NSString *entityName;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *refreshButton;

@property (strong,nonatomic) NSMutableArray *filteredResultsArray;
@property (strong,nonatomic) IBOutlet UISearchBar *resultsSearchBar;

@property (strong, nonatomic) CLLocation *userLocation;

- (IBAction)refreshButtonTouched:(id)sender;

及其实现:

- (void)loadRecordsFromCoreData {
    [self.managedObjectContext performBlockAndWait:^{
        [self.managedObjectContext reset];
        NSError *error = nil;
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:self.entityName];
        [request setSortDescriptors:[NSArray arrayWithObject:
                                     [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES]]];
        self.dates = [self.managedObjectContext executeFetchRequest:request error:&error];
        NSLog(@"self.dates==%@",self.dates);
    }];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [filteredResultsArray count];
    } else {
        return [self.dates count];
    }

    //return [self.dates count];
}

// Add new method above refreshTapped
- (NSNumber*)calculateDistanceForLat:(double)lati Long:(double)longi {
    double distancia;
    CLLocation *pinLocation = [[CLLocation alloc] initWithLatitude:lati longitude:longi];
    CLLocationDistance calculatedDistance = [pinLocation distanceFromLocation:self.userLocation];

    //test locations
    NSLog(@"pinLocations is %@, userLocation is %@", pinLocation, self.userLocation);

    distancia = calculatedDistance/1000;
    return [NSNumber numberWithDouble:distancia];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TableViewCell *cell = nil;

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        static NSString *CellIdentifier = @"HolidayCell";
        if (cell == nil) {
            cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }
        cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        Holiday *holiday = [filteredResultsArray objectAtIndex:indexPath.row];
        NSLog(@"the holiday is %@", holiday.name);
        cell.nameLabel.text = holiday.name;

    } else {

        static NSString *CellIdentifier = @"HolidayCell";
        if (cell == nil) {
            cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        Holiday *holiday = [self.dates objectAtIndex:indexPath.row];
        cell.nameLabel.text = holiday.name;

        cell.dateLabel.text = [[self calculateDistanceForLat:[holiday.latitude doubleValue] Long:[holiday.longitude doubleValue]] stringValue];

        if (holiday.image != nil) {
            UIImage *image = [UIImage imageWithData:holiday.image];
            cell.imageView.image = image;
        } else {
            cell.imageView.image = nil;
        }
    }
    return cell;
}

最后是我的位置:

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

@interface MyLocation : NSObject <MKAnnotation> {
    NSString *_name;
    NSString *_address;
    CLLocationCoordinate2D _coordinate;
}

@property (copy) NSString *name;
@property (copy) NSString *address;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (assign) float distance;

- (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate distance:(float)distance;

@end


#import "MyLocation.h"

@implementation MyLocation
@synthesize name = _name;
@synthesize address = _address;
@synthesize coordinate = _coordinate;
@synthesize distance = _distance;

- (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate distance:(float)distance{
    if ((self = [super init])) {
        _name = [name copy];
        _address = [address copy];
        _coordinate = coordinate;
        _distance = distance;
    }
    return self;
}

- (NSString *)title {
    if ([_name isKindOfClass:[NSNull class]]) 
        return @"Unknown charge";
    else
        return _name;
}

- (NSString *)subtitle {
    return [NSString stringWithFormat:@"A %0.2f Kms", _distance];
    //return _address;
}

具体问题:

1) 如果我在 mapVC(新数据源)中添加了 cFRAIP(noris & nosit)方法,我需要从 tableVC 中删除它吗?

2)如果我从 tableVC 中删除 cFRAIP 和其他 2 个(noris 和 nosit)方法,它会崩溃,因为没有数据源。所以数据源的 tabbarcontroller 分配似乎不起作用。

3) 最后,如果我必须从 tableVC 中删除 cFRAIP,我将失去 UISearchBar tableview 的能力。还是我错了?

当我运行应用程序时,mapVC 是选定的 vc。工具栏中调用 mapVC 中的 plotStoreLocations 的 UIButton 显示为灰色,直到 Web 获取完成。此时,控制台记录了作为假日实体的 self.farsiman 位置。我可以看到所有实体都登录到控制台。

当我单击绘图按钮时,userLocation 会按照 plotStorePositions 中的指定正确记录,并且每个注释的距离值都是正确的。所以每个 MKAnnotation 的距离计算正确。

当我切换到 tableVC 选项卡时,新的 self.dates 数组会记录在控制台中(因为我目前让 tableVC 进行另一个 CD-db 提取。我为每个引脚位置得到这个:

已经在 CFRAIP pinLocations 是 <+15.50288611,-88.02716389> +/- 0.00m(速度 -1.00 mps / course -1.00)@ 1/24/13, 8:20:39 PM 中央标准时间,userLocation 是(空)

从 CFRAIP 调用的 calculateDistanceForLat 调用。单元格细节中的每个距离都是-0.001。

4

1 回答 1

0

您肯定需要将 mapVC 设为数据源和委托。如果 UITableViewController 不允许您将其分配给其他东西,您可能需要考虑使用常规 UIViewController 并将 UITableView 放到它上面。如果你将它设置为一个名为 tableview 的属性,tabbarcontroller 中的代码tableVC.tableView.dataSource = mapVC;仍然可以工作。

是的,您可以并且应该从您的 tableVC 中删除所有 tableview 委托和数据源代码,如果它正在调用它们,那么它不会调用您想要的 mapVC 中的那些。

它可能给你错误的距离,因为 tableVC 没有用户的位置来测量。将表数据源附加到地图的另一个很好的理由。

于 2013-01-25T02:54:01.467 回答