diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f0a0b1ff3..1ac85790fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [ASCollectionView] Check if batch fetching is needed if batch fetching parameter has been changed. [#624](https://github.com/TextureGroup/Texture/pull/624) [Garrett Moon](https://github.com/garrettmoon) - [ASNetworkImageNode] New delegate callback to tell the consumer whether the image was loaded from cache or download. [Adlai Holler](https://github.com/Adlai-Holler) - [Layout] Fixes a deadlock in layout. [#638](https://github.com/TextureGroup/Texture/pull/638) [Garrett Moon](https://github.com/garrettmoon) +- Updated to be backwards compatible with Xcode 8. [Adlai Holler](https://github.com/Adlai-Holler) ## 2.6 - [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon) diff --git a/Source/Base/ASAvailability.h b/Source/Base/ASAvailability.h index 64c5a127ea..6a80e274a4 100644 --- a/Source/Base/ASAvailability.h +++ b/Source/Base/ASAvailability.h @@ -31,10 +31,21 @@ #define kCFCoreFoundationVersionNumber_iOS_11_0 1438.10 #endif +#ifndef __IPHONE_11_0 + #define __IPHONE_11_0 110000 +#endif + #define AS_AT_LEAST_IOS9 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0) #define AS_AT_LEAST_IOS10 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_10_0) #define AS_AT_LEAST_IOS11 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_11_0) +// Use __builtin_available if we're on Xcode >= 9, AS_AT_LEAST otherwise. +#if __has_builtin(__builtin_available) + #define AS_AVAILABLE_IOS(ver) __builtin_available(iOS ver, *) +#else + #define AS_AVAILABLE_IOS(ver) AS_AT_LEAST_IOS##ver +#endif + // If Yoga is available, make it available anywhere we use ASAvailability. // This reduces Yoga-specific code in other files. // NOTE: Yoga integration is experimental and not fully tested. Use with caution and test layouts carefully. diff --git a/Source/Details/_ASDisplayView.mm b/Source/Details/_ASDisplayView.mm index 93f3187f6a..2c2d2c383f 100644 --- a/Source/Details/_ASDisplayView.mm +++ b/Source/Details/_ASDisplayView.mm @@ -345,13 +345,11 @@ } } -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. return [node gestureRecognizerShouldBegin:gestureRecognizer]; } -#endif - (void)tintColorDidChange { diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 419901131e..734cf2b7fb 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -84,11 +84,13 @@ static void SortAccessibilityElements(NSMutableArray *elements) accessibilityElement.accessibilityHint = node.accessibilityHint; accessibilityElement.accessibilityValue = node.accessibilityValue; accessibilityElement.accessibilityTraits = node.accessibilityTraits; - if (@available(iOS 11, *)) { - [accessibilityElement setValue:node.accessibilityAttributedLabel forKey:@"accessibilityAttributedLabel"]; - [accessibilityElement setValue:node.accessibilityAttributedHint forKey:@"accessibilityAttributedHint"]; - [accessibilityElement setValue:node.accessibilityAttributedValue forKey:@"accessibilityAttributedValue"]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + if (AS_AVAILABLE_IOS(11)) { + accessibilityElement.accessibilityAttributedLabel = node.accessibilityAttributedLabel; + accessibilityElement.accessibilityAttributedHint = node.accessibilityAttributedHint; + accessibilityElement.accessibilityAttributedValue = node.accessibilityAttributedValue; } +#endif return accessibilityElement; } @@ -176,7 +178,8 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ SortAccessibilityElements(labeledNodes); - if (AS_AT_LEAST_IOS11) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + if (AS_AVAILABLE_IOS(11)) { NSArray *attributedLabels = [labeledNodes valueForKey:@"accessibilityAttributedLabel"]; NSMutableAttributedString *attributedLabel = [NSMutableAttributedString new]; [attributedLabels enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { @@ -185,8 +188,10 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ } [attributedLabel appendAttributedString:(NSAttributedString *)obj]; }]; - [accessiblityElement setValue:attributedLabel forKey:@"accessibilityAttributedLabel"]; - } else { + accessiblityElement.accessibilityAttributedLabel = attributedLabel; + } else +#endif + { NSArray *labels = [labeledNodes valueForKey:@"accessibilityLabel"]; accessiblityElement.accessibilityLabel = [labels componentsJoinedByString:@", "]; } diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 25c0efdf6c..cf07bd7000 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -904,22 +904,19 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo (_view ? _view.viewAndPendingViewStateProperty : nodeProperty )\ : ASDisplayNodeGetPendingState(self).viewAndPendingViewStateProperty -// Attributed version of `_getAccessibilityFromViewOrProperty` macro -#define _getAttributedAccessibilityFromViewOrProperty(nodeProperty, viewAndPendingViewStatePropertyKey) __loaded(self) ? \ -(_view ? (NSAttributedString *)[_view valueForKey: viewAndPendingViewStatePropertyKey] : nodeProperty )\ -: (NSAttributedString *)[ASDisplayNodeGetPendingState(self) valueForKey: viewAndPendingViewStatePropertyKey] - // Helper function to set property values on pending state or view and property if loaded #define _setAccessibilityToViewAndProperty(nodeProperty, nodeValueExpr, viewAndPendingViewStateProperty, viewAndPendingViewStateExpr) \ nodeProperty = nodeValueExpr; _setToViewOnly(viewAndPendingViewStateProperty, viewAndPendingViewStateExpr) -// Attributed version of `_setAccessibilityToViewAndProperty` macro -#define _setAttributedAccessibilityToViewAndProperty(nodeProperty, nodeValueExpr, viewAndPendingViewStatePropertyKey, viewAndPendingViewStateExpr) \ -nodeProperty = nodeValueExpr; BOOL shouldApply = ASDisplayNodeShouldApplyBridgedWriteToView(self); \ -if (shouldApply) { [_view setValue:(viewAndPendingViewStateExpr) forKey: viewAndPendingViewStatePropertyKey]; } else { [ASDisplayNodeGetPendingState(self) setValue:(viewAndPendingViewStateExpr) forKey:viewAndPendingViewStatePropertyKey]; } - @implementation ASDisplayNode (UIViewBridgeAccessibility) +// iOS 11 only properties. Add this to silence "unimplemented selector" warnings +// in old SDKs. If the caller doesn't respect our API_AVAILABLE attributes, then they +// get an appropriate "unrecognized selector" runtime error. +#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0 +@dynamic accessibilityAttributedLabel, accessibilityAttributedHint, accessibilityAttributedValue; +#endif + - (BOOL)isAccessibilityElement { _bridge_prologue_read; @@ -942,24 +939,28 @@ if (shouldApply) { [_view setValue:(viewAndPendingViewStateExpr) forKey: viewAnd { _bridge_prologue_write; _setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityLabel, accessibilityLabel, accessibilityLabel); - if (AS_AT_LEAST_IOS11) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + if (AS_AVAILABLE_IOS(11)) { NSAttributedString *accessibilityAttributedLabel = accessibilityLabel ? [[NSAttributedString alloc] initWithString:accessibilityLabel] : nil; - _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, @"accessibilityAttributedLabel", accessibilityAttributedLabel); + _setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel); } +#endif } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - (NSAttributedString *)accessibilityAttributedLabel { _bridge_prologue_read; - return _getAttributedAccessibilityFromViewOrProperty(_accessibilityAttributedLabel, @"accessibilityAttributedLabel"); + return _getAccessibilityFromViewOrProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel); } - (void)setAccessibilityAttributedLabel:(NSAttributedString *)accessibilityAttributedLabel { _bridge_prologue_write; - { _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, @"accessibilityAttributedLabel", accessibilityAttributedLabel); } + { _setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel); } { _setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityAttributedLabel.string, accessibilityLabel, accessibilityAttributedLabel.string); } } +#endif - (NSString *)accessibilityHint { @@ -971,24 +972,29 @@ if (shouldApply) { [_view setValue:(viewAndPendingViewStateExpr) forKey: viewAnd { _bridge_prologue_write; _setAccessibilityToViewAndProperty(_accessibilityHint, accessibilityHint, accessibilityHint, accessibilityHint); - if (AS_AT_LEAST_IOS11) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + if (AS_AVAILABLE_IOS(11)) { NSAttributedString *accessibilityAttributedHint = accessibilityHint ? [[NSAttributedString alloc] initWithString:accessibilityHint] : nil; - _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, @"accessibilityAttributedHint", accessibilityAttributedHint); + _setAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint); } +#endif } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - (NSAttributedString *)accessibilityAttributedHint { _bridge_prologue_read; - return _getAttributedAccessibilityFromViewOrProperty(_accessibilityAttributedHint, @"accessibilityAttributedHint"); + return _getAccessibilityFromViewOrProperty(_accessibilityAttributedHint, accessibilityAttributedHint); } - (void)setAccessibilityAttributedHint:(NSAttributedString *)accessibilityAttributedHint { _bridge_prologue_write; - { _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, @"accessibilityAttributedHint", accessibilityAttributedHint); } + { _setAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint); } + { _setAccessibilityToViewAndProperty(_accessibilityHint, accessibilityAttributedHint.string, accessibilityHint, accessibilityAttributedHint.string); } } +#endif - (NSString *)accessibilityValue { @@ -1000,24 +1006,28 @@ if (shouldApply) { [_view setValue:(viewAndPendingViewStateExpr) forKey: viewAnd { _bridge_prologue_write; _setAccessibilityToViewAndProperty(_accessibilityValue, accessibilityValue, accessibilityValue, accessibilityValue); - if (AS_AT_LEAST_IOS11) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + if (AS_AVAILABLE_IOS(11)) { NSAttributedString *accessibilityAttributedValue = accessibilityValue ? [[NSAttributedString alloc] initWithString:accessibilityValue] : nil; - _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, @"accessibilityAttributedValue", accessibilityAttributedValue); + _setAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue); } +#endif } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - (NSAttributedString *)accessibilityAttributedValue { _bridge_prologue_read; - return _getAttributedAccessibilityFromViewOrProperty(_accessibilityAttributedValue, @"accessibilityAttributedValue"); + return _getAccessibilityFromViewOrProperty(_accessibilityAttributedValue, accessibilityAttributedValue); } - (void)setAccessibilityAttributedValue:(NSAttributedString *)accessibilityAttributedValue { _bridge_prologue_write; - { _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, @"accessibilityAttributedValue", accessibilityAttributedValue); } + { _setAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue); } { _setAccessibilityToViewAndProperty(_accessibilityValue, accessibilityAttributedValue.string, accessibilityValue, accessibilityAttributedValue.string); } } +#endif - (UIAccessibilityTraits)accessibilityTraits { diff --git a/Source/Private/_ASPendingState.mm b/Source/Private/_ASPendingState.mm index daeb4d6e6d..9bb4dc1a65 100644 --- a/Source/Private/_ASPendingState.mm +++ b/Source/Private/_ASPendingState.mm @@ -1216,11 +1216,13 @@ static BOOL defaultAllowsEdgeAntialiasing = NO; pendingState.accessibilityLabel = view.accessibilityLabel; pendingState.accessibilityHint = view.accessibilityHint; pendingState.accessibilityValue = view.accessibilityValue; - if (@available(iOS 11, *)) { - pendingState.accessibilityAttributedLabel = [view valueForKey: @"accessibilityAttributedLabel"]; - pendingState.accessibilityAttributedHint = [view valueForKey: @"accessibilityAttributedHint"]; - pendingState.accessibilityAttributedValue = [view valueForKey: @"accessibilityAttributedValue"]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + if (AS_AVAILABLE_IOS(11)) { + pendingState.accessibilityAttributedLabel = view.accessibilityAttributedLabel; + pendingState.accessibilityAttributedHint = view.accessibilityAttributedHint; + pendingState.accessibilityAttributedValue = view.accessibilityAttributedValue; } +#endif pendingState.accessibilityTraits = view.accessibilityTraits; pendingState.accessibilityFrame = view.accessibilityFrame; pendingState.accessibilityLanguage = view.accessibilityLanguage;