mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-19 12:49:02 +00:00
Merge pull request #978 from aaronschubert0/ASMapNode
[ASMapNode] Greatly improve the internal logic of ASMapNode. Also fixes bug #971
This commit is contained in:
commit
c968b8dd9e
@ -12,7 +12,7 @@
|
|||||||
@interface ASMapNode : ASImageNode
|
@interface ASMapNode : ASImageNode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The current region of ASMapNode. This can be set at any time and ASMapNode will animate the change.
|
The current region of ASMapNode. This can be set at any time and ASMapNode will animate the change. This property may be set from a background thread before the node is loaded, and will automatically be applied to define the region of the static snapshot (if .liveMap = NO) or the internal MKMapView (otherwise).
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign) MKCoordinateRegion region;
|
@property (nonatomic, assign) MKCoordinateRegion region;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
@property (nonatomic, readonly) MKMapView *mapView;
|
@property (nonatomic, readonly) MKMapView *mapView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set this to YES to turn the snapshot into an interactive MKMapView and vice versa. Defaults to NO.
|
Set this to YES to turn the snapshot into an interactive MKMapView and vice versa. Defaults to NO. This property may be set on a background thread before the node is loaded, and will automatically be actioned, once the node is loaded.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign, getter=isLiveMap) BOOL liveMap;
|
@property (nonatomic, assign, getter=isLiveMap) BOOL liveMap;
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
@synthesize needsMapReloadOnBoundsChange = _needsMapReloadOnBoundsChange;
|
@synthesize needsMapReloadOnBoundsChange = _needsMapReloadOnBoundsChange;
|
||||||
@synthesize mapDelegate = _mapDelegate;
|
@synthesize mapDelegate = _mapDelegate;
|
||||||
@synthesize region = _region;
|
@synthesize region = _region;
|
||||||
|
@synthesize liveMap = _liveMap;
|
||||||
|
|
||||||
#pragma mark - Lifecycle
|
#pragma mark - Lifecycle
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
@ -37,9 +38,11 @@
|
|||||||
self.clipsToBounds = YES;
|
self.clipsToBounds = YES;
|
||||||
|
|
||||||
_needsMapReloadOnBoundsChange = YES;
|
_needsMapReloadOnBoundsChange = YES;
|
||||||
|
_liveMap = NO;
|
||||||
_centerCoordinateOfMap = kCLLocationCoordinate2DInvalid;
|
_centerCoordinateOfMap = kCLLocationCoordinate2DInvalid;
|
||||||
_region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(43.432858, 13.183671), MKCoordinateSpanMake(0.2, 0.2));
|
|
||||||
|
//Default world-scale view
|
||||||
|
_region = MKCoordinateRegionForMapRect(MKMapRectWorld);
|
||||||
|
|
||||||
_options = [[MKMapSnapshotOptions alloc] init];
|
_options = [[MKMapSnapshotOptions alloc] init];
|
||||||
_options.region = _region;
|
_options.region = _region;
|
||||||
@ -50,26 +53,31 @@
|
|||||||
- (void)didLoad
|
- (void)didLoad
|
||||||
{
|
{
|
||||||
[super didLoad];
|
[super didLoad];
|
||||||
if ([self wasLiveMapPreviously]) {
|
if (self.isLiveMap) {
|
||||||
self.userInteractionEnabled = YES;
|
self.userInteractionEnabled = YES;
|
||||||
[self addLiveMap];
|
[self addLiveMap];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setLayerBacked:(BOOL)layerBacked
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssert(!self.isLiveMap, @"ASMapNode can not be layer backed whilst .liveMap = YES, set .liveMap = NO to use layer backing.");
|
||||||
|
[super setLayerBacked:layerBacked];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)fetchData
|
||||||
{
|
{
|
||||||
[super fetchData];
|
[super fetchData];
|
||||||
if ([self wasLiveMapPreviously]) {
|
if (self.isLiveMap) {
|
||||||
[self addLiveMap];
|
[self addLiveMap];
|
||||||
} else {
|
} else {
|
||||||
[self setUpSnapshotter];
|
|
||||||
[self takeSnapshot];
|
[self takeSnapshot];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)clearContents
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super clearContents];
|
||||||
if (self.isLiveMap) {
|
if (self.isLiveMap) {
|
||||||
[self removeLiveMap];
|
[self removeLiveMap];
|
||||||
}
|
}
|
||||||
@ -79,17 +87,21 @@
|
|||||||
|
|
||||||
- (BOOL)isLiveMap
|
- (BOOL)isLiveMap
|
||||||
{
|
{
|
||||||
return (_mapView != nil);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
return _liveMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setLiveMap:(BOOL)liveMap
|
- (void)setLiveMap:(BOOL)liveMap
|
||||||
{
|
{
|
||||||
liveMap ? [self addLiveMap] : [self removeLiveMap];
|
ASDisplayNodeAssert(!self.isLayerBacked, @"ASMapNode can not use the interactive map feature whilst .isLayerBacked = YES, set .layerBacked = NO to use the interactive map feature.");
|
||||||
}
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
if (liveMap == _liveMap) {
|
||||||
- (BOOL)wasLiveMapPreviously
|
return;
|
||||||
{
|
}
|
||||||
return CLLocationCoordinate2DIsValid(_centerCoordinateOfMap);
|
_liveMap = liveMap;
|
||||||
|
if (self.nodeLoaded) {
|
||||||
|
liveMap ? [self addLiveMap] : [self removeLiveMap];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)needsMapReloadOnBoundsChange
|
- (BOOL)needsMapReloadOnBoundsChange
|
||||||
@ -127,63 +139,62 @@
|
|||||||
|
|
||||||
- (void)takeSnapshot
|
- (void)takeSnapshot
|
||||||
{
|
{
|
||||||
if (!_snapshotter.isLoading) {
|
if (!_snapshotter) {
|
||||||
[_snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
|
[self setUpSnapshotter];
|
||||||
if (!error) {
|
}
|
||||||
UIImage *image = snapshot.image;
|
[_snapshotter cancel];
|
||||||
CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height);
|
[_snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
|
||||||
|
if (!error) {
|
||||||
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
|
UIImage *image = snapshot.image;
|
||||||
[image drawAtPoint:CGPointMake(0, 0)];
|
CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height);
|
||||||
|
|
||||||
if (_annotations.count > 0 ) {
|
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
|
||||||
// Get a standard annotation view pin. Future implementations should use a custom annotation image property.
|
[image drawAtPoint:CGPointMake(0, 0)];
|
||||||
MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""];
|
|
||||||
UIImage *pinImage = pin.image;
|
if (_annotations.count > 0 ) {
|
||||||
for (id<MKAnnotation>annotation in _annotations)
|
// Get a standard annotation view pin. Future implementations should use a custom annotation image property.
|
||||||
|
MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""];
|
||||||
|
UIImage *pinImage = pin.image;
|
||||||
|
for (id<MKAnnotation>annotation in _annotations)
|
||||||
|
{
|
||||||
|
CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
|
||||||
|
if (CGRectContainsPoint(finalImageRect, point))
|
||||||
{
|
{
|
||||||
CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
|
CGPoint pinCenterOffset = pin.centerOffset;
|
||||||
if (CGRectContainsPoint(finalImageRect, point))
|
point.x -= pin.bounds.size.width / 2.0;
|
||||||
{
|
point.y -= pin.bounds.size.height / 2.0;
|
||||||
CGPoint pinCenterOffset = pin.centerOffset;
|
point.x += pinCenterOffset.x;
|
||||||
point.x -= pin.bounds.size.width / 2.0;
|
point.y += pinCenterOffset.y;
|
||||||
point.y -= pin.bounds.size.height / 2.0;
|
[pinImage drawAtPoint:point];
|
||||||
point.x += pinCenterOffset.x;
|
|
||||||
point.y += pinCenterOffset.y;
|
|
||||||
[pinImage drawAtPoint:point];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
||||||
UIGraphicsEndImageContext();
|
|
||||||
self.image = finalImage;
|
|
||||||
}
|
}
|
||||||
}];
|
|
||||||
}
|
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||||
|
UIGraphicsEndImageContext();
|
||||||
|
self.image = finalImage;
|
||||||
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setUpSnapshotter
|
- (void)setUpSnapshotter
|
||||||
{
|
{
|
||||||
if (!_snapshotter) {
|
ASDisplayNodeAssert(!CGSizeEqualToSize(CGSizeZero, self.calculatedSize), @"self.calculatedSize can not be zero. Make sure that you are setting a preferredFrameSize or wrapping ASMapNode in a ASRatioLayoutSpec or similar.");
|
||||||
ASDisplayNodeAssert(!CGSizeEqualToSize(CGSizeZero, self.calculatedSize), @"self.calculatedSize can not be zero. Make sure that you are setting a preferredFrameSize or wrapping ASMapNode in a ASRatioLayoutSpec or similar.");
|
_options.size = self.calculatedSize;
|
||||||
_options.size = self.calculatedSize;
|
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
|
||||||
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resetSnapshotter
|
- (void)resetSnapshotter
|
||||||
{
|
{
|
||||||
if (!_snapshotter.isLoading) {
|
[_snapshotter cancel];
|
||||||
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
|
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
- (void)addLiveMap
|
- (void)addLiveMap
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
if (!self.isLiveMap) {
|
if (!_mapView) {
|
||||||
__weak ASMapNode *weakSelf = self;
|
__weak ASMapNode *weakSelf = self;
|
||||||
_mapView = [[MKMapView alloc] initWithFrame:CGRectZero];
|
_mapView = [[MKMapView alloc] initWithFrame:CGRectZero];
|
||||||
_mapView.delegate = weakSelf.mapDelegate;
|
_mapView.delegate = weakSelf.mapDelegate;
|
||||||
@ -194,8 +205,6 @@
|
|||||||
|
|
||||||
if (CLLocationCoordinate2DIsValid(_centerCoordinateOfMap)) {
|
if (CLLocationCoordinate2DIsValid(_centerCoordinateOfMap)) {
|
||||||
[_mapView setCenterCoordinate:_centerCoordinateOfMap];
|
[_mapView setCenterCoordinate:_centerCoordinateOfMap];
|
||||||
} else {
|
|
||||||
_centerCoordinateOfMap = _options.region.center;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user