Câu trả lời:
Tôi đã tìm thấy cho mình một giải pháp, rất đơn giản và thực hiện được các mẹo nhỏ. Sử dụng MKCoordinateRegionMakeWithDistance
để đặt khoảng cách theo mét theo chiều dọc và chiều ngang để có được mức thu phóng mong muốn. Và tất nhiên khi bạn cập nhật vị trí của mình, bạn sẽ nhận được tọa độ phù hợp hoặc bạn có thể chỉ định trực tiếp nó trong CLLocationCoordinate2D
lúc khởi động, nếu đó là những gì bạn cần làm:
CLLocationCoordinate2D noLocation;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
self.mapView.showsUserLocation = YES;
Nhanh:
let location = ...
let region = MKCoordinateRegion( center: location.coordinate, latitudinalMeters: CLLocationDistance(exactly: 5000)!, longitudinalMeters: CLLocationDistance(exactly: 5000)!)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
MKCoordinateRegionMakeWithDistance
là vẫn còn tồn tại trong Swift. Giải pháp này hoạt động!
Dựa trên thực tế là các đường kinh độ được đặt cách nhau như nhau tại bất kỳ điểm nào trên bản đồ, có một cách triển khai rất đơn giản để đặt centerCogene và zoomLevel:
@interface MKMapView (ZoomLevel)
@property (assign, nonatomic) NSUInteger zoomLevel;
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
zoomLevel:(NSUInteger)zoomLevel
animated:(BOOL)animated;
@end
@implementation MKMapView (ZoomLevel)
- (void)setZoomLevel:(NSUInteger)zoomLevel {
[self setCenterCoordinate:self.centerCoordinate zoomLevel:zoomLevel animated:NO];
}
- (NSUInteger)zoomLevel {
return log2(360 * ((self.frame.size.width/256) / self.region.span.longitudeDelta)) + 1;
}
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
zoomLevel:(NSUInteger)zoomLevel animated:(BOOL)animated {
MKCoordinateSpan span = MKCoordinateSpanMake(0, 360/pow(2, zoomLevel)*self.frame.size.width/256);
[self setRegion:MKCoordinateRegionMake(centerCoordinate, span) animated:animated];
}
@end
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(NSUInteger)zoomLevel animated:(BOOL)animated { MKCoordinateSpan span = MKCoordinateSpanMake(0, 360/pow(2, zoomLevel)*self.frame.size.width/256); [self setRegion:MKCoordinateRegionMake(centerCoordinate, span) animated:animated]; }
double z = log2(360 * ((self.mapView.frame.size.width/256) / self.mapView.region.span.longitudeDelta));
Nó không được tích hợp sẵn, nhưng tôi đã thấy / sử dụng mã này . Điều này cho phép bạn sử dụng:
[mapView setCenterCoordinate:myCoord zoomLevel:13 animated:YES];
Lưu ý: Đây không phải là mã của tôi, tôi đã không viết nó, vì vậy không thể ghi nhận nó
Bạn cũng có thể thu phóng bằng cách sử dụng MKCoosystemRegion và thiết lập vĩ độ & kinh độ đồng bằng của nó. Dưới đây là tham khảo nhanh và đây là tham chiếu iOS. Nó sẽ không làm bất cứ điều gì lạ mắt nhưng sẽ cho phép bạn đặt thu phóng khi nó vẽ bản đồ.
MKCoordinateRegion region;
region.center.latitude = {desired lat};
region.center.longitude = {desired lng};
region.span.latitudeDelta = 1;
region.span.longitudeDelta = 1;
mapView.region = region;
Chỉnh sửa 1:
MKCoordinateRegion region;
region.center.latitude = {desired lat};
region.center.longitude = {desired lng};
region.span.latitudeDelta = 1;
region.span.longitudeDelta = 1;
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:TRUE];
Một triển khai Swift đơn giản, nếu bạn sử dụng cửa hàng.
@IBOutlet weak var mapView: MKMapView! {
didSet {
let noLocation = CLLocationCoordinate2D()
let viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500)
self.mapView.setRegion(viewRegion, animated: false)
}
}
Dựa trên câu trả lời của @ Carnal.
Triển khai nhanh chóng
import Foundation
import MapKit
class MapViewWithZoom: MKMapView {
var zoomLevel: Int {
get {
return Int(log2(360 * (Double(self.frame.size.width/256) / self.region.span.longitudeDelta)) + 1);
}
set (newZoomLevel){
setCenterCoordinate(coordinate:self.centerCoordinate, zoomLevel: newZoomLevel, animated: false)
}
}
private func setCenterCoordinate(coordinate: CLLocationCoordinate2D, zoomLevel: Int, animated: Bool) {
let span = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 360 / pow(2, Double(zoomLevel)) * Double(self.frame.size.width) / 256)
setRegion(MKCoordinateRegion(center: coordinate, span: span), animated: animated)
}
}
IBOutlet
cho của bạn map
, bạn xác định nó là một MapViewWithZoom
thay vì đơn giản MKMapView
. Sau đó, bạn chỉ có thể thiết lập mức độ zoom với map.zoomLevel = 1
hoặcmap.zoomLevel = 0.5
mapView.zoomLevel -= 2
Đối với Swift 3, nó chuyển tiếp khá nhanh:
private func setMapRegion(for location: CLLocationCoordinate2D, animated: Bool)
{
let viewRegion = MKCoordinateRegionMakeWithDistance(location, <#T##latitudinalMeters: CLLocationDistance##CLLocationDistance#>, <#T##longitudinalMeters: CLLocationDistance##CLLocationDistance#>)
MapView.setRegion(viewRegion, animated: animated)
}
Chỉ cần xác định vĩ độ, Mét dài <CLLocationDistance>
và mapView sẽ điều chỉnh mức thu phóng với giá trị của bạn.
Dựa trên câu trả lời tuyệt vời của @ AdilSoomro . Tôi đã nghĩ ra điều này:
@interface MKMapView (ZoomLevel)
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
zoomLevel:(NSUInteger)zoomLevel
animated:(BOOL)animated;
-(double) getZoomLevel;
@end
@implementation MKMapView (ZoomLevel)
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
zoomLevel:(NSUInteger)zoomLevel animated:(BOOL)animated {
MKCoordinateSpan span = MKCoordinateSpanMake(0, 360/pow(2, zoomLevel)*self.frame.size.width/256);
[self setRegion:MKCoordinateRegionMake(centerCoordinate, span) animated:animated];
}
-(double) getZoomLevel {
return log2(360 * ((self.frame.size.width/256) / self.region.span.longitudeDelta));
}
@end
Tôi hy vọng đoạn mã sau đây sẽ giúp bạn.
- (void)handleZoomOutAction:(id)sender {
MKCoordinateRegion newRegion=MKCoordinateRegionMake(mapView.region.center,MKCoordinateSpanMake(mapView.region.s pan.latitudeDelta/0.5, mapView.region.span.longitudeDelta/0.5));
[mapView setRegion:newRegion];
}
- (void)handleZoomInAction:(id)sender {
MKCoordinateRegion newRegion=MKCoordinateRegionMake(mapView.region.center,MKCoordinateSpanMake(mapView.region.span.latitudeDelta*0.5, mapView.region.span.longitudeDelta*0.5));
[mapView setRegion:newRegion];
}
Bạn có thể chọn bất kỳ giá trị nào thay vì 0,5 để giảm hoặc tăng mức thu phóng. Tôi đã sử dụng các phương pháp này khi nhấp vào hai nút.
Một câu trả lời Swift 2.0 sử dụng NSUserDefaults để lưu và khôi phục độ thu phóng và vị trí của bản đồ.
Chức năng lưu vị trí bản đồ và thu phóng:
func saveMapRegion() {
let mapRegion = [
"latitude" : mapView.region.center.latitude,
"longitude" : mapView.region.center.longitude,
"latitudeDelta" : mapView.region.span.latitudeDelta,
"longitudeDelta" : mapView.region.span.longitudeDelta
]
NSUserDefaults.standardUserDefaults().setObject(mapRegion, forKey: "mapRegion")
}
Chạy chức năng mỗi khi bản đồ được di chuyển:
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool)
{
saveMapRegion();
}
Chức năng lưu phóng to bản đồ và vị trí:
func restoreMapRegion()
{
if let mapRegion = NSUserDefaults.standardUserDefaults().objectForKey("mapRegion")
{
let longitude = mapRegion["longitude"] as! CLLocationDegrees
let latitude = mapRegion["latitude"] as! CLLocationDegrees
let center = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let longitudeDelta = mapRegion["latitudeDelta"] as! CLLocationDegrees
let latitudeDelta = mapRegion["longitudeDelta"] as! CLLocationDegrees
let span = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
let savedRegion = MKCoordinateRegion(center: center, span: span)
self.mapView.setRegion(savedRegion, animated: false)
}
}
Thêm cái này vào viewDidLoad:
restoreMapRegion()
Tôi biết đây là một câu trả lời muộn, nhưng tôi chỉ muốn tự mình giải quyết vấn đề đặt mức thu phóng. Câu trả lời của goldmine rất tuyệt nhưng tôi thấy nó không hoạt động tốt trong ứng dụng của mình.
Khi kiểm tra kỹ hơn, mỏ vàng nói rằng "các đường kinh độ được đặt cách nhau như nhau tại bất kỳ điểm nào trên bản đồ". Điều này không đúng, thực tế là các đường vĩ độ được cách đều nhau từ -90 (cực nam) đến +90 (cực bắc). Các đường kinh độ được đặt cách nhau rộng nhất ở đường xích đạo, hội tụ về một điểm ở hai cực.
Do đó, cách triển khai tôi đã áp dụng là sử dụng cách tính vĩ độ như sau:
@implementation MKMapView (ZoomLevel)
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate
zoomLevel:(NSUInteger)zoom animated:(BOOL)animated
{
MKCoordinateSpan span = MKCoordinateSpanMake(180 / pow(2, zoom) *
self.frame.size.height / 256, 0);
[self setRegion:MKCoordinateRegionMake(coordinate, span) animated:animated];
}
@end
Hy vọng nó sẽ giúp ở giai đoạn cuối này.
Nhanh:
Map.setRegion(MKCoordinateRegion(center: locValue, latitudinalMeters: 200, longitudinalMeters: 200), animated: true)
locValue là tọa độ của bạn.
Ở đây, tôi đã đặt câu trả lời của mình và nó hoạt động cho nhanh chóng 4.2 .
Dựa trên câu trả lời của quentinadam
Swift 5.1
// size refers to the width/height of your tile images, by default is 256.0
// Seems to get better results using round()
// frame.width is the width of the MKMapView
let zoom = round(log2(360 * Double(frame.width) / size / region.span.longitudeDelta))
MKMapView
phần mở rộng dựa trên câu trả lời này (+ độ chính xác của mức thu phóng dấu phẩy động):
import Foundation
import MapKit
extension MKMapView {
var zoomLevel: Double {
get {
return log2(360 * (Double(self.frame.size.width / 256) / self.region.span.longitudeDelta)) + 1
}
set (newZoomLevel){
setCenterCoordinate(coordinate:self.centerCoordinate, zoomLevel: newZoomLevel, animated: false)
}
}
private func setCenterCoordinate(coordinate: CLLocationCoordinate2D, zoomLevel: Double, animated: Bool) {
let span = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 360 / pow(2, zoomLevel) * Double(self.frame.size.width) / 256)
setRegion(MKCoordinateRegion(center: coordinate, span: span), animated: animated)
}
}