I have been trying to make an app that allows the user to retrieve the current location using the core location framework. I wanted to be able to get the coordinates of the device that is using the app when the app launches and be able to display them using UILabels. Can someone please tell me what i am doing wrong or what adjustments I should make to the code?
Header file:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *longitude;
#property (strong, nonatomic) IBOutlet UILabel *latitude;
#property (strong, nonatomic) IBOutlet UILabel *altitude;
#property (strong, nonatomic) IBOutlet UILabel *speed;
#end
Implementation file:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
CLLocationManager *locationManager;
[super viewDidLoad];
locationManager = [[CLLocationManager alloc]init]; // initializing locationManager
locationManager.delegate = self; // I set the delegate of locationManager to self.
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // setting the accuracy
[locationManager startUpdatingLocation]; //requesting location updates
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"There was an error retrieving your location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[errorAlert show];
NSLog(#"Error: %#",error.description);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *crnLoc = [locations lastObject];
_latitude.text = [NSString stringWithFormat:#"%.8f",crnLoc.coordinate.latitude];
_longitude.text = [NSString stringWithFormat:#"%.8f",crnLoc.coordinate.longitude];
_altitude.text = [NSString stringWithFormat:#"%.0f m",crnLoc.altitude];
_speed.text = [NSString stringWithFormat:#"%.1f m/s", crnLoc.speed];
}
#end
I get these 2 errors.
Assigning to 'id<CLLocationManagerDelegate> _Nullable' from incompatible type 'ViewController *const __strong'
'UIAlertView' is deprecated: first deprecated in iOS 9.0 - UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead
You're not implementing the CLLocationManagerDelegate protocol, which is why you get the first error. You could implement it like this:
#interface ViewController () <CLLocationManagerDelegate>
#end
You should also check the documentation for the methods that you'll need to implement in order to conform to that protocol, which you'll have to write in your #implementation. Only after conforming to that protocol is this assignment allowed:
locationManager.delegate = self; // I set the delegate of locationManager to self.
The second issue appears to be a warning. Apple did deprecate UIAlertView in iOS 9.0 and it has been replaced by UIAlertController, so you should use that instead. This NSHipster article explains how to use and compares it with the old, deprecated, version, which is interesting, but it's in Swift (I'm leaving it for the discussion they present). Here you'll also find some examples in Objective-C. Here's an example as shown on that last link:
UIAlertController * view= [UIAlertController
alertControllerWithTitle:#"My Title"
message:#"Select you Choice"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Do some thing here
[view dismissViewControllerAnimated:YES
completion:nil];
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[view dismissViewControllerAnimated:YES completion:nil];
}];
[view addAction:ok];
[view addAction:cancel];
[self presentViewController:view animated:YES completion:nil];
Related
I am trying to use GoogleMap API and apple's CLocationManager for my app, but it does not show my current location in either of them.
I have set up the API in AppDelegate.m and also asking and checking user permission to track location. This is the code I have for map.
I am trying to get user's current location and I will get user's destination and notify them when they are close to their location (using both estimated time and distance). I would appreciate if you can help me about that too. thanks
#import "GMapViewController.h"
#import <GoogleMaps/GoogleMaps.h>
#import "CSMarker.h"
#import GoogleMaps;
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface GMapViewController () <GMSMapViewDelegate, CLLocationManagerDelegate, MKMapViewDelegate>
#property(strong, nonatomic) NSURLSession *markerSession;
#property(strong, nonatomic) GMSPolyline *polyline;
#property(strong, nonatomic) NSArray *steps;
//apple
#property (weak, nonatomic) IBOutlet MKMapView *mapViews;
#end
#implementation GMapViewController
#synthesize viewDirection,locationManager;
#synthesize mapView;
- (void)startStandardUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self startStandardUpdates];
self.mapView.delegate=self;
self.mapViews.delegate=self;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[locationManager requestAlwaysAuthorization];
}
[locationManager startUpdatingLocation];
//map type
self.mapView.mapType = kGMSTypeNormal;
[self.view addSubview:self.mapView];
// to show compass and mylocation button
self.mapView.settings.compassButton = YES;
self.mapView.settings.myLocationButton = YES;
//setting max and min zoom
//[self.mapView setMinZoom:10 maxZoom:18];
//for Drawing a line on the map
GMSMutablePath *singleLinePath = [[GMSMutablePath alloc] init];
// create a GMSMutablePath and add two points as lat/lng
[singleLinePath addLatitude:28.5382 longitude:-81.3687];
[singleLinePath addLatitude:28.5421 longitude:-81.3690];
// use the path to create a GMSPolyline
GMSPolyline *singleLine = [GMSPolyline polylineWithPath:singleLinePath];
singleLine.map = self.mapView; //turn the line on
self.mapViews.showsUserLocation = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
NSString *errorType = nil;
if (error.code == kCLErrorDenied)
{errorType = #"Access Decied";}
else
{errorType = #"Unknown Error";}
UIAlertController* alert = [UIAlertController
alertControllerWithTitle: #"Alert"
message: #"Error getting location!"
preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(#"OK action");
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
#end
Can you check if you have defined following keys in your info.plist? All three keys are not needed, you need to define one or two of these keys depending on your uses permissions.
NSLocationAlwaysUsageDescription: Always location description
NSLocationWhenInUseUsageDescription: When in use location description
NSLocationAlwaysAndWhenInUseUsageDescription: description for both
Take another look at your locationManager:(CLLocationManager *)manager didUpdateLocations: method. You are getting the newLocation reference, but it doesn't look like you do anything with it. Also, you do not appear to be setting the currentLocation value anywhere.
Hey everyone running into major errors where I'm being told the SLComposerViewController is unrecognizable. No visible interface for UIController and an expected identifier on my else statement when it's written correctly. It is also not recognizing my actionContoller or my twitterVC. I am in school and this is the code example I was given I have checked it and triple checked it and it is written verbatim to the intructed example which is leaving me confused as there are 12 errors in all. Any help anyone can give me to correct these errors would be great!
// ViewController.m
// SocialNetworkApp
//
// Created by Jessy on 2/12/18.
// Copyright © 2018 A3LeversPeer. All rights reserved.
//
#import "ViewController.h"
#import "Social/Social.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextView *tweetTextView;
- (void) configureTweetTextView;
- (void) showAlertMessage: (NSString *) myMessage;
#property (weak, nonatomic) IBOutlet UITextView *fbTextView;
#property (weak, nonatomic) IBOutlet UITextView *socialTextView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self configureTweetTextView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) showAlertMessage:(NSString *) myMessage {
UIAlertController *alertController;
alertController = [UIAlertController alertControllerWithTitle:#"TwitterShare" message:myMessage preferredStyle: UIAlertControllerStyleAlert];
[alertController addAction: [UIAlertAction actionWithTitle:#"Okay" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
- (IBAction)tweetShareAction:(id)sender {
if ([self.tweetTextView isFirstResponder]) {
[self.tweetTextView resignFirstResponder];
}
UIAlertController *actionController = [UIAlertController alertControllerWithTitle:#"" message:#"Tweet Notes" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction =[UIAlertAction actionWithTitle:#"Cancel" style: UIAlertActionStyleDefault handler:nil];
UIAlertAction *tweetAction =[UIAlertAction actionWithTitle:#"Tweet"style: UIAlertActionStyleDefault handler:
^(UIAlertAction *action) {
if([SLComposeViewController
isAvailableForServiceType:SLServiceTypeTwitter]
(SLComposeViewController *twitterVC= [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter]);
}];
//Tweet Out
if( [self.tweetTextView.text length] <140 ) {
[twitterVC setInitialText:self.tweetTextView.text];
}
else{
NSString *shortText = [self.tweetTextView.text substringToIndex:140];
}
[self.presentedViewController: twitterVC animated:YES completion:nil];
}
else{
//Raise Objection
[self showAlertMessage:#"Sign in to Twitter"];
[actionController addAction:tweetAction];
[actionController addAction:cancelAction];
[self presentViewController:actionController animated:YES completion:nil];
- (void) configureTweetTextView {
self.tweetTextView.layer.backgroundColor =[UIColor colorWithRed: 0.98
green: 0.80 blue: 0.93
alpha: 1.0].CGColor;
self.tweetTextView.layer.cornerRadius= 10.0;
self.tweetTextView.layer.borderColor= [UIColor colorWithWhite: 0
alpha: 0.5].CGColor;
self.tweetTextView.layer.borderWidth= 2.0;
}
- (IBAction)fbShareAction:(id)sender {
}
- (IBAction)socialShareAction:(id)sender {
}
- (IBAction)nothingShareAction:(id)sender {
}
#end
Try to replace:
#import "Social/Social.h"
By:
#import <Social/Social.h>
Social is Apple's framework, so you should import it with <> sign.
By the way, check your Target -> General -> Linked Frameworks and Libraries that you included in Social.framework.
I want to reset the textfields of myview to empty when an actionsheet destructive button is pressed. Done button calls the actionsheet.
This is my actionsheet:
- (IBAction)submit:(id)sender {
UIActionSheet *sheet=[[UIActionSheet alloc]initWithTitle:#"Options" delegate:sender cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Reset" otherButtonTitles:#"Save", nil];
[sheet showInView:self.view];
}
And is used this method to reset:
- (void)sheet:(UIActionSheet *)sheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==0)
{
self.textf1.text = #"";
}
}
But Nothing is happening.
Replace delegate:sender to delegate:self that's why delegates
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
are not getting call also update the delegate function, once you done just set all textFiled to .text= #"". i hope it will work
Also posted as Comment earlier.
delegate method you are using is worng
Please make your delegate to self
delegate:self
and Use this method
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
////check index and empty all textfields
}
You should set self as the delegate, and I think the new UIAlertController is more convenience to use, without any delegate:
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:#"Action Sheet" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *reset = [UIAlertAction actionWithTitle:#"Reset" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
self.textf1.text = #"";
}];
actionSheet.actions = #[reset, cancel];
[self presentViewController:actionSheet animated:YES completion:nil]
Lots of issues:
Change this line:
if (buttonIndex == 0)
to:
if (buttonIndex == sheet.destructiveButtonIndex)
You also need to pass self as the delegate instead of sender.
UIActionSheet *sheet= [[UIActionSheet alloc] initWithTitle:#"Options" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Reset" otherButtonTitles:#"Save", nil];
And the name of the delegate method matters. You need:
- (void)actionSheet:(UIActionSheet *)sheet clickedButtonAtIndex:(NSInteger)buttonIndex
See the docs for UIActionSheet. There are specific properties to get various button indexes. Use those over hardcoding index numbers.
Also note that UIAlertView is deprecated. You should be using UIAlertController unless you need to support iOS 7.
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate,UIActionSheetDelegate>
{
UIActionSheet *sheet;
}
#property (weak, nonatomic) IBOutlet UITextField *txtText;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
//Button click
- (IBAction)OpenActionSheet:(id)sender
{
sheet=[[UIActionSheet alloc]initWithTitle:#"ActionSheetDemo" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Reset" otherButtonTitles:#"Save", nil];
[sheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex==0)
{
_txtText.text=#"";
}
}
#end
I have an action sheet that when one of it's options are clicked successfully calls clickedButtonAtIndex when run in the simulator but when testing on an iPhone (5s in Xcode 6) it doesn't reach the callback.
The header...
#protocol SGETriggerToolBarDelegate
-(void)showCustomEditView;
#end
#interface SGETriggerToolBarController : UIViewController <UIActionSheetDelegate>
#property (nonatomic, assign) id <SGETriggerToolBarDelegate> delegate;
#property (nonatomic, strong) UIToolbar *toolbar;
in the implementation...
// in xController.m
// ...
- (void)triggerButtonHandler
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select an event type"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (SGETrigger *trigger in triggers) {
[actionSheet addButtonWithTitle:trigger.name];
}
[actionSheet addButtonWithTitle:#"Cancel"];
actionSheet.cancelButtonIndex = triggers.count;
[actionSheet showFromToolbar:self.toolbar];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == [actionSheet cancelButtonIndex]) {
return;
} else {
selectedTrigger = triggers[buttonIndex];
triggerButton.title = [NSString stringWithFormat:#"• %# •", selectedTrigger.name];
[delegate showCustomEditView];
}
}
// ...
If you get "Presenting action sheet clipped by its superview. Some controls might not respond to touches"
Replacing...
[actionSheet showFromToolbar:self.toolbar];
with
[actionSheet showInView:[UIApplication sharedApplication].keyWindow];
solved this for me.
If the "button/checkbox" I have created below is selected by the user on view controller 1, then I would like an image to (appear) display on view controller 2.
if i leave view controller 2 screen and come back to view controller 2 screen, the image should still display as long as the button is still selected on view controller 1.
if the "button" is no longer selected on view controller 1, then the image should no longer be displayed on view controller 2.
Please note that the "button/checkbox" mentioned is being created by the code below. Please help, thank you.
(IBAction)checkButton2:(id)sender {
if (!checked2) {
[_checkBoxButton2 setImage:[UIImage imageNamed:#"checkBoxMarked.png"] forState:UIControlStateNormal];
checked2 = YES;
// alert placeholder
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Locked" message:#"this is locked." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:#"Cancel", nil];
[alert show];
[_checkBoxButton2 setImage:[UIImage imageNamed:#"checkBox.png"] forState:UIControlStateNormal];
checked2 = NO;
}
else if (checked2) {
[_checkBoxButton2 setImage:[UIImage imageNamed:#"checkBox.png"] forState:UIControlStateNormal];
checked2 = NO;
// alert placeholder
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Character selection:" message:#"The box is no longer selected." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:#"Cancel", nil];
[alert show];
}
}
You should Embed you View into a navigation controller.
When you press Next Screen, perform a segue:
- (IBAction)nextBtn:(id)sender {
[self performSegueWithIdentifier:#"segue" sender:self];
}
before you segue, set a BOOL flag to determine if it should display or not:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"step2Segue"]){
ImageViewController *controller = (ImageViewController *)segue.destinationViewController;
controller.displayImage = checked2;
}
}
Finaly in the ImageViewController add a condition based on the Bool to determine if you should display it or not:
in .h
#interface ImageViewController : ViewController
#property (strong, nonatomic) IBOutlet UIImageView *image;
#property (nonatomic, assign) BOOL displayImage;
#end
In .m
-(void)viewDidLoad{
if (self.displayImage) {
self.image.hidden = YES;
}else{
self.image.hidden = NO;
}
}
One thing at a time.
In the ViewController1 class, you'll have to have an instance of ViewController2 created and made strong in your .h (if you're not using Swift).
#property (nonatomic, strong) ViewController2 *viewController2;
Make sure it's instantiated at the time that you press the button. Within the .h for ViewController 2, you'll have to do something similar with a UIImage and UIImageView or whatever you use to display the picture
#property (nonatomic, strong) UIImage *myImage;
#property (nonatomic, strong) UIImageView *myImageView;
Then, in ViewController1, you'll have to control the events that happen in ViewController2 when you press the button. I would use a BOOL or something else simple to keep track of when the image is supposed to be visible.
BOOL imageShouldBeThere = false;
- (void) myButtonWasPressed: (id) sender
{
if(imageShouldBeThere == false)
{
[viewController2Instance showTheImage];
imageShouldBeThere = true;
}
else
{
[viewController2Instance hideTheImage];
imageShouldBeThere = false;
}
}
This is obviously just a rudimentary template, but it should do the trick.
Working code:
FirstViewController.m
- (IBAction)buttonClicked:(id)sender {
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"second"];
secondViewController.shouldShowImage = YES;
[self presentViewController:secondViewController animated:YES completion:^{
}];
}
SecondViewController.h
#property (nonatomic, assign) BOOL shouldShowImage;
SecondViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.shouldShowImage)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
[imageView setImage:[UIImage imageNamed:#"9gag.png"]];
[self.view addSubview:imageView];
}
else
{
//dont show image....
}
}