summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Karlsson <bjorn.fredrik.karlsson@gmail.com>2018-06-13 22:23:39 -0700
committerFredrik Karlsson <bjorn.fredrik.karlsson@gmail.com>2018-06-13 23:09:45 -0700
commit3cd32761a59cc80936a06c0b01d3123b7d43fc85 (patch)
treed061c67d87f752c7d636be3a0a94da7c1416c04a
parentee790818d804c4dda7bc30fe99ffe464bded2435 (diff)
downloadqtlocation-mapboxgl-3cd32761a59cc80936a06c0b01d3123b7d43fc85.tar.gz
[ios] Adopt layout anchors
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj12
-rw-r--r--platform/ios/src/MGLMapView.mm230
-rw-r--r--platform/ios/src/UIView+MGLAdditions.h17
-rw-r--r--platform/ios/src/UIView+MGLAdditions.m37
4 files changed, 78 insertions, 218 deletions
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 2515ece910..d7cb81c882 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -159,6 +159,10 @@
35E208A71D24210F00EC9A46 /* MGLNSDataAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */; };
35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */; };
35E79F211D41266300957B9E /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */; };
+ 35F51A3320D22B02009153CD /* UIView+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35F51A3120D22B02009153CD /* UIView+MGLAdditions.h */; };
+ 35F51A3420D22B02009153CD /* UIView+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35F51A3120D22B02009153CD /* UIView+MGLAdditions.h */; };
+ 35F51A3520D22B02009153CD /* UIView+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 35F51A3220D22B02009153CD /* UIView+MGLAdditions.m */; };
+ 35F51A3620D22B02009153CD /* UIView+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 35F51A3220D22B02009153CD /* UIView+MGLAdditions.m */; };
36F1153D1D46080700878E1A /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 36F1153B1D46080700878E1A /* libmbgl-core.a */; };
3E6465D62065767A00685536 /* LimeGreenStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E6465D42065767A00685536 /* LimeGreenStyleLayer.m */; };
3E8770612074297100B7E842 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; };
@@ -837,6 +841,8 @@
35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLValueEvaluator.h; sourceTree = "<group>"; };
35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNSDataAdditionsTests.m; sourceTree = "<group>"; };
35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer_Private.h; sourceTree = "<group>"; };
+ 35F51A3120D22B02009153CD /* UIView+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+MGLAdditions.h"; sourceTree = "<group>"; };
+ 35F51A3220D22B02009153CD /* UIView+MGLAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIView+MGLAdditions.m"; sourceTree = "<group>"; };
36F1153B1D46080700878E1A /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "build/Debug-iphoneos/libmbgl-core.a"; sourceTree = "<group>"; };
36F1153C1D46080700878E1A /* libmbgl-platform-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-platform-ios.a"; path = "build/Debug-iphoneos/libmbgl-platform-ios.a"; sourceTree = "<group>"; };
3E6465D42065767A00685536 /* LimeGreenStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LimeGreenStyleLayer.m; path = ../../darwin/app/LimeGreenStyleLayer.m; sourceTree = "<group>"; };
@@ -1530,6 +1536,8 @@
30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */,
DD9BE4F51EB263C50079A3AF /* UIViewController+MGLAdditions.h */,
DD9BE4F61EB263C50079A3AF /* UIViewController+MGLAdditions.m */,
+ 35F51A3120D22B02009153CD /* UIView+MGLAdditions.h */,
+ 35F51A3220D22B02009153CD /* UIView+MGLAdditions.m */,
);
name = Categories;
sourceTree = "<group>";
@@ -2218,6 +2226,7 @@
4018B1C91CDC288A00F666AF /* MGLAnnotationView_Private.h in Headers */,
35E1A4D81D74336F007AA97F /* MGLValueEvaluator.h in Headers */,
DA88482C1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h in Headers */,
+ 35F51A3320D22B02009153CD /* UIView+MGLAdditions.h in Headers */,
357FE2DD1E02D2B20068B753 /* NSCoder+MGLAdditions.h in Headers */,
35D13AB71D3D15E300AFB4E0 /* MGLStyleLayer.h in Headers */,
07D947531F67488E00E37934 /* MGLComputedShapeSource_Private.h in Headers */,
@@ -2405,6 +2414,7 @@
AC518E00201BB55A00EBC820 /* MGLTelemetryConfig.h in Headers */,
3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */,
DA72620C1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */,
+ 35F51A3420D22B02009153CD /* UIView+MGLAdditions.h in Headers */,
35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */,
96E516F32000597100A02306 /* NSDictionary+MGLAdditions.h in Headers */,
96E516F02000595800A02306 /* NSBundle+MGLAdditions.h in Headers */,
@@ -3011,6 +3021,7 @@
558DE7A21E5615E400C7916D /* MGLFoundation.mm in Sources */,
40834BE91FE05E1800C1BD0D /* MMECommonEventData.m in Sources */,
3510FFF21D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm in Sources */,
+ 35F51A3520D22B02009153CD /* UIView+MGLAdditions.m in Sources */,
DA88481F1CBAFA6200AB86E3 /* MGLMultiPoint.mm in Sources */,
DA88482B1CBAFA6200AB86E3 /* MGLTypes.m in Sources */,
FA68F14D1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.mm in Sources */,
@@ -3137,6 +3148,7 @@
DAA4E41E1CBB730400178DFB /* MGLMapCamera.mm in Sources */,
FA68F14E1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.mm in Sources */,
1F7454921ECBB42C00021D39 /* MGLLight.mm in Sources */,
+ 35F51A3620D22B02009153CD /* UIView+MGLAdditions.m in Sources */,
404C26E51D89B877000AA13D /* MGLTileSource.mm in Sources */,
355AE0021E9281DA00F3939D /* MGLScaleBar.mm in Sources */,
4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */,
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 7003f2e4b4..c2d3b7cd06 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -54,6 +54,7 @@
#import "NSString+MGLAdditions.h"
#import "NSURL+MGLAdditions.h"
#import "UIImage+MGLAdditions.h"
+#import "UIView+MGLAdditions.h"
#import "UIViewController+MGLAdditions.h"
#import "MGLFaux3DUserLocationAnnotationView.h"
@@ -194,14 +195,10 @@ public:
@property (nonatomic) GLKView *glView;
@property (nonatomic) UIImageView *glSnapshotView;
-@property (nonatomic) NSMutableArray<NSLayoutConstraint *> *scaleBarConstraints;
@property (nonatomic, readwrite) MGLScaleBar *scaleBar;
@property (nonatomic, readwrite) UIImageView *compassView;
-@property (nonatomic) NSMutableArray<NSLayoutConstraint *> *compassViewConstraints;
@property (nonatomic, readwrite) UIImageView *logoView;
-@property (nonatomic) NSMutableArray<NSLayoutConstraint *> *logoViewConstraints;
@property (nonatomic, readwrite) UIButton *attributionButton;
-@property (nonatomic) NSMutableArray<NSLayoutConstraint *> *attributionButtonConstraints;
@property (nonatomic, readwrite) MGLStyle *style;
@@ -453,7 +450,6 @@ public:
_logoView.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"LOGO_A11Y_LABEL", nil, nil, @"Mapbox", @"Accessibility label");
_logoView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_logoView];
- _logoViewConstraints = [NSMutableArray array];
// setup attribution
//
@@ -463,7 +459,6 @@ public:
[_attributionButton addTarget:self action:@selector(showAttribution:) forControlEvents:UIControlEventTouchUpInside];
_attributionButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_attributionButton];
- _attributionButtonConstraints = [NSMutableArray array];
[_attributionButton addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:NULL];
UILongPressGestureRecognizer *attributionLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(showAttribution:)];
@@ -480,14 +475,12 @@ public:
_compassView.accessibilityHint = NSLocalizedStringWithDefaultValue(@"COMPASS_A11Y_HINT", nil, nil, @"Rotates the map to face due north", @"Accessibility hint");
_compassView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_compassView];
- _compassViewConstraints = [NSMutableArray array];
// setup scale control
//
_scaleBar = [[MGLScaleBar alloc] init];
_scaleBar.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_scaleBar];
- _scaleBarConstraints = [NSMutableArray array];
// setup interaction
//
@@ -575,6 +568,8 @@ public:
[MGLMapboxEvents pushTurnstileEvent];
[MGLMapboxEvents pushEvent:MMEEventTypeMapLoad withAttributes:@{}];
}
+
+ [self setupConstraints];
}
- (mbgl::Size)size
@@ -682,18 +677,6 @@ public:
{
[EAGLContext setCurrentContext:nil];
}
-
- [self.compassViewConstraints removeAllObjects];
- self.compassViewConstraints = nil;
-
- [self.scaleBarConstraints removeAllObjects];
- self.scaleBarConstraints = nil;
-
- [self.logoViewConstraints removeAllObjects];
- self.logoViewConstraints = nil;
-
- [self.attributionButtonConstraints removeAllObjects];
- self.attributionButtonConstraints = nil;
}
- (void)setDelegate:(nullable id<MGLMapViewDelegate>)delegate
@@ -740,204 +723,18 @@ public:
return nil;
}
-- (void)updateConstraintsPreiOS11 {
- // If we have a view controller reference and its automaticallyAdjustsScrollViewInsets
- // is set to YES, use its view as the parent for constraints. -[MGLMapView adjustContentInset]
- // already take top and bottom layout guides into account. If we don't have a reference, apply
- // constraints against ourself to maintain placement of the subviews.
- //
- UIViewController *viewController = self.viewControllerForLayoutGuides;
- BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets;
- UIView *containerView = useLayoutGuides ? viewController.view : self;
-
- // compass view
- //
- [containerView removeConstraints:self.compassViewConstraints];
- [self.compassViewConstraints removeAllObjects];
-
- if (useLayoutGuides) {
- [self.compassViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.compassView
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:viewController.topLayoutGuide
- attribute:NSLayoutAttributeBottom
- multiplier:1.0
- constant:8.0]];
- }
- [self.compassViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.compassView
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:self
- attribute:NSLayoutAttributeTop
- multiplier:1.0
- constant:8.0 + self.contentInset.top]];
-
- [self.compassViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeTrailing
- relatedBy:NSLayoutRelationEqual
- toItem:self.compassView
- attribute:NSLayoutAttributeTrailing
- multiplier:1.0
- constant:8.0 + self.contentInset.right]];
-
- [containerView addConstraints:self.compassViewConstraints];
-
- // scale bar view
- //
- [containerView removeConstraints:self.scaleBarConstraints];
- [self.scaleBarConstraints removeAllObjects];
-
- if (useLayoutGuides) {
- [self.scaleBarConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.scaleBar
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:viewController.topLayoutGuide
- attribute:NSLayoutAttributeBottom
- multiplier:1.0
- constant:8.0]];
- }
- [self.scaleBarConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.scaleBar
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:self
- attribute:NSLayoutAttributeTop
- multiplier:1.0
- constant:8.0 + self.contentInset.top]];
- [self.scaleBarConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.scaleBar
- attribute:NSLayoutAttributeLeft
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeLeft
- multiplier:1.0
- constant:8.0 + self.contentInset.left]];
-
- [containerView addConstraints:self.scaleBarConstraints];
-
- // logo view
- //
- [containerView removeConstraints:self.logoViewConstraints];
- [self.logoViewConstraints removeAllObjects];
-
- if (useLayoutGuides) {
- [self.logoViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:viewController.bottomLayoutGuide
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:self.logoView
- attribute:NSLayoutAttributeBaseline
- multiplier:1.0
- constant:8.0 + self.contentInset.bottom]];
- }
- [self.logoViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:self.logoView
- attribute:NSLayoutAttributeBaseline
- multiplier:1
- constant:8.0 + self.contentInset.bottom]];
- [self.logoViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.logoView
- attribute:NSLayoutAttributeLeading
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeLeading
- multiplier:1.0
- constant:8.0 + self.contentInset.left]];
- [containerView addConstraints:self.logoViewConstraints];
+- (void)setupConstraints {
+ [[self.scaleBar.topAnchor constraintEqualToAnchor:self.safeTopAnchor constant:8] setActive:YES];
+ [[self.scaleBar.leadingAnchor constraintEqualToAnchor:self.safeLeadingAnchor constant:8] setActive:YES];
- // attribution button
- //
- [containerView removeConstraints:self.attributionButtonConstraints];
- [self.attributionButtonConstraints removeAllObjects];
-
- if (useLayoutGuides) {
- [self.attributionButtonConstraints addObject:
- [NSLayoutConstraint constraintWithItem:viewController.bottomLayoutGuide
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:self.attributionButton
- attribute:NSLayoutAttributeBaseline
- multiplier:1
- constant:8.0 + self.contentInset.bottom]];
- }
- [self.attributionButtonConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationGreaterThanOrEqual
- toItem:self.attributionButton
- attribute:NSLayoutAttributeBaseline
- multiplier:1
- constant:8.0 + self.contentInset.bottom]];
+ [[self.compassView.topAnchor constraintEqualToAnchor:self.safeTopAnchor constant:8] setActive:YES];
+ [[self.compassView.trailingAnchor constraintEqualToAnchor:self.safeTrailingAnchor constant:-8] setActive:YES];
- [self.attributionButtonConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeTrailing
- relatedBy:NSLayoutRelationEqual
- toItem:self.attributionButton
- attribute:NSLayoutAttributeTrailing
- multiplier:1
- constant:8.0 + self.contentInset.right]];
- [containerView addConstraints:self.attributionButtonConstraints];
-}
-
-- (void)updateConstraints
-{
- // If safeAreaLayoutGuide API exists
- if (@available(iOS 11.0, *)) {
- UILayoutGuide *safeAreaLayoutGuide = self.safeAreaLayoutGuide;
-
- // compass view
- [self removeConstraints:self.compassViewConstraints];
- [self.compassViewConstraints removeAllObjects];
- [self.compassViewConstraints addObject:[self constraintForYAxisAnchor:self.compassView.topAnchor belowAnchor:safeAreaLayoutGuide.topAnchor]];
- [self.compassViewConstraints addObject:[safeAreaLayoutGuide.rightAnchor constraintEqualToAnchor:self.compassView.rightAnchor
- constant:8.0 + self.contentInset.right]];
- [self addConstraints:self.compassViewConstraints];
-
- // scale bar view
- [self removeConstraints:self.scaleBarConstraints];
- [self.scaleBarConstraints removeAllObjects];
- [self.scaleBarConstraints addObject:[self constraintForYAxisAnchor:self.scaleBar.topAnchor belowAnchor:safeAreaLayoutGuide.topAnchor]];
- [self.scaleBarConstraints addObject:[self.scaleBar.leftAnchor constraintEqualToAnchor:safeAreaLayoutGuide.leftAnchor
- constant:8.0 + self.contentInset.left]];
- [self addConstraints:self.scaleBarConstraints];
-
- // logo view
- [self removeConstraints:self.logoViewConstraints];
- [self.logoViewConstraints removeAllObjects];
- [self.logoViewConstraints addObject:[self constraintForYAxisAnchor:safeAreaLayoutGuide.bottomAnchor belowAnchor:self.logoView.bottomAnchor]];
- [self.logoViewConstraints addObject:[self.logoView.leftAnchor constraintEqualToAnchor:safeAreaLayoutGuide.leftAnchor
- constant:8.0 + self.contentInset.left]];
- [self addConstraints:self.logoViewConstraints];
-
- // attribution button
- [self removeConstraints:self.attributionButtonConstraints];
- [self.attributionButtonConstraints removeAllObjects];
- [self.attributionButtonConstraints addObject:[self constraintForYAxisAnchor:safeAreaLayoutGuide.bottomAnchor belowAnchor:self.attributionButton.bottomAnchor]];
- [self.attributionButtonConstraints addObject:[safeAreaLayoutGuide.rightAnchor constraintEqualToAnchor:self.attributionButton.rightAnchor
- constant:8.0 + self.contentInset.right]];
- [self addConstraints:self.attributionButtonConstraints];
- } else {
- [self updateConstraintsPreiOS11];
- }
+ [[self.attributionButton.bottomAnchor constraintEqualToAnchor:self.safeBottomAnchor constant:-8] setActive:YES];
+ [[self.attributionButton.trailingAnchor constraintEqualToAnchor:self.safeTrailingAnchor constant:-8] setActive:YES];
- [super updateConstraints];
-}
-
-- (NSLayoutConstraint *)constraintForYAxisAnchor:(NSLayoutYAxisAnchor *)yAxisAnchor belowAnchor:(NSLayoutYAxisAnchor *)anchor
-{
- if (@available(iOS 11.0, *)) {
- return [yAxisAnchor constraintEqualToSystemSpacingBelowAnchor:anchor multiplier:1];
- } else {
- return nil;
- }
+ [[self.logoView.leadingAnchor constraintEqualToAnchor:self.safeLeadingAnchor constant:8] setActive:YES];
+ [[self.logoView.bottomAnchor constraintEqualToAnchor:self.safeBottomAnchor constant:-8] setActive:YES];
}
- (BOOL)isOpaque
@@ -1060,9 +857,6 @@ public:
{
[self didUpdateLocationWithUserTrackingAnimated:animated];
}
-
- // Compass, logo and attribution button constraints needs to be updated.
- [self setNeedsUpdateConstraints];
}
/// Returns the frame of inset content within the map view.
diff --git a/platform/ios/src/UIView+MGLAdditions.h b/platform/ios/src/UIView+MGLAdditions.h
new file mode 100644
index 0000000000..f3d0674fd7
--- /dev/null
+++ b/platform/ios/src/UIView+MGLAdditions.h
@@ -0,0 +1,17 @@
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UIView (MGLAdditions)
+
+- (NSLayoutYAxisAnchor *)safeTopAnchor;
+
+- (NSLayoutXAxisAnchor *)safeLeadingAnchor;
+
+- (NSLayoutYAxisAnchor *)safeBottomAnchor;
+
+- (NSLayoutXAxisAnchor *)safeTrailingAnchor;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/ios/src/UIView+MGLAdditions.m b/platform/ios/src/UIView+MGLAdditions.m
new file mode 100644
index 0000000000..041ce0ce89
--- /dev/null
+++ b/platform/ios/src/UIView+MGLAdditions.m
@@ -0,0 +1,37 @@
+#import "UIView+MGLAdditions.h"
+
+@implementation UIView (MGLAdditions)
+
+- (NSLayoutYAxisAnchor *)safeTopAnchor {
+ if (@available(iOS 11.0, *)) {
+ return self.safeAreaLayoutGuide.topAnchor;
+ } else {
+ return self.topAnchor;
+ }
+}
+
+- (NSLayoutXAxisAnchor *)safeLeadingAnchor {
+ if (@available(iOS 11.0, *)) {
+ return self.safeAreaLayoutGuide.leadingAnchor;
+ } else {
+ return self.leadingAnchor;
+ }
+}
+
+- (NSLayoutYAxisAnchor *)safeBottomAnchor {
+ if (@available(iOS 11.0, *)) {
+ return self.safeAreaLayoutGuide.bottomAnchor;
+ } else {
+ return self.bottomAnchor;
+ }
+}
+
+- (NSLayoutXAxisAnchor *)safeTrailingAnchor {
+ if (@available(iOS 11.0, *)) {
+ return self.safeAreaLayoutGuide.trailingAnchor;
+ } else {
+ return self.trailingAnchor;
+ }
+}
+
+@end