2013-01-25 1 views
0

내 응용 프로그램에는 mapView 및 UITableViewController (SecondViewController - tableVC 호출)를 사용하여 UIViewController (FirstViewController - 호출 mapVC)가있는 tabbarcontroller가 있습니다. 응용 프로그램은 웹에서 데이터를 가져와 CD-db에 넣고 각 VC는 db에 대한 페치를 실행합니다. 각 엔티티는 Holiday (dont ask)로 이름 지어지며 위도와 경도가 있습니다.MapViewController를 셀에 거리 표시를 위해 TableViewController에 Datasource로 설정하는 방법

#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]; 
} 
여기
- (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의 부분이다 : 여기

는 tableVC에 소스로 mapVC을 설정하려고 시도 UITabBarController가 하위 인

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은 웹 가져 오기가 완료 될 때까지 회색으로 표시됩니다. 이 시점에서 콘솔은 휴일 엔티티 인 self.farsiman 위치를 기록합니다. 모든 엔티티가 콘솔에 로그인하는 것을 볼 수 있습니다.

플롯 버튼을 클릭하면 userLocation이 plotStorePositions에 지정된대로 올바르게 로깅되고 각 주석의 거리 값이 정확합니다. 따라서 각 MKAnnotation의 거리가 올바르게 계산됩니다.

나는 tableVC 탭으로 전환하면 새로운 self.dates 어레이 (I 현재 tableVC 다른 할 수 있기 때문에 CD를-DB 가져 그리고 각 핀 위치이 얻을 콘솔에 기록됩니다.

이미 CFRAIP에 있습니다. 핀 위치는 < + 15.50288611, -88.02716389> +/- 0.00m (속도 -1.00 mps/코스 -1.00) @ 1/24/13, 오후 8:20:39 PM 중부 표준시, userLocation은 (null)

이것은 CFRAIP에 의해 호출되는 calculateDistanceForLat에서 호출됩니다.셀 세부 사항의 모든 거리는 -0.001입니다.

+0

새로운 질문을 시작하는 것에 대해 오해 할 수도 있습니다. 대리인과 데이터 소스가 작동한다고 생각 했으므로 cFRAIP를 사용하여 각 셀에 올바른 MyLocation의 데이터가 표시 될 수 있도록 도움을 받아야했습니다. – Craig

답변

0

확실히 mapVC에 데이터 소스와 델리게이트를 만들어야합니다. UITableViewController 당신이 그것을 다른 무언가에 할당시키는 것을 허용하지 않는다면 일반 UIViewController를 사용하여 UITableView를 드롭하는 것을 고려할 수 있습니다. 테이블 뷰라는 속성으로 설정하면 tableVC.tableView.dataSource = mapVC;을 수행하는 tabbarcontroller의 코드가 여전히 작동합니다.

예, tableVC에서 모든 tableview 위임 및 데이터 소스 코드를 제거 할 수 있고 필요하다면, 원하는 경우 해당 항목을 mapVC에서 호출하지 않을 수 있습니다.

tableVC에 측정 할 사용자 위치가 없기 때문에 아마도 잘못된 거리를 제공 할 것입니다. 테이블 데이터 소스가 맵에 첨부 된 다른 좋은 이유.

+0

ok 그러나 tableVC에서 cFRAIP를 제거하면 내 UISearchBar가 tableVC에서 작동합니까?
더하기, SecondLockController에서 MyLocations 개체에 액세스 할 수 없습니까? 아마도 저는 그것들을 사용하여 세포를 만들 수 있습니까? – marciokoko

+0

"http : //stackoverflow.com/questions/12265093/uisearchbar-uitableview"로 나를 안내 한 "http://www.google.com/search?q=uisearchbar+uitableview"를 검색하여 "http : //www.appcoda.com/how-to-add-search-bar-uitableview/ "나머지는 귀하에게 달려 있습니다. 또한 secondviewcontroller가 셀을 만들지 않고 데이터 소스 (mapvc)는 – Craig

+0

입니다. 이미 uISearchBar가 tableviewcontroller에 구현되어 있습니다. 이 아이디어를 대안으로 볼 수 있습니까? http://stackoverflow.com/questions/14514832/how-do-i-pass-mylocation-values-from-mapviewcontroller-to-uitableviewcontroller – marciokoko

관련 문제