diff options
author | Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com> | 2018-06-13 22:23:39 -0700 |
---|---|---|
committer | Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com> | 2018-06-13 23:09:45 -0700 |
commit | 3cd32761a59cc80936a06c0b01d3123b7d43fc85 (patch) | |
tree | d061c67d87f752c7d636be3a0a94da7c1416c04a | |
parent | ee790818d804c4dda7bc30fe99ffe464bded2435 (diff) | |
download | qtlocation-mapboxgl-3cd32761a59cc80936a06c0b01d3123b7d43fc85.tar.gz |
[ios] Adopt layout anchors
-rw-r--r-- | platform/ios/ios.xcodeproj/project.pbxproj | 12 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 230 | ||||
-rw-r--r-- | platform/ios/src/UIView+MGLAdditions.h | 17 | ||||
-rw-r--r-- | platform/ios/src/UIView+MGLAdditions.m | 37 |
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 |