Hi I just came across MTLocation here: https://github.com/darkseed/MTLocation.
I want to use a locate me button in my app which will be located in navigation bar and when pressed will move the map to current location.
The author proposes to use the code like this:
// Configure Location Manager
[MTLocationManager sharedInstance].locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[MTLocationManager sharedInstance].locationManager.distanceFilter = kCLDistanceFilterNone;
[MTLocationManager sharedInstance].locationManager.headingFilter = 5; // 5 Degrees
// create locate-me item
MTLocateMeBarButtonItem *locateMeItem = [[[MTLocateMeBarButtonItem alloc] initWithLocationStatus:MTLocationStatusIdle] autorelease];
// set delegate that is called when mode of Button changes
locateMeItem.delegate = [MTLocationManager sharedInstance];
// add target-action
[locateMeItem addTarget:self action:#selector(myCustomSelector:) forControlEvents:UIControlEventTouchUpInside];
// disable heading
locateMeItem.headingEnabled = NO;
// create array with ToolbarItems
NSArray *toolbarItems = [NSArray arrayWithObject:locateMeItem];
// set toolbar items
[self.toolbar setItems:toolbarItems animated:NO];
which is great to show a locate me button in toolbar but how can we make this work to show current location through gps? I guess tha we have to implement myCustomSelector method but I do not know how. Any help?
Make sure that you have
self.mapView.showsUserLocation = YES;
And then implement myCustomSelector:, for example like this:
- (void) myCustomSelector:(MTLocateMeBarButtonItem*) button {
[self.mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate];
}
You'll need to take care of a proper functionality at different button modes (whether MTLocateMeBarButton is Idle, or something else), but that should give you a direction.
Related
I want to create a simple mobilesubstrate tweak that hides and shows status bar icons like battery or Carrier or wifi signal indecator. I've seen libstatusbar project but i can't find out how to hide iOS's icons. Is there any other way to do this without the use of this library? I just want to hide and show the default icons
Not possible using public API. You can only hide the entire status bar, not only certain elements of it.
For jailbreak, take a look at:
https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIStatusBarItem.h
In particularly, look at the following methods:
+ (BOOL)itemType:(int)arg1 idiom:(int)arg2 appearsInRegion:(int)arg3;
+ (BOOL)itemType:(int)arg1 idiom:(int)arg2 canBeEnabledForData:(id)arg3 style:(id)arg4;
These methods are consulted whether iterms should appear or not. Return NO here to disable items.
Here is what I use in my tweak:
int itemToHide = 0;
[[objc_getClass("SBStatusBarStateAggregator") sharedInstance] beginCoalescentBlock];
[[objc_getClass("SBStatusBarStateAggregator") sharedInstance] _setItem:itemToHide enabled:NO];
[[objc_getClass("SBStatusBarStateAggregator") sharedInstance] endCoalescentBlock];
Only problem - iOS uses integer values for status bar items and they're different on different iOS versions. You could test every iOS version and store values for each one of them but I found a better way.
I hook SBStatusBarStateAggregator _setItem:(int)arg1 enabled:(BOOL)arg2 method. Then I call one of the SBStatusBarStateAggregator -(void)_update**** methods. For example, let's say I want to find location icon index. I call SBStatusBarStateAggregator -(void)_updateLocationItem method. It then will call hooked SBStatusBarStateAggregator _setItem:(int)arg1 enabled:(BOOL)arg2 where I will store the index.
I also hook SBStatusBarStateAggregator -(void)_notifyItemChanged:(int)arg. This method is called as part of SBStatusBarStateAggregator -(void)_update**** call. When determing status bar icon index I simply ignore calls to it by returning without calling original implementation.
And if you want to permanently hide some of the icons you still need to hook SBStatusBarStateAggregator _setItem:(int)arg1 enabled:(BOOL)arg2 and SBStatusBarStateAggregator -(void)_notifyItemChanged:(int)arg in order to ignore any iOS attempts to show hidden icons. For example, signal level and data/time are reanabled every time they're updated.
That's all for iOS 7. On iOS 5-6 API is different but I use pretty much the same approach. To hide status bar item
int itemToHide = 0;
[[objc_getClass("SBStatusBarDataManager") sharedDataManager] setStatusBarItem:itemToHide enabled:NO];
I hook SBStatusBarDataManager -(void)updateStatusBarItem:(int)item to determine icon index and then call SBStatusBarDataManager -(void)_locationStatusChange in case of location icon.
Ok. Here is solution.
In your plist file add row:
View controller-based status bar appearance : NO
Make a category on UINavigationBar with this content:
#import "UINavigationBar+StatusBar.h"
#import
#implementation UINavigationBar (StatusBar)
+ (void)load
{
[self swizzleOriginalSelectorWithName:#"layoutSubviews" toSelectorWithName:#"my_layoutSubviews"];
}
- (void)my_layoutSubviews
{
[self my_layoutSubviews];
[self setFrame:CGRectMake(0, 0, self.frame.size.width, 64)];
}
+ (void)swizzleOriginalSelectorWithName:(NSString *)origName toSelectorWithName:(NSString *)swizzleName
{
Method origMethod = class_getInstanceMethod([self class], NSSelectorFromString(origName));
Method newMethod = class_getInstanceMethod([self class], NSSelectorFromString(swizzleName));
method_exchangeImplementations(origMethod, newMethod);
}
#end
This will increase navigation bar for 20pt.
Then, make your custom view for status bar.
e.g.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self makeCustomSatusBar];
// Override point for customization after application launch.
return YES;
}
- (void)makeCustomSatusBar
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
UIColor *statusBarColor = [UIColor blackColor];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.frame.size.width, 20)];
view.layer.zPosition = INT_MAX;
view.backgroundColor = [UIColor clearColor];
// Making time label
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = #"HH:mm";
UILabel *timeLabel = [UILabel new];
timeLabel.text = [formatter stringFromDate:[NSDate date]];
timeLabel.textColor = statusBarColor;
timeLabel.font = [UIFont systemFontOfSize:12];
[timeLabel sizeToFit];
timeLabel.center = CGPointMake(view.frame.size.width/2, view.frame.size.height/2);
[view addSubview:timeLabel];
//
// make other indicators you need...
//...
[self.window addSubview:view];
}
And you will have something like this:
Note, that you need to update values of your custom view every time (i.e. time label, battery, etc..) , so it would be better to make a separate class for your status bar, and make a infinite timer with 1 sec of tick and do your updates in timer's action.
may be you just need this?
[[UIApplication sharedApplication] setStatusBarHidden:YES]
And if you want just empty view on top of 20pt height, then make that and add to UIWindow, and shift down subview of UIWindow for 20 pt
I am trying to add the default button to return to current Location within google map. I added the button using
self.mapView.myLocationButton = YES
But not able to hide the blue dot which is not required in my case.
If i set
self.mapView.myLocationEnabled = NO
It would remove the functionality to return back to current Location on pressing the current Location button.
Following is the code i've implemented
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.mapView.delegate = self;
self.mapView.settings.myLocationButton = YES;
self.mapView.myLocationEnabled = YES;
}
You can simply add the annotation view:
-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *note= [mapView viewForAnnotation:mapView.userLocation];
note.hidden = YES;
}
In this way the map will still receive user's location updates but the blue dot is hidden. Remember that since this is a delegate method, you should correctly set the delegate.
self.mapView.myLocationEnabled = NO to hide the blue dot.
set a class to implement CLLocationManagerDelegate to track user's location.
try
self. mapView.showsUserLocation=NO;
Easier way would be to replace your annotation with view that has color as clearColor. This way our current location would be shown with an invisible annotation ;-)
Simply use mapView_.myLocationEnabled = NO;
Its solve your problem
In Swift 4x -
mapView.delegate = self
mapView.settings.myLocationButton = true
mapView.isMyLocationEnabled = true
In my app on button click i have add pickerview to the windows below is the code show that
- (IBAction)btnMake:(id)sender
{
pickerViewMake = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerViewMake.showsSelectionIndicator = YES;
pickerViewMake.dataSource = self;
pickerViewMake.delegate = self;
[pickerViewMake setBackgroundColor:[UIColor clearColor]];
[viewPicker addSubview:pickerViewMake];
[self.view.window addSubview:pickerViewMake];
}
-(void)removeAllPicker
{
[pickerViewMake removeFromSuperview];
[pickerViewModel removeFromSuperview];
[pickerViewYear removeFromSuperview];
[pickerViewTrim removeFromSuperview];
}
remove all picker is the method used for removing the picker from superview
it works
The problem is that on multiple clicking btnMake number of the picker view cones up then
removeallPicker method call than also pickerview does not remove from superview.
Do one Thing create one BOOL variable and set in viewdidload yes and check in function if it is yes then picker come and also make it no in btnmake method.
Try in the following way
if (<instance>)
{
[<instance> removeFromSuperview],<instance> = nil;
}
After this create your picker then it won't create multiple times, it will create only once.
I want to have the same functionality of MKUserTrackingBarButtonItem on a Map but I want to do it programmatically.
Normally using I do this on ViewController
- (void) viewDidLoad
{
...
MKUserTrackingBarButtonItem *buttonItem = [[MKUserTrackingBarButtonItem alloc] initWithMapView:self.map];
self.navigationItem.rightBarButtonItem = buttonItem;
...
}
But I want to try it by code. I know how to get the UserLocation, but how can I get the compass functionality?
I know it's an old post but isn't compass functionality the "heading"? And so, you can set the tracking mode of the map by changing the userTrackingMode of the MKMapView.
When I have location services disabled, this alert shows up twice. The first time is without the location manager purpose property displayed. Immediately after that (before a button of first alert is touched), it shows again, this time with the purpose property included.
When the second alert is dismissed, the first alert is still there.
This is a little annoying, and I would expect it to be confusing to the users.
What can I do to only show it once, with the purpose property?
I had both a map controller object and a location manager object instantiated in my app delegate.
mapController = [[[MapController alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] retain];
[self restartLocationManager];
However, the location manager purpose property is not set until the location manager is instantiated in this code:
- (void) restartLocationManager {
if (locationManager)
[locationManager release];
locationManager = [[[CLLocationManager alloc] init] retain];
locationManager.purpose = NSLocalizedString(#"Location Service Purpose", nil);
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
}
So this was a clue that something in the initialization of the map was triggering the first alert.
Because I declined to turn location services on in the first alert, the map controller initialized and saw a need to show the alert. The map controller initialization is this (it is part of a singleton, and needs some cleanup in that regard, but ignoring that...):
- (id) initWithFrame:(CGRect)aFrame {
#synchronized(self) {
if (!theMap) {
if (!self) self = [super init];
theMap = [[[MKMapView alloc] initWithFrame:aFrame] retain];
theMap.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
theMap.showsUserLocation = YES;
theMap.delegate = self;
}
return self;
}
Stepping through the code, I saw the second alert show up when the showUserLocation line was executed. I'll have to do a little more testing to narrow it down exactly, but I think I'm on the right track now.