I have a view controller(VC) having 3 buttons(country , state , city). On click of these buttons , i am presenting another VC(using popover segue) , which is a search table to search country (or states or city). Now if user clicks two buttons , then both the view controller are presented at the same time. I want only one to be presented.How to do this?
Tried self.view.multipleTouchEnabled = NO; but not working.
code of the searchVC:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIImage *bgApplication = [UIImage imageNamed:#"bg-app-568h.jpg"];
self.view.backgroundColor = [UIColor colorWithPatternImage:bgApplication];
self.searchItems = [self loadData];
self.filteredSearchItems = [NSMutableArray arrayWithCapacity:[self.searchItems count]];
for (UIView *view in self.SearchBarBase.subviews){
if ([view isKindOfClass: [UITextField class]]) {
UITextField *tf = (UITextField *)view;
tf.delegate = self;
break;
}
}
}
- (NSArray *)loadData
{
MatchDayDataController * sharedController = [MatchDayDataController sharedDataController];
NSArray *data = [sharedController fetchStates];
//NSLog(#"states: %#", data);
return data;
}
Code of the presenter VC:
-(void) viewWillAppear:(BOOL)animated
{
keyboardIsShown = NO;
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
// Load match venue data
self.locationField.text = sharedController.matchVenue;
//Load home team related data
NSString *stateText = [sharedController.homeStateName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([stateText length] == 0 )
{
self.selectHomeAssoc.enabled = NO;
self.selectHomeClub.enabled = NO;
}
NSString *homeAssocText = [sharedController.homeAssociationName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([homeAssocText length] == 0 )
{
self.selectHomeAssoc.enabled = YES;
self.selectHomeClub.enabled = NO;
}
NSString *homeClubText = [self.homeClub.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([homeClubText length] == 0 )
{
self.selectHomeClub.enabled = YES;
}
self.stateTextFieldHome.text = sharedController.homeStateName;
self.homeAssociation.text = sharedController.homeAssociationName;
self.homeClub.text = sharedController.homeClubName;;
self.homeTeam.text = sharedController.homeTeamName;
// Away team related data
self.stateTextFieldAway.text = sharedController.awayStateName;
self.awayAssociation.text = sharedController.awayAssocationName;
self.awayClub.text = sharedController.awayClubName;
self.awayTeam.text = sharedController.awayTeamName;
}
- (void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.matchVenue = self.locationField.text;
// Save Venue related data
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm"];
NSString *dateTimeString = [self.dateField.text stringByAppendingString:#" "];
dateTimeString = [dateTimeString stringByAppendingString:self.timeField.text];
//NSLog(#"DateTimeString : %#", dateTimeString);
NSDate *matchDateTime = [dateFormatter dateFromString:dateTimeString];
sharedController.inspectionDate = matchDateTime;
//Save Home team related data
sharedController.homeTeamName = self.homeTeam.text;
// Save away team related data
sharedController.awayTeamName = self.awayTeam.text;
[sharedController saveData];
// hide the keyboard when we come back after leaving the cursor on text field.
// I have called resignFirstResponder on homeTeam Text field. You can use any of text field to hide.
[self.homeTeam resignFirstResponder];
[self.awayTeam resignFirstResponder];
}
- (void)viewDidDisappear:(BOOL)animated
{
[self.view endEditing:YES];
[super viewDidDisappear:animated];
}
// This event is called when the user clicks on Done/Next button in the key board.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)segue sender:(id)sender
{
if (![sender isKindOfClass:[UIBarButtonItem class]]) {
return true;
}
return [JLTValidator validateFields:#[self.locationField, self.dateField, self.timeField, self.homeTeam, self.homeClub, self.homeAssociation, self.stateTextFieldHome, self.stateTextFieldAway, self.awayAssociation, self.awayClub, self.awayTeam]];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//NSLog(#"segue.identifier : %#", segue.identifier);
self.popSegue = (UIStoryboardPopoverSegue *)segue;
if([segue.identifier isEqualToString:#"toSearchHomeStateFromButton"]
|| [segue.identifier isEqualToString:#"toSearchHomeStateFromText"] )
{
SearchHomeStateViewController *viewController = segue.destinationViewController;
viewController.delegate = (id) self;
}
else if ([segue.identifier isEqualToString:#"toSearchHomeAssocFromButton"] || [segue.identifier isEqualToString:#"toSearchHomeAssocFromText"])
{
HomeAssocSearchViewController *viewController = segue.destinationViewController;
viewController.delegate = (id) self;
}
else if ([segue.identifier isEqualToString:#"toSearchHomeClubFromButton"] || [segue.identifier isEqualToString:#"toSearchHomeClubFromText"])
{
SearchHomeClubViewController *viewController = segue.destinationViewController;
viewController.delegate = (id) self;
}
else if([segue.identifier isEqualToString:#"toSearchAwayStateFromButton"] || [segue.identifier isEqualToString:#"toSearchAwayStateFromText"])
{
StateViewController *viewController = segue.destinationViewController;
viewController.delegate = (id) self;
}
else if ([segue.identifier isEqualToString:#"toSearchAwayAssocFromButton"] || [segue.identifier isEqualToString:#"toSearchAwayAssocFromText"])
{
SearchAwayAssocViewController *viewController = segue.destinationViewController;
viewController.delegate = (id) self;
}
else if ([segue.identifier isEqualToString:#"toSearchAwayClubFromButton"] || [segue.identifier isEqualToString:#"toSearchAwayClubFromText"])
{
SearchAwayClubViewController *viewController = segue.destinationViewController;
viewController.delegate = (id) self;
}
}
-(void) searchHomeStateDone:(NSString *)selectedState
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.stateAwayTeam = sharedController.stateHomeTeam;
sharedController.homeTeamName = EMPTY_STRING;
sharedController.awayStateName = sharedController.homeStateName;
sharedController.awayAssocationName = EMPTY_STRING;
sharedController.awayAssociationId = EMPTY_STRING;
sharedController.awayClubName = EMPTY_STRING;
sharedController.awayClubId = EMPTY_STRING;
[self updateDataOnScreen];
self.selectHomeAssoc.enabled = YES;
self.selectHomeClub.enabled = NO;
[self.popSegue.popoverController dismissPopoverAnimated:YES];
}
-(void) searchHomeAssocDone:(NSString *)selectedHomeAssoc
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.awayAssocationName = sharedController.homeAssociationName;
sharedController.homeTeamName = EMPTY_STRING;
sharedController.awayStateName = sharedController.homeStateName;
sharedController.awayAssociationId = sharedController.homeAssociationId;
sharedController.awayClubName = EMPTY_STRING;
sharedController.awayClubId = EMPTY_STRING;
[self updateDataOnScreen];
self.selectHomeClub.enabled = YES;
[JLTValidator clearTextFieldValidation:self.homeAssociation];
[self.popSegue.popoverController dismissPopoverAnimated:YES];
}
-(void) searchHomeClubDone:(NSString *)selectedHomeClub
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.homeTeamName = EMPTY_STRING;
[self updateDataOnScreen];
[JLTValidator clearTextFieldValidation:self.homeClub];
[self.popSegue.popoverController dismissPopoverAnimated:YES];
}
-(void) searchAwayStateDone:(NSString *)selectedAwayState
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.homeTeamName = self.homeTeam.text;
[self updateDataOnScreen];
[JLTValidator clearTextFieldValidation:self.stateTextFieldAway];
[self.popSegue.popoverController dismissPopoverAnimated:YES];
}
-(void) searchAwayAssocDone:(NSString *)selectedAwayAssoc
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.homeTeamName = self.homeTeam.text;
[self updateDataOnScreen];
[JLTValidator clearTextFieldValidation:_awayAssociation];
[self.popSegue.popoverController dismissPopoverAnimated:YES];
}
-(void) searchAwayClubDone:(NSString *) selectedAwayClub;
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
sharedController.homeTeamName = self.homeTeam.text;
[self updateDataOnScreen];
[JLTValidator clearTextFieldValidation:_awayClub];
[self.popSegue.popoverController dismissPopoverAnimated:YES];
}
-(void) updateDataOnScreen
{
MatchDayDataController *sharedController = [MatchDayDataController sharedDataController];
// sharedController.awayTeamName = EMPTY_STRING;
self.stateTextFieldHome.text = sharedController.homeStateName;
self.homeAssociation.text =sharedController.homeAssociationName;
self.homeClub.text = sharedController.homeClubName;
self.homeTeam.text = sharedController.homeTeamName;
self.stateTextFieldAway.text = sharedController.awayStateName;
self.awayAssociation.text = sharedController.awayAssocationName;
self.awayClub.text = sharedController.awayClubName;
//self.awayTeam.text = sharedController.awayTeamName;
}
Any ideas ?
Thanks,
You can create static bool variable busy, and at first line of each button action method check out state of this variable. If busy equal to NO, then set her to YES and at last line of action method or somewhere else set her to NO. If busy equal to YES do return from action method. So, until first called method didn't finish no other methods will be running.
#implementation yourController
-(void)changeCountry
{
if (!busy)
{
busy = YES;
// do what you need
} else return;
}
-(void)changeState
{
if (!busy)
{
busy = YES;
// do what you need
} else return;
}
#end
You should implement singleton, which return a static instance with BOOL value for using him in difference viewControllers (1 mainC + 3 popOverC) and set busy to NO when you finish edition.
try self.view.exclusiveTouch = YES;
Related
I am stuck with a problem on the mapView. I am really sorry to ask this question but I have searched for almost one day to look into this issue but I don't find a solution to fix it.
#interface MapViewController ()<CLLocationManagerDelegate, MKMapViewDelegate, UITextFieldDelegate, CheckInDelegate, NotificationsViewControllerDelegate, ReportVCDelegate, TutorialViewControllerDelegate> {
CLLocationManager *locationManager;
NSTimer *refreshTimer;
int rangeValue;
CheckInViewController *checkInVC;
TutorialViewController *tutorialVC1;
TutorialViewController *tutorialVC2;
UIImageView *imgAvatar;
NSArray *markers;
}
#property (weak, nonatomic) IBOutlet UIView *viewSearch;
#property (weak, nonatomic) IBOutlet RateView *viewRate;
#property (weak, nonatomic) IBOutlet UIView *viewBottom;
#property (weak, nonatomic) IBOutlet UILabel *lblUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtSearch;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *btnNotifications;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomSpace;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomHeight;
#property (weak, nonatomic) IBOutlet UIButton *btnBottom;
#property (weak, nonatomic) IBOutlet HandsawayMapView *mapView;
#property (weak, nonatomic) IBOutlet UIView *mapViewContainer;
#property (strong, nonatomic) MKPlacemark *searchMarker;
#property (strong, nonatomic) MKUserLocation *myMarker;
#property (weak, nonatomic) MapToolbarViewController *mapToolbar;
#property (strong, atomic) NSArray *allMapMarkers;
#property (strong, nonatomic) NSNumber *aggressionIdToCenter;
#end
#implementation MapViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// [[UserModel sharedModel] setUserHome:#(1)];
rangeValue = 300;
self.viewSearch.layer.masksToBounds = NO;
self.viewSearch.layer.shadowRadius = 0.5f;
self.viewSearch.layer.shadowColor = [UIColor blackColor].CGColor;
self.viewSearch.layer.shadowOffset = CGSizeMake(0.0f, 0.5f);
self.viewSearch.layer.shadowOpacity = 0.5f;
self.viewRate.starCount = 4;
self.viewRate.step = 1.0f;
self.viewRate.starNormalColor = UIColorFromRGB(0xD8D8D8);
self.viewRate.starFillColor = UIColorFromRGB(0xFF5B59);
self.viewRate.rating = 3.0f;
self.viewRate.starSize = 20.0f;
self.viewRate.padding = 8.0f;
locationManager = [[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization];
locationManager.delegate = self;
[DbHelper saveActivationWithNumer:#(1)];
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
}];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSNumber *agressionID = [[NSUserDefaults standardUserDefaults] valueForKey:#"aggression_id"];
if (agressionID && agressionID != 0)
{
self.aggressionIdToCenter = agressionID;
[[NSUserDefaults standardUserDefaults] setValue:0 forKey:#"aggression_id"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
if (self.aggressionIdToCenter != nil) {
[self centerOnAggressionWithId:self.aggressionIdToCenter];
self.aggressionIdToCenter = nil;
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[locationManager stopUpdatingLocation];
didSetLocation = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIView*)locationPin {
User *user = [DbHelper getCurrentUser];
UIImage *pin = [UIImage imageNamed:#"marker-person"];
if([user.isCurrent boolValue]) {
pin = [UIImage imageNamed:#"my-pin"];
}
UIImageView *pinImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 39, 48)];
[pinImageView setImage:pin];
UIView *markerContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 39, 48)];
[markerContainer addSubview:pinImageView];
imgAvatar = [[UIImageView alloc] initWithFrame:CGRectMake(4.5, 4.5, 30, 30)];
[imgAvatar setContentMode:UIViewContentModeScaleAspectFill];
imgAvatar.layer.cornerRadius = 15;
imgAvatar.clipsToBounds = YES;
[markerContainer addSubview:imgAvatar];
if([user.isPictureHidden boolValue]) {
[imgAvatar setImage:[user avatarPlaceholder]];
}
else {
[imgAvatar setImageWithURL:[NSURL URLWithString:user.pictureURL] placeholderImage:[user avatarPlaceholder]];
}
[pinImageView setBackgroundColor:[UIColor clearColor]];
[imgAvatar setBackgroundColor:[UIColor clearColor]];
[markerContainer setBackgroundColor:[UIColor clearColor]];
return markerContainer;
}
- (void)ckeckUserImage
{
User *user = [DbHelper getCurrentUser];
if([user.isPictureHidden boolValue]) {
[imgAvatar setImage:[user avatarPlaceholder]];
}
else {
[imgAvatar setImageWithURL:[NSURL URLWithString:user.pictureURL] placeholderImage:[user avatarPlaceholder]];
}
if (self.mapToolbar.currentUser)
{
[self.mapToolbar setCurrentUser];
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if([segue.identifier isEqualToString:#"PresentInfo"]) {
self.mapToolbar = segue.destinationViewController;
self.mapToolbar.height = self.bottomHeight;
self.mapToolbar.masterVC = self;
} else if ([segue.identifier isEqualToString:#"NotificationsSegue"] && [segue.destinationViewController isKindOfClass:[NotificationsViewController class]]) {
NotificationsViewController *destination = (NotificationsViewController *)segue.destinationViewController;
destination.delegate = self;
}
else if([segue.identifier isEqualToString:#"ActionSheetMap"]) {
self.VCactionSheetMap = segue.destinationViewController;
self.VCactionSheetMap.delegate = self.mapToolbar;
} else if ([segue.identifier isEqualToString:#"mapToReport"]) {
self.reportVC = (ReportVC *)segue.destinationViewController;
self.reportVC.delegate = self;
}
}
- (IBAction)onMenu:(id)sender {
[self.frostedViewController presentMenuViewController];
}
-(IBAction)onLocate:(id)sender {
self.txtSearch.text = #"";
[self.mapView removeAnnotation:self.searchMarker];
self.searchMarker = nil;
didSetLocation = NO;
}
- (IBAction)onCheckIn:(id)sender {
if([[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials2"]) {
self.btnCheckin.hidden = YES;
checkInVC = [self.storyboard instantiateViewControllerWithIdentifier:#"NewCheckin"];
checkInVC.delegate = self;
checkInVC.model = [[CheckInModel alloc] init];
if(_searchMarker != nil) {
checkInVC.model.longitude = (double) _searchMarker.coordinate.longitude;
checkInVC.model.latitude = (double) _searchMarker.coordinate.latitude;
}
else {
checkInVC.model.longitude = (double) locationManager.location.coordinate.longitude;
checkInVC.model.latitude = (double) locationManager.location.coordinate.latitude;
}
if([sender isKindOfClass:[NSNumber class]]) {
checkInVC.agressionId = sender;
}
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:checkInVC.view];
}
else {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(![[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials2"]) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.btnCheckin setAdjustsImageWhenHighlighted:NO];
[self.btnCheckin setUserInteractionEnabled:NO];
UIStoryboard *tutorials = [UIStoryboard storyboardWithName:#"Tutorial" bundle:nil];
tutorialVC2 = (TutorialViewController *)[tutorials instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"Tutorial%ld", (long)2]];
tutorialVC2.delegate = self;
[[tutorialVC2 view] setFrame:self.view.bounds];
[self.view insertSubview:[tutorialVC2 view] belowSubview:self.btnCheckin];
[[NSUserDefaults standardUserDefaults] setValue:#YES forKey:#"tutorials2"];
}
});
}
}
- (IBAction)onNotifications:(id)sender {
if([[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials1"]) {
[self performSegueWithIdentifier:#"NotificationsSegue" sender:nil];
}
else {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(![[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials1"]) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
UIStoryboard *tutorials = [UIStoryboard storyboardWithName:#"Tutorial" bundle:nil];
tutorialVC1 = (TutorialViewController *)[tutorials instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"Tutorial%ld", (long)1]];
tutorialVC1.delegate = self;
[[tutorialVC1 view] setFrame:self.view.bounds];
[self.view addSubview:[tutorialVC1 view]];
[[NSUserDefaults standardUserDefaults] setValue:#YES forKey:#"tutorials1"];
}
});
});
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
[manager startUpdatingLocation];
}
BOOL didSetLocation;
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray<CLLocation *> *)locations {
if(locations.count > 0 ) {
CLLocation *aUserLocation = locations[0];
self.myMarker.coordinate = aUserLocation.coordinate;
// if(_myMarker == nil) {
// GMSMarker *marker = [[GMSMarker alloc] init];
// marker.iconView = [[DbHelper getCurrentUser] locationPin];
// marker.map = mapView_;
// _myMarker = marker;
// }
// _myMarker.position = aUserLocation.coordinate;
if(!didSetLocation) {
didSetLocation = YES;
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.01557113906538632;
span.longitudeDelta = 0.02284631241712987;
CLLocationCoordinate2D location;
location.latitude = aUserLocation.coordinate.latitude;
location.longitude = aUserLocation.coordinate.longitude;
region.span = span;
region.center = location;
[self.mapView setRegion:region animated:YES];
// [APICLIENT locateUserWithCoordinates:location
// completion:^(NSDictionary *result) {
//
// } error:^{
//
// }];
}
}
}
#pragma mark - Bottom bar
BOOL isBottomBarShown = YES;
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
// NSLog(#"longitured : %#, lattitude: %#", #(mapView.region.span.longitudeDelta), #(mapView.region.span.latitudeDelta));
[self hideBottomView];
[refreshTimer invalidate];
refreshTimer = [NSTimer scheduledTimerWithTimeInterval:0.8
target:self
selector:#selector(refreshMapMarkersWithCoordinates:)
userInfo:#{#"longitude" : #(mapView.region.center.longitude), #"latitude" : #(mapView.region.center.latitude), #"range" : #(rangeValue)}
repeats:NO];
}
- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if(![annotation isKindOfClass:[MKPlacemark class]]) {
MKAnnotationView * annotationView = [MKAnnotationView new];
if([annotation isKindOfClass:[MKUserLocation class]]) {
UIView *userView = [self locationPin];
[annotationView setFrame:userView.frame];
[annotationView addSubview:userView];
self.myMarker = annotation;
[self.mapView sendSubviewToBack:annotationView];
}
else {
annotationView.annotation = annotation;
Marker *dbmarker = ((MarkerAnnotation*)annotation).userData;
if(dbmarker.agression != nil) {
[annotationView setImage:[dbmarker markerImage]];
[self.mapView bringSubviewToFront:annotationView];
}
else if(dbmarker.user != nil) {
UIView *userView = [dbmarker userMarkerView];
[annotationView setFrame:userView.frame];
[annotationView addSubview:userView];
[self.mapView bringSubviewToFront:annotationView];
}
}
return annotationView;
}
return nil;
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
if(view.annotation != self.searchMarker && view.annotation != self.myMarker) {
if([view.annotation isKindOfClass:[MKUserLocation class]]) {
}
else {
[self selectMarker:((MarkerAnnotation*)view.annotation).userData];
}
}
else
{
if (view.annotation == self.myMarker)
{
[self.mapToolbar setCurrentUser];
}
[self showBottomView];
}
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
if(view.annotation != self.searchMarker && view.annotation != self.myMarker) {
if([view.annotation isKindOfClass:[MKUserLocation class]]) {
}
else {
[self hideBottomView];
}
}
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
[APICLIENT locateUserWithCoordinates:userLocation.location.coordinate
completion:^(NSDictionary *result) {
} error:^{
}];
}
#pragma mark - GMSMap delegate
//- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
// [self selectMarker:marker];
// return YES;
//}
- (void)selectMarker:(Marker *)marker {
Marker *dbMarker = marker;
if(dbMarker.agression != nil) {
[APICLIENT getAgressionWithId:dbMarker.agression.webID
completion:^(Marker *newmarker) {
[APICLIENT getUserById:[newmarker.user.webID stringValue]
completion:^(User *result) {
self.mapToolbar.marker = newmarker;
//[self showBottomView];
} error:^{
}];
} error:^{
}];
}
else {
[APICLIENT getUserById:[dbMarker.user.webID stringValue]
completion:^(User *result) {
self.mapToolbar.marker = dbMarker;
[self showBottomView];
} error:^{
}];
}
}
-(void)reloadMarkers {
[APICLIENT getMapMarkersAroundMeWithCoordinates:self.mapView.region.center
range:#(rangeValue)
completion:^(NSArray *result) {
[self updateDistance];
NSArray *oldAnnotations = [self.mapView.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF.class == %#", [MarkerAnnotation class]]];
oldAnnotations = [oldAnnotations valueForKey:#"userData"];
markers = [Marker MR_findAllWithPredicate:[NSPredicate predicateWithFormat:#"NOT (SELF IN %#)", oldAnnotations]];
//[self.mapView removeAnnotations:self.mapView.annotations];
NSMutableArray *allMapMarkersMutable = [[NSMutableArray alloc] init];
for(Marker *dbmarker in markers) {
MarkerAnnotation *marker = [[MarkerAnnotation alloc] init];
marker.coordinate = CLLocationCoordinate2DMake([dbmarker.latitude doubleValue], [dbmarker.longitude doubleValue]);
marker.userData = dbmarker;
[self.mapView addAnnotation:marker];
[allMapMarkersMutable addObject:marker];
}
self.allMapMarkers = [[allMapMarkersMutable copy] arrayByAddingObjectsFromArray:oldAnnotations];
if(_searchMarker != nil && ![self.mapView.annotations containsObject:_searchMarker]) {
[self.mapView addAnnotation:_searchMarker];
}
if(self.aggressionIdToCenter != nil) {
[self centerOnAggressionWithId:self.aggressionIdToCenter];
self.aggressionIdToCenter = nil;
}
} error:^{
}];
/*NSArray *oldAnnotations = [self.mapView.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF.class == %#", [MarkerAnnotation class]]];
oldAnnotations = [oldAnnotations valueForKey:#"userData"];
markers = [Marker MR_findAllWithPredicate:[NSPredicate predicateWithFormat:#"NOT (SELF IN %#)", oldAnnotations]];
// [self.mapView removeAnnotations:self.mapView.annotations];
NSMutableArray *allMapMarkersMutable = [[NSMutableArray alloc] init];
for(Marker *dbmarker in markers) {
MarkerAnnotation *marker = [[MarkerAnnotation alloc] init];
marker.coordinate = CLLocationCoordinate2DMake([dbmarker.latitude doubleValue], [dbmarker.longitude doubleValue]);
marker.userData = dbmarker;
[self.mapView addAnnotation:marker];
[allMapMarkersMutable addObject:marker];
}
self.allMapMarkers = [[allMapMarkersMutable copy] arrayByAddingObjectsFromArray:oldAnnotations];
if(_searchMarker != nil && ![self.mapView.annotations containsObject:_searchMarker]) {
[self.mapView addAnnotation:_searchMarker];
}
if(self.aggressionIdToCenter != nil) {
[self centerOnAggressionWithId:self.aggressionIdToCenter];
self.aggressionIdToCenter = nil;
}*/
}
//-(void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
// [self hideBottomView];
//}
#pragma mark - UITextFieldDelegate and place search
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.view endEditing:YES];
MKCoordinateRegion newRegion;
newRegion.center.latitude = locationManager.location.coordinate.latitude;
newRegion.center.longitude = locationManager.location.coordinate.longitude;
// Setup the area spanned by the map region:
// We use the delta values to indicate the desired zoom level of the map,
// (smaller delta values corresponding to a higher zoom level).
// The numbers used here correspond to a roughly 8 mi
// diameter area.
//
newRegion.span.latitudeDelta = 0.112872;
newRegion.span.longitudeDelta = 0.109863;
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = textField.text;
request.region = newRegion;
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error) {
if (error != nil) {
// NSString *errorStr = [[error userInfo] valueForKey:NSLocalizedDescriptionKey];
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Could not find places"
// message:errorStr
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil];
// [alert show];
} else {
NSArray<MKMapItem *> *mapItems = [response mapItems];
if(mapItems.count > 0) {
MKCoordinateRegion boundingRegion = response.boundingRegion;
MKMapItem *item = mapItems[0];
self.searchMarker = item.placemark;
[self.mapView addAnnotation:item.placemark];
[self.mapView setRegion:boundingRegion animated:YES];
}
}
};
[localSearch startWithCompletionHandler:completionHandler];
double radians(double degrees) {
return degrees * M_PI / 180.0;
}
double degrees(double radians) {
return radians * 180.0 / M_PI;
}
const CLLocationDegrees kLatLonEarthRadius = 6371.0;
CLLocationCoordinate2D LatLonDestPoint(CLLocationCoordinate2D origin, double bearing, CLLocationDistance distance) {
double brng = radians(bearing);
double lat1 = radians(origin.latitude);
double lon1 = radians(origin.longitude);
CLLocationDegrees lat2 = asin(sin(lat1) * cos(distance / kLatLonEarthRadius) +
cos(lat1) * sin(distance / kLatLonEarthRadius) * cos(brng));
CLLocationDegrees lon2 = lon1 + atan2(sin(brng) * sinf(distance / kLatLonEarthRadius) * cos(lat1),
cosf(distance / kLatLonEarthRadius) - sin(lat1) * sin(lat2));
lon2 = fmod(lon2 + M_PI, 2.0 * M_PI) - M_PI;
CLLocationCoordinate2D coordinate;
if (! (isnan(lat2) || isnan(lon2))) {
coordinate.latitude = degrees(lat2);
coordinate.longitude = degrees(lon2);
}
return coordinate;
}
#pragma mark - CheckInDelegate
- (void)willRemoveCheckinView {
[[UIApplication sharedApplication] setStatusBarHidden:NO
withAnimation:UIStatusBarAnimationSlide];
[self.navigationController setNavigationBarHidden:NO
animated:YES];
}
The problem is you are adding marker in MKLocalSearchCompletionHandler, so remove below line from MKLocalSearchCompletionHandler will solved your issue.
[self.mapView addAnnotation:item.placemark];
You can remove all annotation pins from MKMapView by using following code
for (int i =0; i < [_mapView.annotations count]; i++) {
if ([[_mapView.annotations objectAtIndex:i] isKindOfClass:[YOURANNOTATIONCLASS class]]) {
[_mapView removeAnnotation:[_mapView.annotations objectAtIndex:i]];
}
}
If you want to remove Annotation while search then remove bellow code in textFieldShouldReturn method.
Find method:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
}
Then Comment or Remove bellow code
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = textField.text;
request.region = newRegion;
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error) {
if (error != nil) {
// NSString *errorStr = [[error userInfo] valueForKey:NSLocalizedDescriptionKey];
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Could not find places"
// message:errorStr
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil];
// [alert show];
} else {
NSArray<MKMapItem *> *mapItems = [response mapItems];
if(mapItems.count > 0) {
MKCoordinateRegion boundingRegion = response.boundingRegion;
MKMapItem *item = mapItems[0];
self.searchMarker = item.placemark;
[self.mapView addAnnotation:item.placemark];
[self.mapView setRegion:boundingRegion animated:YES];
}
}
};
Hope it will help you
First off: My project is ARC enabled and I'm using storyboard.
I have a view controller that pushes a segue (modal),
[self performSegueWithIdentifier: #"goInitialSettings" sender: self];
there i'm setting some parameters and store them. When the parameters are stored (true a button tap), the app should return to the original viewcontroller.
This i am doing with this command:
[self.presentingViewController dismissViewControllerAnimated:NO completion:^{}];
I'm noticing that the viewcontroller that i dismiss, never deallocs. How does this come?
I'm adding the code of the 'presented viewcontroller' below:
#interface CenterChoiceController ()
{
UIView* _titleBackground;
UILabel* _lblTitle;
UIButton* _btnGaVerder;
UIPickerView* _myPickerView;
NSArray* _centers;
UILabel* _adresLine;
UILabel* _cityLine;
MKPointAnnotation* _point;
MKMapView* _mapView;
UIActivityIndicatorView* _indicator;
UIAlertView* _alert;
GCenter* _center;
DataManager* _dm;
}
#end
#implementation CenterChoiceController
-(void)dealloc
{
NSLog(#"Centerchoice deallocs");
_titleBackground = nil;
_lblTitle = nil;
_btnGaVerder = nil;
_myPickerView = nil;
_point = nil;
_mapView = nil;
_indicator = nil;
_alert = nil;
_centers = nil;
_adresLine = nil;
_cityLine = nil;
_center = nil;
_dm = nil;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_dm = [[DataManager alloc]init];
if([_dm hasConnectivity])
{
[_dm fetchCentersForController:self];
}
else
{
[self pushErrorMessage:NSLocalizedString(#"nointernetconnection", nil)];
}
CAGradientLayer *bgLayer = [BackgroundLayer blueGradient];
bgLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:bgLayer atIndex:0];
_titleBackground = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
_titleBackground.backgroundColor = [GColor blueColor];
[self.view addSubview:_titleBackground];
_lblTitle = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width - 10, 44)];
_lblTitle.textAlignment = NSTextAlignmentRight;
_lblTitle.textColor = [GColor whiteColor];
_lblTitle.text = NSLocalizedString(#"bioscoopkeuze", nil);
[self.view addSubview:_lblTitle];
_btnGaVerder = [[UIButton alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height - 54, self.view.frame.size.width, 54)];
[_btnGaVerder setTitle:NSLocalizedString(#"gaverder", nil) forState:UIControlStateNormal];
_btnGaVerder.titleLabel.font = [_btnGaVerder.titleLabel.font fontWithSize:12];
_btnGaVerder.backgroundColor = [GColor blueColor];
[_btnGaVerder setTitleColor:[GColor whiteColor] forState:UIControlStateNormal];
[_btnGaVerder setShowsTouchWhenHighlighted:YES];
[_btnGaVerder addTarget:self action:#selector(gaVerder) forControlEvents:UIControlEventTouchUpInside];
_myPickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, 200)];
}
-(void)showLoading
{
NSLog(#"shows loading");
_indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGPoint cntr = self.view.center;
_indicator.center = cntr;
[_indicator startAnimating];
[self.view addSubview:_indicator];
}
-(void)hideLoading
{
NSLog(#"hides loading");
[_indicator removeFromSuperview];
_indicator = nil;
}
-(void)pushData:(NSArray *)data
{
[self.view addSubview:_btnGaVerder];
[self.view addSubview:_myPickerView];
_centers = data;
_myPickerView.delegate = self;
_myPickerView.dataSource = self;
_dm = [[DataManager alloc]init];
GSettings* settings = [_dm loadSettings];
if(settings == nil)
{
settings = [[GSettings alloc]init];
settings.chosenCenter = [_centers objectAtIndex:0];
settings.loadedCenter = [_centers objectAtIndex:0];
_center = settings.chosenCenter;
settings.notificationsEnabled = YES;
[self changeAddressLines];
}
/*if(settings != nil)
{
GCenter* loaded = settings.loadedCenter;
int i = 0;
BOOL found = NO;
while(i < [_centers count] && !found)
{
GCenter* center = (GCenter*)[_centers objectAtIndex:i];
if(settings.loadedCenter.iD == center.iD)
{
_center = center;
settings.chosenCenter = center;
[_dm storeSettings:settings];
found = YES;
}
i++;
}
//[self.myPickerView selectRow:i-1 inComponent:0 animated:NO];
loaded = nil;
[self changeAddressLines];
}
*/
}
-(void) pushErrorMessage: (NSString*) errorMessage
{
_alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"fout", nil) message:errorMessage delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
_alert.delegate = self;
[_alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 0)
{
if(self.navigationController != nil)
{
[self.navigationController popViewControllerAnimated:YES];
}
else
{
//[self initializeData];
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillDisappear:(BOOL)animated
{
[_dm cancelCenterRequest];
/*if(self.tabBarController != nil)
{
dm = [[DataManager alloc]init];
settings = [dm loadSettings];
if([dm hasConnectivity])
{
settings.lastUpdated = nil;
[dm storeSettings:settings];
}
if(settings.loadedCenter.centerCode != settings.chosenCenter.centerCode)
{
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SplashScreenController *controller = [mystoryboard instantiateViewControllerWithIdentifier:#"root"];
[self presentViewController:controller animated:YES completion:nil];
}
dm = nil;
settings = nil;
}
*/
}
-(void)gaVerder
{
_dm = [[DataManager alloc]init];
GSettings* settings = [_dm loadSettings];
if(settings == nil)
{
settings = [[GSettings alloc]init];
settings.notificationsEnabled = YES;
}
if(_center != nil)
{
settings.chosenCenter = _center;
}
[_dm storeSettings:settings];
[_mapView removeFromSuperview];
_mapView = nil;
_titleBackground = nil;
_lblTitle = nil;
_btnGaVerder = nil;
_myPickerView = nil;
_point = nil;
_indicator = nil;
_alert = nil;
_centers = nil;
_adresLine = nil;
_cityLine = nil;
_center = nil;
_dm = nil;
[self.presentingViewController dismissViewControllerAnimated:NO completion:^{}];
//DEZE BLIJFT HELAAS IN HET GEHEUGEN HANGEN... GEEN OPLOSSING GEVONDEN
//[self.navigationController popViewControllerAnimated:NO];
}
//PICKERVIEWDELEGATE EN DATASOURCE
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [_centers count];
}
- (UILabel *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
GCenter* center = (GCenter*)[_centers objectAtIndex:row];
NSString* string = center.name;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, pickerView.frame.size.width, 44)];
label.textColor = [GColor blueColor];
label.font = [label.font fontWithSize:18];
label.text = string;
label.textAlignment = NSTextAlignmentCenter;
return label;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
_center = (GCenter*)[_centers objectAtIndex:row];
[self changeAddressLines];
}
-(void)changeAddressLines
{
if (_mapView != nil)
{
[_mapView removeAnnotation:_point];
}
[_adresLine removeFromSuperview];
[_cityLine removeFromSuperview];
_adresLine = nil;
_cityLine = nil;
CGRect rctAdres = CGRectMake(0, _myPickerView.frame.origin.y + _myPickerView.frame.size.height -10, self.view.frame.size.width, 20);
_adresLine = [[UILabel alloc]initWithFrame:rctAdres];
_adresLine.textAlignment = NSTextAlignmentCenter;
_adresLine.textColor = [GColor greyColor];
_adresLine.text = _center.street;
CGRect rctCity = CGRectMake(0, rctAdres.origin.y + rctAdres.size.height, self.view.frame.size.width, 20);
_cityLine = [[UILabel alloc]initWithFrame:rctCity];
_cityLine.textAlignment = NSTextAlignmentCenter;
_cityLine.textColor = [GColor greyColor];
_cityLine.font = [_cityLine.font fontWithSize:14];
_cityLine.text = _center.city;
[self.view addSubview:_adresLine];
[self.view addSubview:_cityLine];
if(_mapView == nil)
{
double height;
height = _btnGaVerder.frame.origin.y - _cityLine.frame.origin.y - _cityLine.frame.size.height;
CGRect mapRect = CGRectMake(0, _cityLine.frame.origin.y+3 + _cityLine.frame.size.height, self.view.frame.size.width, height);
_mapView = [[MKMapView alloc]initWithFrame:mapRect];
[self.view addSubview:_mapView];
}
CLLocationCoordinate2D punt;
punt.latitude = _center.latitude;
punt.longitude = _center.longitude;
_point = [[MKPointAnnotation alloc] init];
[_point setCoordinate:punt];
_mapView.centerCoordinate = punt;
_point.title = _center.name;
[_mapView addAnnotation:_point];
[_mapView setCenterCoordinate:punt animated:YES];
MKCoordinateRegion theRegion = _mapView.region;
theRegion.span.longitudeDelta = 0.005;
theRegion.span.latitudeDelta = 0.005;
[_mapView setRegion:theRegion animated:YES];
}
#end
In my case it was a little more complicated. I don't have any variable that has strong reference to my view controller, and my view controller is not a strong delegate to any property/variable contained inside this class itself. After some hard thinking and trials, I found my issue was caused by a NSTimer object defined in the interface. The timer object itself is non-repeatable, but the method invoked by it will schedule the timer again at the end, which as you can imagine would reference this method defined in my view controller again, thus causing circular references. To break out of this loop, I had to invalidate the timer before I dismiss my view controller.
As a summary, these are cases when a view controller can be blocked from deallocating after it is dismissed:
The view controller is being strongly referenced by some outside object;
The view controller is a strong delegate referenced by some object defined within the view controller itself
The dismissViewControllerAnimated:completion: block may reference to self or it has some other code block that may cause a circular references
The view controller has NSTimer objects which can invoke some methods which re-schedules the timer
There could be more, but hopefully we can capture a lot of cases with the above cases.
If your view controller is not deallocated after it is dismissed, there's probably a strong reference to that view controller somewhere in your code. ARC will always deallocate objects that doesn't have strong reference anymore.
Help, my app is showing thread 1 error exc_bad_access(code=1, address=0x2000001) on the last curly brace of my PlayViewController.
Note: this happen when I click the continue button on my GuessViewController. The continue button calls the the PlayViewController.
What i already did:
enabled ZOMBIE
close db
my GuessViewController:
#import "GuessViewController.h"
#import "PlayViewController.h"
#import "ViewController.h"
#interface GuessViewController ()
#end
#implementation GuessViewController
#synthesize userInput = _userInput;
#synthesize gword;
#synthesize gletter;
int score = 0;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_userInput.delegate = self;
self.scoreLabel.text = [NSString stringWithFormat:#"%d", score];
// Do any additional setup after loading the view.
}
-(void)touchesBegan:(NSSet*)touches withEvent: (UIEvent *) event{
[_userInput resignFirstResponder];
}
-(BOOL)textFieldShouldReturn: (UITextField*)textField {
if(textField){
[textField resignFirstResponder];
}
return NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)checkAnswer:(id)sender {
NSLog(#"%#", gword);
NSLog(#"%#", gletter);
NSString *temp = self.userInput.text;
unichar temp2 = [temp characterAtIndex: 0];
NSString *userletter= [NSString stringWithFormat:#"%C", temp2];
NSString *message1 = #"The word is ";
NSString *message2= [NSString stringWithFormat:#"%#", gword];
NSString *fm = [message1 stringByAppendingString:message2];
if([userletter isEqualToString:gletter]){
UIAlertView *checkAlert = [[UIAlertView alloc] initWithTitle:#"Got it Right" message:fm delegate:self cancelButtonTitle:#"Continue" otherButtonTitles:#"Back to Main Menu", nil];
score++;
self.scoreLabel.text = [NSString stringWithFormat:#"%d", score];
[checkAlert show];
}else{
UIAlertView *checkAlert = [[UIAlertView alloc] initWithTitle:#"Wrong" message:fm delegate:self cancelButtonTitle:#"Continue" otherButtonTitles:#"Back to Main Menu", nil];
[checkAlert show];
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex ==0){
PlayViewController *playViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Play"];
[self presentViewController:playViewController animated:YES completion: Nil];
} else {
ViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Main"];
[self presentViewController:viewController animated:YES completion: Nil];
}
}
#end
My PlayViewController:
#import "PlayViewController.h"
#import "GuessViewController.h"
#import <sqlite3.h>
#import "Word.h"
#interface PlayViewController ()
#end
#implementation PlayViewController
#synthesize thewords;
NSString *word;
NSTimer *myTimer;
int randomIndex;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[self wordList];
[super viewDidLoad];
// Do any additional setup after loading the view.
self.listChar.text = #" ";
int r = (arc4random()%[self.thewords count]);
word = [self.thewords objectAtIndex:r];
NSLog(#"%#", word);
randomIndex = (arc4random()%word.length);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)startGame:(id)sender {
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(listLetter:) userInfo:nil repeats:YES];
}
- (void)listLetter:(NSTimer *)timer
{
static int i = 0;
unichar letter;
if(randomIndex == i){
letter = ' ';
} else {
letter = [word characterAtIndex: i];
}
self.listChar.text = [NSString stringWithFormat:#"%C", letter];
if (++i == word.length) {
[timer invalidate];
i = 0;
GuessViewController *guessViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Guess"];
//passing some data
guessViewController.word = word;
guessViewController.letter = [NSString stringWithFormat:#"%C", [word characterAtIndex: randomIndex]];
[self presentViewController:guessViewController animated:YES completion: Nil];
}
}
-(NSMutableArray *) wordList {
thewords = [[NSMutableArray alloc] initWithCapacity:26];
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"LetterHunter.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success){
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)){
NSLog(#"An error has occured");
}
const char *sql = "SELECT * FROM WordList";
sqlite3_stmt*sqlStatement;
if(sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL)!=SQLITE_OK){
NSLog(#"Problem with prepare statement1");
} else {
while(sqlite3_step(sqlStatement) == SQLITE_ROW){
Word *word = [[Word alloc]init];
word.wordfromdb = [NSString stringWithUTF8String:(char*)sqlite3_column_text(sqlStatement, 1)];
[thewords addObject: word.wordfromdb];
}
}
sqlite3_finalize(sqlStatement);
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement2");
}
#finally {
sqlite3_close(db);
}
}
#end
As suggested below, I tried doing this instead but still there's the error
while(sqlite3_step(sqlStatement) == SQLITE_ROW){
NSString *temp = #"";
temp = [NSString stringWithUTF8String:(char*)sqlite3_column_text(sqlStatement, 1)];
[thewords addObject: temp;
}
From debug stack, it's a problem about autorelease. And I think the problem maybe in
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)){
I can't find db define. So I think it should be a instance property.
Try this:
DbClass *tempDb = nil;
if(!(sqlite3_open([dbPath UTF8String], &tempDb) == SQLITE_OK)){
self.db = tempDb;
What is wordfromdb? If it is string variable or any other datatype then add directly that into an array...
I think there is not need to create word object here as anyway your are not storing word object in array.
It looks to me an issue with word object. You are crating word object but adding its property only and not entire object.
I have the following code using quickblox.
Unfortunately, when I accessthe view controller, I get an "unAuthorized" error from quickblox API.
What am I doing wrong?
#import "QChatViewController.h"
#include "ChatMessageTableViewCell.h"
#interface QChatViewController ()
#end
#implementation QChatViewController
#synthesize opponent;
#synthesize currentRoom;
#synthesize messages;
#synthesize toolBar;
#synthesize sendMessageField;
#synthesize sendMessageButton;
#synthesize tableView;
#pragma mark -
#pragma mark View controller's lifecycle
- (id) initWithStartup: (NSDictionary *) _startup investor: (NSDictionary *) _investor chat_id: (NSInteger) _chat_id chat_name: (NSString *) _name
{
self = [self initWithNibName: #"QChatViewController" bundle: nil];
if(self)
{
startup = _startup;
investor = _investor;
startup_id = 0;
investor_id = 0;
if ([startup objectForKey: #"id"] &&
[startup objectForKey: #"id"] != (id)[NSNull null])
{
startup_id = [[startup objectForKey: #"id"] intValue];
}
if ([investor objectForKey: #"id"] &&
[investor objectForKey: #"id"] != (id)[NSNull null])
{
investor_id = [[investor objectForKey: #"id"] intValue];
}
past = 0;
chat_id = _chat_id;
self.title = _name;
self.title = #"Chat";
UIButton * button4 = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage * btnImage = [UIImage imageNamed: #"chatrightbtn.png"];
[button4 setFrame:CGRectMake(-90.0f, 0.0f, btnImage.size.width, btnImage.size.height)];
[button4 addTarget:self action:#selector(showSheet:) forControlEvents:UIControlEventTouchUpInside];
[button4 setImage: btnImage forState:UIControlStateNormal];
UIBarButtonItem *random1 = [[UIBarButtonItem alloc] initWithCustomView:button4];
self.navigationItem.rightBarButtonItem = random1;
self.navigationItem.leftBarButtonItem.title = #"";
}
return self;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
QBASessionCreationRequest *extendedAuthRequest = [QBASessionCreationRequest request];
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"jerry";
[QBAuth createSessionWithExtendedRequest:extendedAuthRequest delegate:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBarHidden = NO;
if(chat_id >= 1) {
NSString * roomName = [NSString stringWithFormat: #"%d", chat_id];
[[QBChat instance] createOrJoinRoomWithName: roomName membersOnly:YES persistent:NO];
}
messages = [[NSMutableArray alloc] init];
}
-(void) chatDidLogin{
// You have successfully signed in to QuickBlox Chat
}
- (void)completedWithResult:(Result *)result{
// Create session result
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// You have successfully created the session
QBAAuthSessionCreationResult *res = (QBAAuthSessionCreationResult *)result;
// Sign In to QuickBlox Chat
QBUUser *currentUser = [QBUUser user];
currentUser.ID = res.session.userID; // your current user's ID
currentUser.password = #"jerry"; // your current user's password
// set Chat delegate
[QBChat instance].delegate = self;
// login to Chat
[[QBChat instance] loginWithUser:currentUser];
}
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// leave room
if(self.currentRoom){
if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
// back button was pressed.
[[QBChat instance] leaveRoom:self.currentRoom];
[[DataManager shared].rooms removeObject:self.currentRoom];
}
}
}
- (void)viewDidUnload{
[self setToolBar:nil];
[self setSendMessageField:nil];
[self setSendMessageButton:nil];
[self setTableView:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
}
- (IBAction)sendMessage:(id)sender {
if(self.sendMessageField.text.length == 0){
return;
}
if(chat_id == 0)
{
NSString * sid = [NSString stringWithFormat: #"%d", startup_id];
NSString * iid = [NSString stringWithFormat: #"%d", investor_id];
NSString * pasts = [NSString stringWithFormat: #"%d", past];
NSString * chat_ids = [NSString stringWithFormat: #"%d", chat_id];
NSString * path_str = [NSString stringWithFormat: #"chats/?format=json"];
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:
sid, #"startup",
iid, #"investor",
pasts, #"past",
chat_ids, #"conversation_id",
#"avv7ejtaegxxk2wzgnymsj8xtm2tk9s4xgp6854r6dqn8bk6jjwux4g9dh9b", #"apikey",
nil];
[[API sharedInstance] postcommandWithParams:params
path: path_str
onCompletion:^(NSDictionary *json)
{
if(chat_id == 0)
{
if ([json objectForKey: #"id"] &&
[json objectForKey: #"id"] != (id)[NSNull null])
{
chat_id = [[json objectForKey: #"id"] intValue];
if(chat_id >= 1) {
NSString * roomName = [NSString stringWithFormat: #"%d", chat_id];
[[QBChat instance] createOrJoinRoomWithName: roomName membersOnly:YES persistent:NO];
}
[[QBChat instance] sendMessage:self.sendMessageField.text toRoom:self.currentRoom];
// reload table
[self.tableView reloadData];
// hide keyboard & clean text field
[self.sendMessageField resignFirstResponder];
[self.sendMessageField setText:nil];
}
}
}];
}
else
{
[[QBChat instance] sendMessage:self.sendMessageField.text toRoom:self.currentRoom];
// reload table
[self.tableView reloadData];
// hide keyboard & clean text field
[self.sendMessageField resignFirstResponder];
[self.sendMessageField setText:nil];
}
}
-(void)keyboardShow{
CGRect rectFild = self.sendMessageField.frame;
rectFild.origin.y -= 215;
CGRect rectButton = self.sendMessageButton.frame;
rectButton.origin.y -= 215;
[UIView animateWithDuration:0.25f
animations:^{
[self.sendMessageField setFrame:rectFild];
[self.sendMessageButton setFrame:rectButton];
}
];
}
-(void)keyboardHide{
CGRect rectFild = self.sendMessageField.frame;
rectFild.origin.y += 215;
CGRect rectButton = self.sendMessageButton.frame;
rectButton.origin.y += 215;
[UIView animateWithDuration:0.25f
animations:^{
[self.sendMessageField setFrame:rectFild];
[self.sendMessageButton setFrame:rectButton];
}
];
}
#pragma mark -
#pragma mark TextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[self keyboardShow];
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
[self keyboardHide];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField setText:nil];
[textField resignFirstResponder];
return YES;
}
#pragma mark -
#pragma mark TableViewDataSource & TableViewDelegate
static CGFloat padding = 20.0;
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MessageCellIdentifier";
// Create cell
ChatMessageTableViewCell *cell = (ChatMessageTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ChatMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.userInteractionEnabled = NO;
// Message
QBChatMessage *messageBody = [messages objectAtIndex:[indexPath row]];
// set message's text
NSString *message = [messageBody text];
cell.message.text = message;
// message's datetime
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat: #"yyyy-mm-dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"..."]];
NSString *time = [formatter stringFromDate:messageBody.datetime];
CGSize textSize = { 260.0, 10000.0 };
CGSize size = [message sizeWithFont:[UIFont boldSystemFontOfSize:13]
constrainedToSize:textSize
lineBreakMode:UILineBreakModeWordWrap];
size.width += (padding/2);
// Left/Right bubble
UIImage *bgImage = nil;
if ([[[DataManager shared] currentUser] ID] == messageBody.senderID || self.currentRoom) {
bgImage = [[UIImage imageNamed:#"orange.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
[cell.message setFrame:CGRectMake(padding, padding*2, size.width+padding, size.height+padding)];
[cell.backgroundImageView setFrame:CGRectMake( cell.message.frame.origin.x - padding/2,
cell.message.frame.origin.y - padding/2,
size.width+padding,
size.height+padding)];
cell.date.textAlignment = UITextAlignmentLeft;
cell.backgroundImageView.image = bgImage;
if(self.currentRoom){
cell.date.text = [NSString stringWithFormat:#"%d %#", messageBody.senderID, time];
}else{
cell.date.text = [NSString stringWithFormat:#"%# %#", [[[DataManager shared] currentUser] login], time];
}
} else {
bgImage = [[UIImage imageNamed:#"aqua.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
[cell.message setFrame:CGRectMake(320 - size.width - padding,
padding*2,
size.width+padding,
size.height+padding)];
[cell.backgroundImageView setFrame:CGRectMake(cell.message.frame.origin.x - padding/2,
cell.message.frame.origin.y - padding/2,
size.width+padding,
size.height+padding)];
cell.date.textAlignment = UITextAlignmentRight;
cell.backgroundImageView.image = bgImage;
cell.date.text = [NSString stringWithFormat:#"%# %#", self.opponent.login, time];
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messages count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
QBChatMessage *chatMessage = (QBChatMessage *)[messages objectAtIndex:indexPath.row];
NSString *text = chatMessage.text;
CGSize textSize = { 260.0, 10000.0 };
CGSize size = [text sizeWithFont:[UIFont boldSystemFontOfSize:13]
constrainedToSize:textSize
lineBreakMode:UILineBreakModeWordWrap];
size.height += padding;
return size.height+padding+5;
}
#pragma mark -
#pragma mark QBChatDelegate
// Did receive 1-1 message
- (void)chatDidReceiveMessage:(QBChatMessage *)message{
[self.messages addObject:message];
// save message to cache if this 1-1 chat
if (self.opponent) {
[[DataManager shared] saveMessage:[NSKeyedArchiver archivedDataWithRootObject:messages]
toHistoryWithOpponentID:self.opponent.ID];
}
// reload table
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
// Did receive message in room
- (void)chatRoomDidReceiveMessage:(QBChatMessage *)message fromRoom:(NSString *)roomName{
// save message
[self.messages addObject:message];
// reload table
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
// Fired when you did leave room
- (void)chatRoomDidLeave:(NSString *)roomName{
NSLog(#"Chat Controller chatRoomDidLeave");
}
// Called in case changing occupant
- (void)chatRoomDidChangeOnlineUsers:(NSArray *)onlineUsers room:(NSString *)roomName{
NSLog(#"chatRoomDidChangeOnlineUsers %#, %#",roomName, onlineUsers);
}
- (void)chatRoomDidEnter:(QBChatRoom *)room{
NSLog(#"Private room %# was created", room.name);
// You have to retain created room if this is temporary room. In other cases room will be destroyed and all occupants will be disconnected from room
self.currentRoom = room;
// Add users to this room
NSInteger user_id = [[[[API sharedInstance] user] objectForKey: #"id"] intValue];
NSNumber *me = [NSNumber numberWithInt: user_id];
NSArray *users = [NSArray arrayWithObjects: me, nil];
[[QBChat instance] addUsers:users toRoom:room];
}
#end
I'm not sure that you have user with these credentials
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"jerry";
I first check user exist or not modified your code like this...
//your code
.....
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
//Create extended session request with user authorization
QBASessionCreationRequest *extendedAuthRequest = [QBASessionCreationRequest request];
//Check user exist or not
if(self.currentQBUser){
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"testjk";
}
[QBAuth createSessionWithExtendedRequest:extendedAuthRequest delegate:self];
}
........
- (void)completedWithResult:(Result *)result{
// Create session result
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// Register new user
self.currentQBUser = [[QBUUser alloc] init];
user.fullName = #"Your Name";
user.login = #"testjk";
user.password = #"testjk";
user.tags = [NSMutableArray arrayWithObject:#"Chat"];
// Create user
[QBUsers signUp:user delegate:self];
// You have successfully created the session
QBAAuthSessionCreationResult *res = (QBAAuthSessionCreationResult *)result;
} else if([result isKindOfClass:[QBUUserLogInResult class]]){
if(result.success){
QBUUserLogInResult *res = (QBUUserLogInResult *)result;
//Now login to chat
// Sign In to QuickBlox Chat
QBUUser *currentUser = res.user;
currentUser.ID = #"testjk; // your current user's ID
currentUser.password = #"testjk"; // same as user id
// set Chat delegate
[QBChat instance].delegate = self;
// login to Chat
[[QBChat instance] loginWithUser:currentUser];
}
}
if (result.errors.count && (401 != result.status))
{
NSLog(#"QBErrors: %#",result.errors);
}
}
I met the same problem here. And i gave the way i made it.
error unauthorized is the user.login or user.password.
user.login can not be email address but your login username. these i do not know why.
user.password is the email address/username password.
check these informations in your User list at QuickBlox Dashboard
Hope these instructions will help.
use quickblox.min.js
var QBApp = {
appId: 123,
authKey: 'dfdgfd44444',
authSecret: 'dffdgfdg455445'
};
$(document).ready(function () {
QB.init(QBApp.appId, QBApp.authKey, QBApp.authSecret);
QB.createSession(function (err, result) {
console.log('Session create callback', err, result);
});
})
function addUser() {
var pwd, ctr, data;
ctr = document.getElementById(myForm.password);
pwd = ctr.value;
var params = { 'login': 'Rajesh', 'password': 'Pass#123' };
alert(params)
QB.users.create(params, function (err, user) {
debugger;
if (user) {
alert('Done')
//$('#output_place').val(JSON.stringify(user));
} else {
alert('Error')
//$('#output_place').val(JSON.stringify(err));
}
})}
When my view is trying to load, the applications crashes and i get this stack:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
This is my code, i don't really know where to look when this crash is occurred:
#import "Itineraire.h"
#import "SBMapView.h"
#import "SBRouteAnnotation.h"
#import "City.h"
#import "UICGRoutes.h"
#import "SBCheckPointViewController.h"
//#import "SBRouteDetailView.h"
#interface Itineraire(Private)
-(void)customInitialization;
#end
#implementation Itineraire(Private)
-(void)customInitialization
{
// do the initialization of class variables here..
mDirections = [UICGDirections sharedDirections];
mDirections.delegate = self;
}
#end
#implementation Itineraire
#synthesize map = mMap;
#synthesize startPoint = mStartPoint;
#synthesize endPoint = mEndPoint;
#synthesize loadBtn = mLoadBtn;
#synthesize annotationArray = mAnnotationArray;
#synthesize travelMode = mTravelMode;
#synthesize destination;
#synthesize routes;
#synthesize mAnnotations;
#synthesize mRouteArray;
#synthesize mRouteDetail;
//Invoked when the class is instantiated in XIB
-(id)initWithCoder:(NSCoder*)aDecoder
{
self = [super initWithCoder:aDecoder];
if( self)
{
[self customInitialization];
}
return self;
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
[self customInitialization];
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Google Maps";
self.map = [[SBMapView alloc] initWithFrame:CGRectMake(0, 49, self.view.frame.size.width, self.view.frame.size.height)];
//self.map = [[SBMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 381)];
[self.view addSubview:mMap];
self.view.backgroundColor = [UIColor blackColor];
self.annotationArray = [[NSMutableArray alloc]init];
self.routes = [[UICGRoutes alloc]init];
if (mDirections.isInitialized) {
[self updateRoute];
}
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
}
- (void)viewWillDisappear:(BOOL)animated;
{
[super viewWillDisappear:YES];
}
#pragma mark -
#pragma mark Instance Methods
- (void)updateRoute
{ /*
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
UICGDirectionsOptions *options = [[[UICGDirectionsOptions alloc] init] autorelease];
options.travelMode = mTravelMode;
City *mFirstCity = [[[City alloc]init] autorelease];
mFirstCity.mCityName = #"Paris";//mStartPoint;
//[mDirections loadWithStartPoint:mFirstCity.mCityName endPoint:destination options:options];
//added
NSMutableArray * DestinationCityArray = [[NSMutableArray alloc]init];
[DestinationCityArray addObject:#"Berlin"];
[mDirections loadWithStartPoint:mFirstCity.mCityName endPoint:destination options:options];
*/
//
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
UICGDirectionsOptions *options = [[UICGDirectionsOptions alloc] init] ;
options.travelMode = mTravelMode;
City *mFirstCity = [[City alloc]init];
mFirstCity.mCityName = #"Amsterdam";//mStartPoint;
NSMutableArray *dest=[[NSMutableArray alloc]init];
[dest addObject:#"Berlin"];
[mDirections loadWithStartPoint:mFirstCity.mCityName endPoint:dest options:options];
}
-(void)loadRouteAnnotations
{
self.mRouteArray = [mDirections routeArray];
NSLog(#"mRouteArray %#",mRouteArray);
self.mAnnotations = [[NSMutableArray alloc]init];
for (int idx = 0; idx < [mRouteArray count]; idx++) {
NSArray *_routeWayPoints1 = [[mRouteArray objectAtIndex:idx] wayPoints];
NSArray *mPlacetitles = [[mRouteArray objectAtIndex:idx] mPlaceTitle];
self.annotationArray = [NSMutableArray arrayWithCapacity:[_routeWayPoints1 count]-2];
mLoadBtn.title = #"OFF";
mLoadBtn.target = self;
mLoadBtn.action = #selector(removeRouteAnnotations);
for(int idx = 0; idx < [_routeWayPoints1 count]-1; idx++)
{
mBetweenAnnotation = [[SBRouteAnnotation alloc] initWithCoordinate:[[_routeWayPoints1 objectAtIndex:idx]coordinate]
title:[mPlacetitles objectAtIndex:idx]
annotationType:SBRouteAnnotationTypeWayPoint];
[self.annotationArray addObject:mBetweenAnnotation];
}
[mAnnotations addObject:mAnnotationArray];
[self.map.mapView addAnnotations:[mAnnotations objectAtIndex:idx]];
NSLog(#"map %#",mMap);
}
}
-(void)showCheckpoints
{
SBCheckPointViewController *_Controller = [[SBCheckPointViewController alloc]initWithNibName:#"SBCheckPoints" bundle:nil];
[self.navigationController pushViewController:_Controller animated:YES];
NSMutableArray *arr = [[mDirections checkPoint] mPlaceTitle];
_Controller.mCheckPoints = arr ;
}
//
-(void)removeRouteAnnotations
{
NSMutableArray *mTempAnnotation;// = [mAnnotations retain];
for (int idx = 0; idx < [mTempAnnotation count]; idx++) {
[mMap.mapView removeAnnotations:[mTempAnnotation objectAtIndex:idx] ];
}
mLoadBtn.title = #"ON";
mLoadBtn.target = self;
mLoadBtn.action = #selector(loadRouteAnnotations);
}
#pragma mark <UICGDirectionsDelegate> Methods
- (void)directionsDidFinishInitialize:(UICGDirections *)directions {
[self updateRoute];
}
- (void)directions:(UICGDirections *)directions didFailInitializeWithError:(NSError *)error {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Map Directions" message:[error localizedFailureReason] delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertView show];
}
- (void)directionsDidUpdateDirections:(UICGDirections *)indirections {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
UICGPolyline *polyline = [indirections polyline];
NSArray *routePoints = [polyline routePoints];
[mMap loadRoutes:routePoints]; // Loads route by getting the array of all coordinates in the route.
UIToolbar *tools = [[UIToolbar alloc]
initWithFrame:CGRectMake(0.0f, 0.0f, 103.0f, 44.01f)]; // 44.01 shifts it up 1px for some reason
tools.clearsContextBeforeDrawing = NO;
tools.clipsToBounds = NO;
tools.tintColor = [UIColor colorWithWhite:0.305f alpha:0.0f]; // closest I could get by eye to black, translucent style.
// anyone know how to get it perfect?
tools.barStyle = -1; // clear background
NSMutableArray *buttons = [[NSMutableArray alloc] initWithCapacity:2];
// Create a standard Load button.
self.loadBtn = [[UIBarButtonItem alloc]initWithTitle:#"ON"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(loadRouteAnnotations)];
[buttons addObject:mLoadBtn];
// Add Go button.
UIBarButtonItem *mGoBtn = [[UIBarButtonItem alloc] initWithTitle:#"Go"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(showCheckpoints)];
[buttons addObject:mGoBtn];
// Add buttons to toolbar and toolbar to nav bar.
[tools setItems:buttons animated:NO];
UIBarButtonItem *twoButtons = [[UIBarButtonItem alloc] initWithCustomView:tools];
self.navigationItem.rightBarButtonItem = twoButtons;
//Add annotations of different colors based on initial and final places.
SBRouteAnnotation *startAnnotation = [[SBRouteAnnotation alloc] initWithCoordinate:[[routePoints objectAtIndex:0] coordinate]
title:mStartPoint
annotationType:SBRouteAnnotationTypeStart];
SBRouteAnnotation *endAnnotation = [[SBRouteAnnotation alloc] initWithCoordinate:[[routePoints lastObject] coordinate]
title:mEndPoint
annotationType:SBRouteAnnotationTypeEnd];
[mMap.mapView addAnnotations:[NSArray arrayWithObjects:startAnnotation, endAnnotation,nil]];
}
- (void)directions:(UICGDirections *)directions didFailWithMessage:(NSString *)message {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Map Directions" message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertView show];
}
#pragma mark -
#end
I tried to put my code on a new project (empty application) and it worked fine, i didn't understand that error and its possible causes.
EDIT:
I tried to track the problem by elimination,and my code worked fine when i remove this method:
//Invoked when the class is instantiated in XIB
-(id)initWithCoder:(NSCoder*)aDecoder
{
self = [super initWithCoder:aDecoder];
if( self)
{
[self customInitialization];
}
return self;
}
However, when i run, my app doesn't display me the route between the two points (The purpose of the app). So this method seems important for the whole class because without it, i couldn't get the route and in the other side when it's there, the app crashes. How should i deal with this contradiction?
#Vince is putting you on the right track. Since the problem is in an NSURL method being called by a framework (Google Maps in this case) you need to debug what you are passing to the framework. You have the source for the framework also right? You can set breakpoints in loadWithStartPoint:endPoint:options:] to see what's going on.
One thing I did notice is you are passing an NSMutableArray as the endPoint param when I believe it expects an NSString.