diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 75c06532d..f9ed77041 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -242,7 +242,8 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; _glView.contentMode = UIViewContentModeCenter; - [self setBackgroundColor:[UIColor clearColor]]; + self.backgroundColor = [UIColor clearColor]; + self.clipsToBounds = YES; // load extensions // @@ -293,9 +294,9 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // setup logo bug // - _logoBug = [[UIImageView alloc] initWithImage:[MGLMapView resourceImageNamed:@"mapbox.png"]]; + UIImage *logo = [[MGLMapView resourceImageNamed:@"mapbox.png"] imageWithAlignmentRectInsets:UIEdgeInsetsMake(1.5, 4, 3.5, 2)]; + _logoBug = [[UIImageView alloc] initWithImage:logo]; _logoBug.accessibilityLabel = @"Mapbox logo"; - _logoBug.frame = CGRectMake(8, self.bounds.size.height - _logoBug.bounds.size.height - 4, _logoBug.bounds.size.width, _logoBug.bounds.size.height); _logoBug.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_logoBug]; @@ -304,7 +305,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; _attributionButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; _attributionButton.accessibilityLabel = @"Attribution info"; [_attributionButton addTarget:self action:@selector(showAttribution:) forControlEvents:UIControlEventTouchUpInside]; - _attributionButton.frame = CGRectMake(self.bounds.size.width - _attributionButton.bounds.size.width - 8, self.bounds.size.height - _attributionButton.bounds.size.height - 8, _attributionButton.bounds.size.width, _attributionButton.bounds.size.height); _attributionButton.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_attributionButton]; @@ -315,7 +315,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; UIImage *compassImage = [MGLMapView resourceImageNamed:@"Compass.png"]; _compass.frame = CGRectMake(0, 0, compassImage.size.width, compassImage.size.height); _compass.alpha = 0; - UIView *container = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.size.width - compassImage.size.width - 5, 5, compassImage.size.width, compassImage.size.height)]; + UIView *container = [[UIView alloc] initWithFrame:CGRectZero]; [container addSubview:_compass]; container.translatesAutoresizingMaskIntoConstraints = NO; [container addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleCompassTapGesture:)]]; @@ -491,70 +491,122 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // views so they don't underlap navigation or tool bars. If we don't have a reference, apply // constraints against ourself to maintain (albeit less ideal) placement of the subviews. // - NSString *topGuideFormatString = (self.viewControllerForLayoutGuides ? @"[topLayoutGuide]" : @"|"); - NSString *bottomGuideFormatString = (self.viewControllerForLayoutGuides ? @"[bottomLayoutGuide]" : @"|"); - - id topGuideViewsObject = (self.viewControllerForLayoutGuides ? (id)self.viewControllerForLayoutGuides.topLayoutGuide : (id)@""); - id bottomGuideViewsObject = (self.viewControllerForLayoutGuides ? (id)self.viewControllerForLayoutGuides.bottomLayoutGuide : (id)@""); - - UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? self.viewControllerForLayoutGuides.view : self); + UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? + self.viewControllerForLayoutGuides.view : + self); // compass // UIView *compassContainer = self.compass.superview; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:%@-topSpacing-[container]", topGuideFormatString] - options:0 - metrics:@{ @"topSpacing" : @(5) } - views:@{ @"topLayoutGuide" : topGuideViewsObject, - @"container" : compassContainer }]]; + if (self.viewControllerForLayoutGuides) + { + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.viewControllerForLayoutGuides.topLayoutGuide + attribute:NSLayoutAttributeBottom + multiplier:1 + constant:5]]; + } + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self + attribute:NSLayoutAttributeTop + multiplier:1 + constant:5]]; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[container]-rightSpacing-|" - options:0 - metrics:@{ @"rightSpacing" : @(5) } - views:@{ @"container" : compassContainer }]]; + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:compassContainer + attribute:NSLayoutAttributeTrailing + multiplier:1 + constant:5]]; - [compassContainer addConstraint:[NSLayoutConstraint constraintWithItem:compassContainer - attribute:NSLayoutAttributeWidth - relatedBy:NSLayoutRelationEqual - toItem:nil - attribute:NSLayoutAttributeNotAnAttribute - multiplier:1 - constant:self.compass.image.size.width]]; + [compassContainer addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1 + constant:self.compass.image.size.width]]; - [compassContainer addConstraint:[NSLayoutConstraint constraintWithItem:compassContainer - attribute:NSLayoutAttributeHeight - relatedBy:NSLayoutRelationEqual - toItem:nil - attribute:NSLayoutAttributeNotAnAttribute - multiplier:1 - constant:self.compass.image.size.height]]; + [compassContainer addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeHeight + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1 + constant:self.compass.image.size.height]]; // logo bug // - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[logoBug]-bottomSpacing-%@", bottomGuideFormatString] - options:0 - metrics:@{ @"bottomSpacing" : @(4) } - views:@{ @"logoBug" : self.logoBug, - @"bottomLayoutGuide" : bottomGuideViewsObject }]]; + if (self.viewControllerForLayoutGuides) + { + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.logoBug + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:8]]; + } + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.logoBug + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:8]]; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-leftSpacing-[logoBug]" - options:0 - metrics:@{ @"leftSpacing" : @(8) } - views:@{ @"logoBug" : self.logoBug }]]; + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self.logoBug + attribute:NSLayoutAttributeLeading + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeLeading + multiplier:1 + constant:8]]; // attribution button // - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[attributionButton]-bottomSpacing-%@", bottomGuideFormatString] - options:0 - metrics:@{ @"bottomSpacing" : @(8) } - views:@{ @"attributionButton" : self.attributionButton, - @"bottomLayoutGuide" : bottomGuideViewsObject }]]; + if (self.viewControllerForLayoutGuides) + { + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.attributionButton + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:8]]; + } + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.attributionButton + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:8]]; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[attributionButton]-rightSpacing-|" - options:0 - metrics:@{ @"rightSpacing" : @(8) } - views:@{ @"attributionButton" : self.attributionButton }]]; + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:self.attributionButton + attribute:NSLayoutAttributeTrailing + multiplier:1 + constant:8]]; [super updateConstraints]; } diff --git a/platform/ios/MGLUserLocationAnnotationView.m b/platform/ios/MGLUserLocationAnnotationView.m index 779382b5e..c130582d6 100644 --- a/platform/ios/MGLUserLocationAnnotationView.m +++ b/platform/ios/MGLUserLocationAnnotationView.m @@ -30,6 +30,7 @@ const CGFloat MGLTrackingDotRingWidth = 24.0; self.annotation.mapView = mapView; _mapView = mapView; [self setupLayers]; + self.accessibilityLabel = @"User location"; } return self; } diff --git a/test/ios/KIFTestActor+MapboxGL.h b/test/ios/KIFTestActor+MapboxGL.h index df83b2377..d16e34848 100644 --- a/test/ios/KIFTestActor+MapboxGL.h +++ b/test/ios/KIFTestActor+MapboxGL.h @@ -1,12 +1,12 @@ #import #import -@class MGLMapView; +@class MGLTViewController, MGLMapView; @interface KIFTestActor (MapboxGL) @property (nonatomic, readonly) UIWindow *window; -@property (nonatomic, readonly) UIViewController *viewController; +@property (nonatomic, readonly) MGLTViewController *viewController; @property (nonatomic, readonly) MGLMapView *mapView; @property (nonatomic, readonly) UIView *compass; diff --git a/test/ios/KIFTestActor+MapboxGL.m b/test/ios/KIFTestActor+MapboxGL.m index ef40c1bed..330adfdc2 100644 --- a/test/ios/KIFTestActor+MapboxGL.m +++ b/test/ios/KIFTestActor+MapboxGL.m @@ -10,8 +10,8 @@ return [[UIApplication sharedApplication] statusBarWindow]; } -- (UIViewController *)viewController { - return (UIViewController *)[[tester.mapView nextResponder] nextResponder]; +- (MGLTViewController *)viewController { + return (MGLTViewController *)[[tester.mapView nextResponder] nextResponder]; } - (MGLMapView *)mapView { diff --git a/test/ios/MGLTViewController.h b/test/ios/MGLTViewController.h index 39df59bb5..0be0e1ff2 100644 --- a/test/ios/MGLTViewController.h +++ b/test/ios/MGLTViewController.h @@ -2,4 +2,7 @@ @interface MGLTViewController : UIViewController +- (void)insetMapView; +- (void)resetMapView; + @end diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m index e839c4504..e8b500b43 100644 --- a/test/ios/MGLTViewController.m +++ b/test/ios/MGLTViewController.m @@ -2,17 +2,30 @@ #import "MapboxGL.h" @implementation MGLTViewController +{ + MGLMapView *_mapView; +} - (void)viewDidLoad { [super viewDidLoad]; - MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds + _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:@"pk.eyJ1IjoianVzdGluIiwiYSI6Ik9RX3RRQzAifQ.dmOg_BAp1ywuDZMM7YsXRg"]; - mapView.viewControllerForLayoutGuides = self; - mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _mapView.viewControllerForLayoutGuides = self; + _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self.view addSubview:mapView]; + [self.view addSubview:_mapView]; +} + +- (void)insetMapView +{ + _mapView.frame = CGRectInset(_mapView.frame, 50, 50); +} + +- (void)resetMapView +{ + _mapView.frame = self.view.bounds; } @end diff --git a/test/ios/MapViewTests.m b/test/ios/MapViewTests.m index deed521b7..fff52adc0 100644 --- a/test/ios/MapViewTests.m +++ b/test/ios/MapViewTests.m @@ -4,6 +4,7 @@ #import "KIFTestActor+MapboxGL.h" #import "MapboxGL.h" +#import "MGLTViewController.h" @interface MapViewTests : KIFTestCase @@ -13,6 +14,7 @@ - (void)beforeEach { [system simulateDeviceRotationToOrientation:UIDeviceOrientationPortrait]; + [tester.viewController resetMapView]; tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.913175, -77.032458); tester.mapView.zoomLevel = 14; @@ -297,6 +299,28 @@ @"rotated device should not have attribution button under toolbar"); } +- (void)testInsetMapView { + [tester.viewController insetMapView]; + [tester waitForAnimationsToFinish]; + + UIView *logoBug = (UIView *)[tester waitForViewWithAccessibilityLabel:@"Mapbox logo"]; + UIView *attributionButton = (UIView *)[tester waitForViewWithAccessibilityLabel:@"Attribution info"]; + + CGRect mapViewFrame = [tester.mapView.superview convertRect:tester.mapView.frame toView:nil]; + + CGRect logoBugFrame = [logoBug.superview convertRect:logoBug.frame toView:nil]; + XCTAssertTrue(CGRectIntersectsRect(logoBugFrame, mapViewFrame), + @"logo bug should lie inside shrunken map view"); + + CGRect attributionButtonFrame = [attributionButton.superview convertRect:attributionButton.frame toView:nil]; + XCTAssertTrue(CGRectIntersectsRect(attributionButtonFrame, mapViewFrame), + @"attribution button should lie inside shrunken map view"); + + CGRect compassFrame = [tester.compass.superview convertRect:tester.compass.frame toView:nil]; + XCTAssertTrue(CGRectIntersectsRect(compassFrame, mapViewFrame), + @"compass should lie inside shrunken map view"); +} + - (void)testDelegateRegionWillChange { __block NSUInteger unanimatedCount; __block NSUInteger animatedCount;