Is it possible to have an MKMapView lined up on top of another MKMapView with the top having a level of transparency so you can see the bottom. Further when the user swipes, I would like BOTH the top and bottom map to scroll, or zoom in unison.
I am finding the standard map too plain and the satellite map too intense and was hoping to combine them for effect.
Any thoughts?
You can do this, no problem at all. As you already described, just put a MKMapView in your window and a second one on top. Let's assume we call them _map1 and _map2, the latter being on top of _map1. The MKMapViewDelegate protocol will let you know when a user scrolls/moves/zooms _map2, so you can tell _map1 to display the same visible region of _map2.
In my example I use a slider to set the level of transparency of _map2.
#import "ViewController.h"
#import MapKit;
#interface ViewController () <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *map1;
#property (weak, nonatomic) IBOutlet MKMapView *map2;
#property (weak, nonatomic) IBOutlet UISlider *alphaSlider;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[_map1 setMapType:MKMapTypeSatellite];
[_map2 setMapType:MKMapTypeStandard];
[_map2 setAlpha:0.5];
[_map2 setDelegate:self];
[_alphaSlider addTarget:self action:#selector(sliderChanged) forControlEvents:UIControlEventAllEvents] ;
_alphaSlider.value = _map2.alpha;
}
- (void)mapViewDidChangeVisibleRegion:(MKMapView *)mapView
{
// _map2 is on top and will receive visible region updates, i.e. the user scrolled/moved/zoomed the map
// just pass the new region to _map1 so it will be similar to that one of _map2
[_map1 setRegion:_map2.region];
}
- (void)sliderChanged
{
[_map2 setAlpha:_alphaSlider.value];
}
Related
I have a ViewController that populates a couple of sliders as so:
// ViewController.h
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UISlider *aSlider;
#property (weak, nonatomic) IBOutlet UISlider *anotherSlider;
#end
// ViewController.m
#interface ViewController ()
#end
#implementation ViewController
-(void)resetSliders
{
NSLog(#"Resetting sliders sl1: %# sl2: %#", self.aSlider, self.anotherSlider);
[self.aSlider setValue:0.5f animated:NO];
[self.anotherSlider setValue:0.5f animated:NO];
}
- (IBAction)setOneSlider:(UISlider *)sender {
NSLog(#"Setting aSlider to %f", sender.value);
self.sl1Val = sender.value;
[self doAThing];
}
- (IBAction)setTwoSlider:(UISlider *)sender {
NSLog(#"Setting anotherSlider to %f", sender.value);
self.sl2Val = sender.value;
[self doBThing];
}
#end
The calls to setOneSlider and setTwoSlider are wired to the value changed events of the two sliders. That works perfectly well. Unfortunately, I have not connected the sliders to their programmatic handles, because the call to resetSliders yields no change in the UI, even with a call added to setNeedsDisplay on the two slider elements.
When resetSliders is called, the log shows:
2015-04-28 12:22:19.608 myApp[4489:681127] Resetting sliders sl1: (null) sl2: (null)
Can anyone indicate to me how to set the self.aSlider and self.anotherSlider with the correct object handles?
To add some color: I have dragged the UI representation of the sliders to their respective #property declarations, and I can see that they have filled-in grey circles in the margin, indicating that they've been wired. The Connections Inspector shows both a "Value Changed" event trigger and a Referencing Outlet connecting myApp to the slider(s).
I'm extremely new to IOS programming and am reaching the limits of learning-by-failing.
The properties should be defined inside the #interface blocks. Yours are currently outside. Additionally, they should probably be weak instead of retain, and no need for the #synthesize statements or the ivars.
Lastly, when you reference them in code, you should do so as self.aSlider, not just aSlider.
It sounds like you still need to connect these outlets in Interface Builder:
#property (retain, nonatomic) IBOutlet UISlider *aSlider;
#property (retain, nonatomic) IBOutlet UISlider *anotherSlider;
Also you don't need to declare properties and ivars for the same sliders. Just declare and use the properties you already have.
#interface ViewController : UIViewController
and
-(void)resetSliders
{
// note the addition of 'self.' below
NSLog(#"Resetting sliders sl1: %# sl2: %#", self.aSlider, self.anotherSlider);
[self.aSlider setTo:0.5f animated:NO];
[self.anotherSlider setTo:0.5f animated:NO];
}
I am using google panorama street view in ios, But i am not able to put GMSPanoramaView in subview , it occupies whole screen .Please help me regarding this.Or is there any way that we can put it view with desired size so that it should not occupy whole screen.
Right now I am using following code : and I am getting black screen while using this code.
#import <UIKit/UIKit.h>
#import <GoogleMaps/GoogleMaps.h>
#interface NextViewController : UIViewController{
GMSPanoramaView *panoView_;
}
#property (weak, nonatomic) IBOutlet UIView *sub_View;
#end
-(void)loadView{
panoView_ = [[GMSPanoramaView alloc] initWithFrame:CGRectZero];
self.sub_View = panoView_;
[panoView_ moveNearCoordinate:CLLocationCoordinate2DMake(-33.732, 150.312)];
}
I have screen w/ a few labels. Each of them might be from 1 to a dozen lines.
So some times all content not to fit on screen so scrolling is necessary.
All seem to be easy and there are a lot of tutorials how to do it.
But my problem that scrolling works only when I zoom in screen. Setting "contentSize" doesn't give any effect.
#interface OMSScroolViewController : UIViewController <UIScrollViewDelegate>
#property (strong, nonatomic) IBOutlet UIScrollView *scroll;
#property (strong, nonatomic) IBOutlet UILabel *label1;
#property (strong, nonatomic) IBOutlet UILabel *label2;
#end
and implementation
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
scroll.minimumZoomScale=1.0;
scroll.maximumZoomScale=1.0;
[scroll setContentSize:CGSizeMake(320, 1690)]; // constants for simplicity
scroll.delegate=self;
}
any suggestions?
thanks in advance.
Although not technically required, I've never had UIScrollView to work properly without using a content view to wrap the scrollable content. Once you wrap all your labels in a single view, your code should work without issue.
I have looked around many different threads over the same issue and can't seem to grasp what is going on here. I created a very basic and simple project. What I want to happen is for a bunch of elements to be inside of a scroll view that scrolls properly. These elements may include a UITableView that scrolls independently (or not). Here is how I set up my basic project:
Running this in the simulator will result in a view that doesn't scroll. This is expected as there is more than enough room for all of the elements. I then changed the size of UIScrollView like so:
Running this in the simulator results in a smaller view that will not scroll. I assume I am not doing this the correct way. Here is the code I have most recently tried:
ViewController.h
#interface ViewController : UIViewController <UIScrollViewDelegate>
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
#property (strong, nonatomic) IBOutlet UIButton *buttonOne;
#property (strong, nonatomic) IBOutlet UIButton *buttonTwo;
#property (strong, nonatomic) IBOutlet UIButton *buttonThree;
#property (strong, nonatomic) IBOutlet UIButton *buttonFour;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.buttonOne setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.buttonTwo setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.buttonThree setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.buttonFour setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Any help would be greatly appreciated.
The problem is that when you change the size of the scroll view in interface builder, you are also setting the content's size to the same as the frame size.
You can manually increase the content size of the scroll view in code so that you can scroll it like this:
// scrollView is an outlet to your scroll view
// Add 200 points to the bottom of the scroll view
[self.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 200, 0)];
Though, you probably don't need to do this as long as you draw the sub view at full size, and make it a sub view of some other view, and let it automatically re-size itself.
so i have a navigation controller, and in it i have a view and a scrollview embedded in that view. My goal is to make my program scroll to a location when it is close to it.
to do this i added to outlets to my vc. one is the scroll view and the other is the view. The view is just a big rectangle about twice as wide as the iphones screen and slightly higher. My scroll view scrolls only horizantally, and whenever i lift my finger from scrolling, my goal is if the iphones bounds are within the views bounds. I want the scroll view to manually scroll to the middle of that view. (if you can think of a game menu in angry birds or cut the rope, when the user is scrolling between level packs horizantally, when the user lets go from scrolling it sort of zaps into place to the level the user let go by, this is what i want to mimick).
so, heres my code for both my view and my vc. The only thing i did with storyboards is that i hooked up the two outlets, and set the size of my view.
(the level packs is the vc and the other one is the view).
#import <UIKit/UIKit.h>
#import "HorizantalLockingView.h"
#interface LevelPacks : UIViewController <ViewDelegate>
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#property (weak, nonatomic) IBOutlet HorizantalLockingView *lockingView;
#end
#import "LevelPacks.h"
#implementation LevelPacks
#synthesize scrollView=_scrollView;
#synthesize lockingView = _lockingView;
-(void)viewDidAppear:(BOOL)animated
{
CGSize size;
size.width=825;
size.height=460;
self.scrollView.contentSize=size;
self.scrollView.contentOffset=CGPointMake(0, 0);
}
-(void)viewDidLoad
{
[super viewDidLoad];
self.lockingView.delegate=self;
}
- (void)viewDidUnload
{
[self setLockingView:nil];
[super viewDidUnload];
self.scrollView=nil;
// Release any retained subviews of the main view.
}
#end
#import <UIKit/UIKit.h>
#protocol ViewDelegate
#property (nonatomic, weak) UIScrollView *scrollView;
#end
#interface HorizantalLockingView : UIView
#property (nonatomic, weak) IBOutlet id <ViewDelegate> delegate;
#end
#import "HorizantalLockingView.h"
#implementation HorizantalLockingView
#synthesize delegate=_delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGRect location=self.superview.bounds;
NSLog(#"dkfjdkjf");
if (CGRectContainsRect(self.frame, location))
{
[self.delegate.scrollView scrollRectToVisible:CGRectMake(284, 190, 157, 119) animated:YES];
}
}
#end
o, and i did the nslog earlier to see if the method would even do anything, and the nslog never even ran, so obviously somethings wrong.
Im kind of new to this, any help would really be great!
Enabling paging will automatically do this for you.
scrollView.pagingEnabled=YES;
Also adding a UIPageControl and using the UIScrollView delegate methods to update the page control will add a good usability