For some reason when I launch my app it does everything correctly except show the user as blue dot on the map. It zooms in to the users current location, just no dot. Any help would be greatly appreciated.
I've added code and screenshots below for resources.
FrontViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface FrontViewController : UIViewController <CLLocationManagerDelegate>
{
CLLocationManager *objLocationManager;
double latitude_UserLocation, longitude_UserLocation;
}
#property (weak, nonatomic) IBOutlet MKMapView *objMapView;
#end
FrontViewController.m
#import "FrontViewController.h"
#import "SWRevealViewController.h"
#interface FrontViewController()
// Private Methods:
- (IBAction)pushExample:(id)sender;
#end
#implementation FrontViewController
#synthesize objMapView;
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadUserLocation];
//self.title = NSLocalizedString(#"Front View", nil);
SWRevealViewController *revealController = [self revealViewController];
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];
[self.navigationController.navigationBar addGestureRecognizer:revealController.panGestureRecognizer];
UIBarButtonItem *revealButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"reveal-icon.png"]
style:UIBarButtonItemStyleBordered target:revealController action:#selector(revealToggle:)];
self.navigationItem.leftBarButtonItem = revealButtonItem;
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BSEEK-Logo.png"]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
UIView* titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 84, 84)];
imageView.frame = titleView.bounds;
[titleView addSubview:imageView];
self.navigationItem.titleView = titleView;
}
- (IBAction)pushExample:(id)sender
{
UIViewController *stubController = [[UIViewController alloc] init];
stubController.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:stubController animated:YES];
}
- (void) loadUserLocation
{
objLocationManager = [[CLLocationManager alloc] init];
objLocationManager.delegate = self;
objLocationManager.distanceFilter = kCLDistanceFilterNone;
objLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
if ([objLocationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[objLocationManager requestWhenInUseAuthorization];
}
[objLocationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0)
{
CLLocation *newLocation = [locations objectAtIndex:0];
latitude_UserLocation = newLocation.coordinate.latitude;
longitude_UserLocation = newLocation.coordinate.longitude;
[objLocationManager stopUpdatingLocation];
[self loadMapView];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[objLocationManager stopUpdatingLocation];
}
- (void) loadMapView
{
CLLocationCoordinate2D objCoor2D = {.latitude = latitude_UserLocation, .longitude = longitude_UserLocation};
MKCoordinateSpan objCoorSpan = {.latitudeDelta = 0.2, .longitudeDelta = 0.2};
MKCoordinateRegion objMapRegion = {objCoor2D, objCoorSpan};
[objMapView setRegion:objMapRegion];
}
#end
Project Files
MKMapView has a showsUserLocation property. It looks like you need to turn that on.
You can set that property in code, but if your map view is created in a storyboard scene you can just check the User Location box in the storyboard editor:
Also: Make sure you have the appropriate key in your Info.plist to allow the app to access the user's location, and that you've granted the app appropriate permission on the device. (You can check in Settings->Privacy->Location Services.) If the app doesn't have permission to get the location, the map won't show it even if showsUserLocation is enabled.
Related
I have no issues displaying a users current location, but I am having trouble trying to zoom to it. I have found a few solutions from other posts here, but nothing seems to be working. Advice is appreciated as it is highly likely that I am missing something simple.
Here is what I have so far:
#import CoreLocation;
#interface ViewController () <CLLocationManagerDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Get authorization
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
// Check before requesting, otherwise it might crash older versions of ios
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager requestWhenInUseAuthorization];
}
self.mapView.showsUserLocation = YES;
self.mapView = [[MKMapView alloc] init];
self.mapView.delegate = self;
self.mapView.scrollEnabled = YES;
self.mapView.zoomEnabled = YES;
self.mapView.userTrackingMode = YES;
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
//CLLocationCoordinate2D loc = [userLocation coordinate];
//MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 1000, 1000);
//[self.mapView setRegion:region animated:YES];
//Zoom map to users current location
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.00001;
span.longitudeDelta = 0.00001;
CLLocationCoordinate2D location = mapView.userLocation.coordinate;
region.span = span;
region.center = location;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
}
#end
I did something like this
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
if (!self.initialLocation) {
self.initialLocation = userLocation.location;
MKCoordinateRegion mapRegion;
mapRegion.center = mapView.userLocation.coordinate;
mapRegion.span.latitudeDelta = 0.2;
mapRegion.span.longitudeDelta = 0.2;
[mapView setRegion:mapRegion animated: YES];
}
}
self.initialLocation is an instance of CLLocation. This method constantly updates the user's current location and so what I would do is check to see if it is nil, which it should be off the start and then run the code to zoom in. After the first time, self.initialLocation will never be nil.
if you would constantly like to zoom into the the user's current location...get rid of the if statement.
EDIT
Set this in your .h file for self.initialLocation
#property (strong, nonatomic) CLLocation *initialLocation;
EDIT 2
Remove this line
self.mapView = [[MKMapView alloc] init];
No need to re-initialize your IBOulet
I am trying to put an overlay on top of status bar by doing the following :
ViewController implementation
- (IBAction)addViewOnTop:(id)sender {
StatusBarOverlayWindow *overlay = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
overlay.hidden = NO;
[overlay makeKeyAndVisible];
}
StatusBarOverlayWindow header file
#import <UIKit/UIKit.h>
#interface StatusBarOverlayWindow : UIWindow {
}
#end
StatusBarOverLayWindow implementation
#implementation StatusBarOverlayWindow
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Place the window on the correct level and position
self.windowLevel = UIWindowLevelStatusBar + 1;
self.frame = frame;
self.backgroundColor = [UIColor orangeColor];
}
return self;
}
#end
When I click a button, nothing happens at all.
Does anyone have any thoughts about this issue. Please guide, thanks
Try keeping a strong reference to the StatusBarOverlayWindow, without that the variable will go out of scope after the addViewOnTop: method is complete. A property will work well here.
Example:
#interface ViewController : UIViewController
#property (nonatomic, strong) StatusBarOverlayWindow *overlayWindow;
#end
Then in your method:
- (IBAction)addViewOnTop:(id)sender {
self.overlayWindow = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
overlay.hidden = NO;
[overlay makeKeyAndVisible];
}
I have a class (ViewOpenAppointments) where I create and display a UIPopover. This is the code to define the popover in my .h file:
#interface ViewOpenAppointments : UIView {
}
#property (nonatomic, retain) UIPopoverController *popoverController;
-(void)createOpenAppointmentsPopover: (UIButton *) obViewOpenAppts;
#end
I have a check in the code that if the popover is visible, dismiss it. This is the code:
// create popover
UIViewController* popoverContent = [[UIViewController alloc] init];
// UIView *popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 650, 416)];
ViewOpenAppointments *popoverView = [[ViewOpenAppointments alloc] initWithFrame:CGRectMake(0, 0, 650, 416)];
popoverView.backgroundColor = [UIColor whiteColor];
popoverContent.preferredContentSize = CGSizeMake(650.0, 416.0);
// create the popover controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
popoverController.delegate = (id)self;
[popoverController setPopoverContentSize:CGSizeMake(650, 416) animated:NO];
if ([popoverController isPopoverVisible]) {
[popoverController dismissPopoverAnimated:YES];
}
[popoverController presentPopoverFromRect:CGRectMake(650, 416, 10, 50) inView: obViewOpenAppts
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
The problem is that the code to dismiss the popover is never hit, which means it's not visible. But I still get the error message (described in the question title).
What am I doing wrong?
Here is a complete popover management example:
#interface ViewController () <UIPopoverControllerDelegate>
#property (nonatomic, strong) UIPopoverController* currentPop;
#end
#implementation ViewController
-(IBAction)doPopover1:(id)sender {
Popover1View1* vc = [[Popover1View1 alloc] initWithNibName:#"Popover1View1" bundle:nil];
UIPopoverController* pop = [[UIPopoverController alloc] initWithContentViewController:vc];
self.currentPop = pop;
[pop presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
pop.passthroughViews = nil;
// make ourselves delegate so we learn when popover is dismissed
pop.delegate = self;
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)pc {
self.currentPop = nil;
}
By checking self.currentPop you can make sure you don't present two popovers at once (illegal anyway).
I have a view which includes two subviews. I had it working so that only one subview was shown at a time and each subview had a button and when the button was clicked the subview would flip over and the next subview would appear. The problem was that it appeared as though the entire view was flipping. After reading on this site about how to solve the problem I attempted to add the subviews to a container and flip that instead. However now, although my first subview is showing up when I press the button it no longer flip. It doesn't do anything. I put a log statement in the method which flips the subviews, as well as a breakpoint and as far as I can tell it no longer gets called. I'm very new to xcode and objective c and delegates and I have no idea how to proceed. Any help would be appreciated. Thanks.
I have included the relevant code here:
The header for the ViewController
#interface ExerciseViewController : UIViewController<ExerciseSubViewDelegate>
//stuff for subviews
#property (nonatomic, strong) ExerciseSubViewImage *subViewImage;
#property (nonatomic, strong) ExerciseSubViewText *subViewText;
#property UIView *panel;
#end
This is the code for the ViewController:
#interface ExerciseViewController ()
#end
#implementation ExerciseViewController
#synthesize subViewImage, subViewText;
- (void)viewDidLoad
{
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
}
-(ExerciseSubViewImage *)subViewImage
{
if (!subViewImage)
{
CGRect subViewImageFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewImage = [[ExerciseSubViewImage alloc] initWithFrame:subViewImageFrame];
[_panel addSubview:subViewImage];
}
return subViewImage;
}
-(ExerciseSubViewText *)subViewText
{
if (!subViewText)
{
CGRect subViewTextFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewText = [[ExerciseSubViewText alloc] initWithFrame:subViewTextFrame];
self.subViewText.backgroundColor = [UIColor blueColor];
[_panel addSubview:subViewText];
}
return subViewText;
}
-(void)exerciseSubViewImagePressed
{
[UIView transitionWithView:_panel
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[subViewImage removeFromSuperview];
[_panel addSubview:subViewText];
}
completion: nil];
//This is how I did it before I added the container
/*[UIView transitionFromView:subViewImage
toView:subViewText
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewText.delegate = self;*/
NSLog(#"Ipushedtheimage");
}
-(void)exerciseSubViewTextPressed
{//I haven't updated this yet
[UIView transitionFromView:subViewText
toView:subViewImage
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewImage.delegate = self;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
subViewImage = nil;
subViewText = nil;
}
#end
This is the code for the delegate
#import
#protocol ExerciseSubViewDelegate <NSObject>
-(void) exerciseSubViewImagePressed;
-(void) exerciseSubViewTextPressed;
#end
I am also added the code for the first subview:
#import
#import "ExerciseSubViewDelegate.h"
#interface ExerciseSubViewImage : UIView
#property (nonatomic, strong) UIButton *button;
#property (nonatomic, assign) id<ExerciseSubViewDelegate>delegate;
#property (strong, nonatomic) UIImageView *exerciseImageView;
#end
#import "ExerciseSubViewImage.h"
#import "UIImage+animatedGIF.h"
#implementation ExerciseSubViewImage
#synthesize button;
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Initialization code
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect buttonFrame = CGRectMake(50,200,100,35);
self.button.frame = buttonFrame;
[self.button setTitle:#"Image"forState:UIControlStateNormal];
[self.button addTarget:self
action:#selector(buttonTouched)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.button];
_exerciseImageView = [[UIImageView alloc] initWithFrame:CGRectMake(50,20,160,158)];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"AppleLogo" withExtension:#"gif"];
_exerciseImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
[self addSubview:self.exerciseImageView];
}
return self;
}
-(void)buttonTouched
{
NSLog(#"imagebuttonpressed");
[self.delegate exerciseSubViewImagePressed];
}
Again, any help would be appreciate. I know I'm probably just not understanding something simple.
Ok. This took me all weekend but I finally figured it out on my own. I thought I would shere the answer here in case anyone else ever has a similar problem. After trying several other approaches I finally went back to the approach I used here and started inserting a whole bunch of NSLogs to determine the order that every thing was executing in. What I finally ended up doing was changing this: (all in the top ViewController)
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
to this:
//create panel
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, s self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
//Set the subview delegates
self.subViewImage.delegate = self;
self.subViewText.delegate = self;
I try to build a endless scrolling UIScrollView. So far I took the apple sample "StreetScroller". So all I do is setting the contentOffset back when it reaches the end of the scroll view.
Override -layoutSubviews of the UIScrollView:
- (void)layoutSubviews
{
CGFloat contentWidth = [self contentSize].width;
CGPoint contentOffset = [self contentOffset];
CGFloat centerOffsetX = (contentWidth - [self bounds].size.width) / 2.0;
CGFloat distanceFromCenter = contentOffset.x - centerOffsetX;
if (ABS(distanceFromCenter) > (contentWidth / 4.0)) {
contentOffset = CGPointMake(centerOffsetX, contentOffset.y);
[super setContentOffset:contentOffset];
}
}
Now on iOS 5 this works like a charm. But on iOS 4.3 it's not working. As soon as I call [super setContentOffset:contentOffset] it stoops scrolling because next time -layoutSubviews get's called the [self contentOffset] does not return the contentOffset that was set.
I know there are a lot a questions about infinite UIScrollViews, but one of these has fixed this problem!
Try this One. This Code is Working Properly for me on iOS 4.3
RootViewController.h
#class ViewControllerForDuplicateEndCaps;
#interface RootViewController : UIViewController {
ViewControllerForDuplicateEndCaps *viewControllerForDuplicateEndCaps;
}
#property (nonatomic, retain) ViewControllerForDuplicateEndCaps *viewControllerForDuplicateEndCaps;
- (IBAction)loadScrollViewWithDuplicateEndCaps:(id)sender;
#end
RootViewController.m
#import "RootViewController.h"
#import "ViewControllerForDuplicateEndCaps.h"
#import "InfiniteScrollViewAppDelegate.h"
#implementation RootViewController
#synthesize viewControllerForDuplicateEndCaps;
- (IBAction)loadScrollViewWithDuplicateEndCaps:(id)sender {
InfiniteScrollViewAppDelegate *delegate = (InfiniteScrollViewAppDelegate*)[[UIApplication sharedApplication] delegate];
if(self.viewControllerForDuplicateEndCaps == nil) {
ViewControllerForDuplicateEndCaps *temp = [[ViewControllerForDuplicateEndCaps alloc] initWithNibName:#"ViewControllerForDuplicateEndCaps" bundle:nil];
self.viewControllerForDuplicateEndCaps = temp;
[temp release];
}
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[delegate.navigationController pushViewController:self.viewControllerForDuplicateEndCaps animated:YES];
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end
ViewControllerForDuplicateEndCaps.h
#import <UIKit/UIKit.h>
#interface ViewControllerForDuplicateEndCaps : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scrollView;
}
#property (nonatomic, retain) UIScrollView *scrollView;
- (void)addImageWithName:(NSString*)imageString atPosition:(int)position;
#end
ViewControllerForDuplicateEndCaps.m
#import "ViewControllerForDuplicateEndCaps.h"
#implementation ViewControllerForDuplicateEndCaps
#synthesize scrollView;
- (void)viewDidLoad {
[super viewDidLoad];
// add the last image (image4) into the first position
[self addImageWithName:#"image4.jpg" atPosition:0];
// add all of the images to the scroll view
for (int i = 1; i < 5; i++) {
[self addImageWithName:[NSString stringWithFormat:#"image%i.jpg",i] atPosition:i];
}
// add the first image (image1) into the last position
[self addImageWithName:#"image1.jpg" atPosition:5];
scrollView.contentSize = CGSizeMake(1920, 416);
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
- (void)addImageWithName:(NSString*)imageString atPosition:(int)position {
// add image to scroll view
UIImage *image = [UIImage imageNamed:imageString];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(position*320, 0, 320, 416);
[scrollView addSubview:imageView];
[imageView release];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
NSLog(#"%f",scrollView.contentOffset.x);
// The key is repositioning without animation
if (scrollView.contentOffset.x == 0) {
// user is scrolling to the left from image 1 to image 4
// reposition offset to show image 4 that is on the right in the scroll view
[scrollView scrollRectToVisible:CGRectMake(1280,0,320,416) animated:NO];
}
else if (scrollView.contentOffset.x == 1600) {
// user is scrolling to the right from image 4 to image 1
// reposition offset to show image 1 that is on the left in the scroll view
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end