2013-01-25 56 views
0

我的應用程序具有帶有帶有mapview和UITableViewController(SecondViewController-稱爲tableVC)的UIViewController(FirstViewController-稱爲mapVC)的tabbarcontroller。該應用程序從Web獲取數據並將其放入CD-db,每個VC執行一次對數據庫的提取。每個實體都被命名爲假日(不要問),它有一個lat和long屬性。如何將MapViewController作爲Datasource設置爲TableViewController以顯示單元格中的距離

這裏是的UITabBarController子類,可以嘗試設置mapVC作爲數據源,以tableVC:

- (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方法是UIButton中唯一的方法調用mapVC工具欄。

至於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; 
} 

最後MyLocation:

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 /當然-1.00)@ 1/24/13,8:20:39 PM Central Standard Time,userLocation是( null)

它是由CFRAIP調用的calculateDistanceForLat調用的。細胞細節中的每個距離都是-0.001。

+0

我可能會誤導你開始一個新的問題。我認爲你的委託和數據源正在工作,你想要的只是幫助cFRAIP,以便每個單元顯示正確的MyLocation的數據。 – Craig

回答

0

你一定要做出mapVC數據源和委託。如果UITableViewController不讓你將它分配給其他自己,你可能會考慮使用常規的UIViewController並將UITableView放到它上面。如果您將其設置爲名爲tableview的屬性,tabbarcontroller中的代碼tableVC.tableView.dataSource = mapVC;仍然可以工作。

是的,你可以而且應該從你的tableVC刪除所有的tableview委託和數據源代碼,如果調用這些則不是要求在mapVC這是你想要什麼的人。

它可能給你錯誤的距離,因爲tableVC沒有用戶從測量位置。將表格數據源附加到地圖的另一個好理由。

+0

好吧,但如果我從tableVC中刪除cFRAIP,我的UISearchBar將爲tableVC工作嗎?
加,不應該我能夠從SecondViewController訪問MyLocations對象?也許我可以用它們來創建單元格? – marciokoko

+0

我搜索「http://www.google.com/search?q=uisearchbar+uitableview」,它帶我去「http://stackoverflow.com/questions/12265093/uisearchbar-uitableview」,這使我的「http ://www.appcoda.com/how-to-add-search-bar-uitableview/「其餘的由你決定。另外,你的secondviewcontroller沒有製作單元格,數據源(mapvc)是 – Craig

+0

我已經在tableviewcontroller中實現了uISearchBar。你可以看看這個想法作爲替代:http://stackoverflow.com/questions/14514832/how-do-i-pass-mylocation-values-from-mapviewcontroller-to-uitableviewcontroller – marciokoko

相關問題