You will only need a ScrollView
if the contents you have now do not fit in the iPhone screen. (If you are adding the ScrollView
as the superview of the components just to make the TextField
scroll up when keyboard comes up, then it's not needed.)
The standard way to prevent the TextField
s from being covered by the keyboard is to move the view up/down whenever the keyboard is shown.
Here is some sample code:
#define kOFFSET_FOR_KEYBOARD 80.0
-(void)keyboardWillShow {
// Animate the current view out of the way
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)keyboardWillHide {
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:mailTf])
{
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
First of all, MKMapView does not use/have a predefined set of zoom levels like Google Maps does.
Instead, the visible area of a MKMapView is described using MKCoordinateRegion, which consists of two values:
- center (the center point of the region), and
- span (the size of the visible area around center).
The center point should be obvious (it's the center point of the region.)
However, span (which is a MKCoordinateSpan) consists of:
- latitudeDelta (the vertical distance represented by the region), and
- longitudeDelta (the horizontal distance represented by the region).
A brief example. Here's a toy MKCoordinateRegion:
- center:
- span:
- latitudeDelta: 8
- longitudeDelta: 6
The region could be described using its min and max coordinates as follows:
- min coordinate (lower left-hand point):
- latitude: -4
- longitude: -3
- max coordinate (upper right-hand point):
So, you can specify zoom levels around a center point by using an appropriately sized MKCoordinateSpan. As an approximation of Google's numeric zoom levels, you could reverse engineer the span sizes that Google uses for a given zoom level and create a span, accordingly. (Google describes their view regions in the same way that MKMapView does, as a center + span, so you can pull these values out of Google Maps.)
As for restricting the region, you may play w/ this delegate method:
mapView:regionWillChangeAnimated
e.g. by resizing the region back into your allowed zoom levels. (Kind of like how table views will let you scroll past the edge, but will then rubber band back into place.) However, your mileage may vary, since I haven't used it for this purpose.
btw, there are definite fixes/improvements in OS 3.1 to aspects of MapKit that were giving me trouble in 3.0.
Best Answer
It is pretty simple to calculate the zoom level. See the snippet below. You can get the mRect parameter from the
visibleMapRect
property on yourMKMapView
instance.You could probably just stop at the step for calculating the
zoomScale
as that will tell you if the zoom has changed at all.I figured this stuff out from reading Troy Brants excellent blog posts on the topic:
http://troybrant.net/blog/2010/01/mkmapview-and-zoom-levels-a-visual-guide/
Swift 3