diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 19771c9ea4..06db270dcc 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -134,9 +134,7 @@ 690C35621E055C5D00069B91 /* ASDimensionInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 690C35601E055C5D00069B91 /* ASDimensionInternal.mm */; }; 690C35641E055C7B00069B91 /* ASDimensionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 690C35631E055C7B00069B91 /* ASDimensionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; 690ED58E1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 690ED5961E36D118000627C0 /* ASControlNode+tvOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 690ED5921E36D118000627C0 /* ASControlNode+tvOS.h */; settings = {ATTRIBUTES = (Private, ); }; }; 690ED5981E36D118000627C0 /* ASControlNode+tvOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */; }; - 690ED5991E36D118000627C0 /* ASImageNode+tvOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 690ED5941E36D118000627C0 /* ASImageNode+tvOS.h */; settings = {ATTRIBUTES = (Private, ); }; }; 690ED59B1E36D118000627C0 /* ASImageNode+tvOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */; }; 692510141E74FB44003F2DD0 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 692510131E74FB44003F2DD0 /* Default-568h@2x.png */; }; 692BE8D71E36B65B00C86D87 /* ASLayoutSpecPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 692BE8D61E36B65B00C86D87 /* ASLayoutSpecPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -475,6 +473,7 @@ E5E2D72E1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; E5E2D7301EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */; }; F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */; }; + FA4FAF15200A850200E735BD /* ASControlNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4FAF14200A850200E735BD /* ASControlNode+Private.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -670,9 +669,7 @@ 690C35601E055C5D00069B91 /* ASDimensionInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDimensionInternal.mm; sourceTree = ""; }; 690C35631E055C7B00069B91 /* ASDimensionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDimensionInternal.h; sourceTree = ""; }; 690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementStylePrivate.h; sourceTree = ""; }; - 690ED5921E36D118000627C0 /* ASControlNode+tvOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+tvOS.h"; sourceTree = ""; }; 690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASControlNode+tvOS.m"; sourceTree = ""; }; - 690ED5941E36D118000627C0 /* ASImageNode+tvOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+tvOS.h"; sourceTree = ""; }; 690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASImageNode+tvOS.m"; sourceTree = ""; }; 692510131E74FB44003F2DD0 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 692BE8D61E36B65B00C86D87 /* ASLayoutSpecPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecPrivate.h; sourceTree = ""; }; @@ -982,6 +979,7 @@ E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionGalleryLayoutDelegate.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeExtrasTests.m; sourceTree = ""; }; + FA4FAF14200A850200E735BD /* ASControlNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Private.h"; sourceTree = ""; }; FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1424,6 +1422,7 @@ CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */, CC0F885A1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.h */, CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.m */, + FA4FAF14200A850200E735BD /* ASControlNode+Private.h */, 9F98C0231DBDF2A300476D92 /* ASControlTargetAction.h */, 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.m */, 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */, @@ -1531,9 +1530,7 @@ 690ED5911E36D118000627C0 /* tvOS */ = { isa = PBXGroup; children = ( - 690ED5921E36D118000627C0 /* ASControlNode+tvOS.h */, 690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */, - 690ED5941E36D118000627C0 /* ASImageNode+tvOS.h */, 690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */, ); path = tvOS; @@ -1887,6 +1884,7 @@ 9C70F20F1CDBE9FF007D6C76 /* ASLayoutManager.h in Headers */, 6947B0C31E36B5040007C478 /* ASStackPositionedLayout.h in Headers */, DBABFAFC1C6A8D2F0039EA4A /* _ASTransitionContext.h in Headers */, + FA4FAF15200A850200E735BD /* ASControlNode+Private.h in Headers */, B350624F1B010EFD0018CF92 /* ASDisplayNode+DebugTiming.h in Headers */, CC57EAF71E3939350034C595 /* ASCollectionView+Undeprecated.h in Headers */, B35062521B010EFD0018CF92 /* ASDisplayNodeInternal.h in Headers */, @@ -1902,14 +1900,12 @@ DEC146B71C37A16A004A0EE7 /* ASCollectionInternal.h in Headers */, 68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */, 9F98C0271DBE29FC00476D92 /* ASControlTargetAction.h in Headers */, - 690ED5961E36D118000627C0 /* ASControlNode+tvOS.h in Headers */, 695943401D70815300B0EE1F /* ASDisplayNodeLayout.h in Headers */, 0442850E1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.h in Headers */, DE8BEAC21C2DF3FC00D57C12 /* ASDelegateProxy.h in Headers */, B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */, AC6145411D8AFAE8003D62A2 /* ASSection.h in Headers */, 8BBBAB8C1CEBAF1700107FC6 /* ASDefaultPlaybackButton.h in Headers */, - 690ED5991E36D118000627C0 /* ASImageNode+tvOS.h in Headers */, 254C6B741BF94DF4003EC431 /* ASTextNodeWordKerner.h in Headers */, 698DFF441E36B6C9002891F1 /* ASStackLayoutSpecUtilities.h in Headers */, CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */, diff --git a/CHANGELOG.md b/CHANGELOG.md index 60ab5ecd9d..4666231476 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [tvOS] Fixes errors when building against tvOS SDK [Alex Hill](https://github.com/alexhillc) [#728](https://github.com/TextureGroup/Texture/pull/728) - [ASDisplayNode] Add unit tests for layout z-order changes (with an open issue to fix). - [ASDisplayNode] Consolidate main thread initialization and allow apps to invoke it manually instead of +load. - [ASRunloopQueue] Introduce new runloop queue(ASCATransactionQueue) to coalesce Interface state update calls for view controller transitions. diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index 10dd6dc9a5..451322564b 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -275,7 +275,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier"; // Experiments done by Instagram show that this option being YES (default) // when unused causes a significant hit to scroll performance. // https://github.com/Instagram/IGListKit/issues/318 - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { super.prefetchingEnabled = NO; } diff --git a/Source/ASControlNode.h b/Source/ASControlNode.h index e08f0650f3..7896b93eb7 100644 --- a/Source/ASControlNode.h +++ b/Source/ASControlNode.h @@ -141,12 +141,17 @@ static UIControlState const ASControlStateSelected ASDISPLAYNODE_DEPRECATED_MSG( @param event The event which triggered these control actions. May be nil. */ - (void)sendActionsForControlEvents:(ASControlNodeEvent)controlEvents withEvent:(nullable UIEvent *)event; +@end + #if TARGET_OS_TV +@interface ASControlNode (tvOS) + /** @abstract How the node looks when it isn't focused. Exposed here so that subclasses can override. */ - (void)setDefaultFocusAppearance; -#endif + @end +#endif NS_ASSUME_NONNULL_END diff --git a/Source/ASControlNode.mm b/Source/ASControlNode.mm index fdd1155e7a..702161721e 100644 --- a/Source/ASControlNode.mm +++ b/Source/ASControlNode.mm @@ -16,6 +16,7 @@ // #import +#import #import #import #import @@ -103,10 +104,12 @@ CGRect _ASControlNodeGetExpandedBounds(ASControlNode *controlNode); #if TARGET_OS_TV - (void)didLoad { + [super didLoad]; + // On tvOS all controls, such as buttons, interact with the focus system even if they don't have a target set on them. // Here we add our own internal tap gesture to handle this behaviour. self.userInteractionEnabled = YES; - UITapGestureRecognizer *tapGestureRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pressDown)]; + UITapGestureRecognizer *tapGestureRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_pressDown)]; tapGestureRec.allowedPressTypes = @[@(UIPressTypeSelect)]; [self.view addGestureRecognizer:tapGestureRec]; } diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 1128383f5b..26b8f91d84 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -3601,40 +3601,6 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { { // Subclass override } - -#if TARGET_OS_TV -#pragma mark - UIFocusEnvironment Protocol (tvOS) - -- (void)setNeedsFocusUpdate -{ - -} - -- (void)updateFocusIfNeeded -{ - -} - -- (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context -{ - return NO; -} - -- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator -{ - -} - -- (UIView *)preferredFocusedView -{ - if (self.nodeLoaded) { - return self.view; - } else { - return nil; - } -} -#endif - @end #pragma mark - ASDisplayNode (Debugging) diff --git a/Source/ASImageNode+AnimatedImage.mm b/Source/ASImageNode+AnimatedImage.mm index 246ee49cc2..a9ef4d33ff 100644 --- a/Source/ASImageNode+AnimatedImage.mm +++ b/Source/ASImageNode+AnimatedImage.mm @@ -322,7 +322,7 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes; CFTimeInterval timeBetweenLastFire; if (self.lastDisplayLinkFire == 0) { timeBetweenLastFire = 0; - } else if (AS_AVAILABLE_IOS(10)){ + } else if (AS_AVAILABLE_IOS_TVOS(10, 10)) { timeBetweenLastFire = displayLink.targetTimestamp - displayLink.timestamp; } else { timeBetweenLastFire = CACurrentMediaTime() - self.lastDisplayLinkFire; diff --git a/Source/ASImageNode.h b/Source/ASImageNode.h index 547044c7d2..99ef575490 100644 --- a/Source/ASImageNode.h +++ b/Source/ASImageNode.h @@ -141,6 +141,11 @@ typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image); @end +#if TARGET_OS_TV +@interface ASImageNode (tvOS) +@end +#endif + @interface ASImageNode (AnimatedImage) /** diff --git a/Source/ASMultiplexImageNode.h b/Source/ASMultiplexImageNode.h index 15baced602..b3aa331e7d 100644 --- a/Source/ASMultiplexImageNode.h +++ b/Source/ASMultiplexImageNode.h @@ -131,14 +131,12 @@ typedef NS_ENUM(NSUInteger, ASMultiplexImageNodeErrorCode) { */ @property (nonatomic, assign, readwrite) BOOL shouldRenderProgressImages; -#if TARGET_OS_IOS /** * @abstract The image manager that this image node should use when requesting images from the Photos framework. If this is `nil` (the default), then `PHImageManager.defaultManager` is used. * @see `+[NSURL URLWithAssetLocalIdentifier:targetSize:contentMode:options:]` below. */ -@property (nullable, nonatomic, strong) PHImageManager *imageManager; -#endif +@property (nullable, nonatomic, strong) PHImageManager *imageManager API_AVAILABLE(ios(8.0), tvos(10.0)); @end @@ -245,7 +243,6 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier */ - (nullable NSURL *)multiplexImageNode:(ASMultiplexImageNode *)imageNode URLForImageIdentifier:(ASImageIdentifier)imageIdentifier; -#if TARGET_OS_IOS /** * @abstract A PHAsset for the specific asset local identifier * @param imageNode The sender. @@ -256,12 +253,10 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier * @note This method may be called from any thread. * @return A PHAsset corresponding to `assetLocalIdentifier`, or nil if none is available. */ -- (nullable PHAsset *)multiplexImageNode:(ASMultiplexImageNode *)imageNode assetForLocalIdentifier:(NSString *)assetLocalIdentifier; -#endif +- (nullable PHAsset *)multiplexImageNode:(ASMultiplexImageNode *)imageNode assetForLocalIdentifier:(NSString *)assetLocalIdentifier API_AVAILABLE(ios(8.0), tvos(10.0)); @end -#pragma mark - -#if TARGET_OS_IOS +#pragma mark - @interface NSURL (ASPhotosFrameworkURLs) /** @@ -275,9 +270,8 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier + (NSURL *)URLWithAssetLocalIdentifier:(NSString *)assetLocalIdentifier targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode - options:(PHImageRequestOptions *)options AS_WARN_UNUSED_RESULT; + options:(PHImageRequestOptions *)options AS_WARN_UNUSED_RESULT API_AVAILABLE(ios(8.0), tvos(10.0)); @end -#endif NS_ASSUME_NONNULL_END diff --git a/Source/ASMultiplexImageNode.mm b/Source/ASMultiplexImageNode.mm index ecc5fd7af1..12a2647e19 100644 --- a/Source/ASMultiplexImageNode.mm +++ b/Source/ASMultiplexImageNode.mm @@ -16,7 +16,10 @@ // #import + +#if TARGET_OS_IOS #import +#endif #import #import @@ -136,6 +139,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent @param completionBlock The block to be performed when the image has been loaded, if possible. May not be nil. */ - (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock; +#endif /** @abstract Loads the image corresponding to the given image request from the Photos framework. @@ -143,8 +147,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent @param request The photos image request to load. May not be nil. @param completionBlock The block to be performed when the image has been loaded, if possible. May not be nil. */ -- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock; -#endif +- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock API_AVAILABLE(ios(8.0), tvos(10.0)); + /** @abstract Downloads the image corresponding to the given imageIdentifier from the given URL. @param imageIdentifier The identifier for the image to be downloaded. May not be nil. @@ -345,9 +349,9 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent _dataSource = dataSource; _dataSourceFlags.image = [_dataSource respondsToSelector:@selector(multiplexImageNode:imageForImageIdentifier:)]; _dataSourceFlags.URL = [_dataSource respondsToSelector:@selector(multiplexImageNode:URLForImageIdentifier:)]; - #if TARGET_OS_IOS - _dataSourceFlags.asset = [_dataSource respondsToSelector:@selector(multiplexImageNode:assetForLocalIdentifier:)]; - #endif + if (AS_AVAILABLE_IOS_TVOS(9, 10)) { + _dataSourceFlags.asset = [_dataSource respondsToSelector:@selector(multiplexImageNode:assetForLocalIdentifier:)]; + } } @@ -616,7 +620,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent return; } - #if TARGET_OS_IOS +#if TARGET_OS_IOS // If it's an assets-library URL, we need to fetch it from the assets library. if ([[nextImageURL scheme] isEqualToString:kAssetsLibraryURLScheme]) { // Load the asset. @@ -624,48 +628,54 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent as_log_verbose(ASImageLoadingLog(), "Acquired image from assets library for %@ %@", weakSelf, nextImageIdentifier); finishedLoadingBlock(downloadedImage, nextImageIdentifier, error); }]; + + return; } - // Likewise, if it's a Photos asset, we need to fetch it accordingly. - else if (ASPhotosFrameworkImageRequest *request = [ASPhotosFrameworkImageRequest requestWithURL:nextImageURL]) { - [self _loadPHAssetWithRequest:request identifier:nextImageIdentifier completion:^(UIImage *image, NSError *error) { - as_log_verbose(ASImageLoadingLog(), "Acquired image from Photos for %@ %@", weakSelf, nextImageIdentifier); - finishedLoadingBlock(image, nextImageIdentifier, error); - }]; - } - #endif - else // Otherwise, it's a web URL that we can download. - { - // First, check the cache. - [self _fetchImageWithIdentifierFromCache:nextImageIdentifier URL:nextImageURL completion:^(UIImage *imageFromCache) { - __typeof__(self) strongSelf = weakSelf; - if (!strongSelf) - return; - - // If we had a cache-hit, we're done. - if (imageFromCache) { - as_log_verbose(ASImageLoadingLog(), "Acquired image from cache for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, imageFromCache); - finishedLoadingBlock(imageFromCache, nextImageIdentifier, nil); - return; - } - - // If the next image to load has changed, bail. - if (!ASObjectIsEqual([strongSelf _nextImageIdentifierToDownload], nextImageIdentifier)) { - finishedLoadingBlock(nil, nil, [NSError errorWithDomain:ASMultiplexImageNodeErrorDomain code:ASMultiplexImageNodeErrorCodeBestImageIdentifierChanged userInfo:nil]); - return; - } - - // Otherwise, we've got to download it. - [strongSelf _downloadImageWithIdentifier:nextImageIdentifier URL:nextImageURL completion:^(UIImage *downloadedImage, NSError *error) { - __typeof__(self) strongSelf = weakSelf; - if (downloadedImage) { - as_log_verbose(ASImageLoadingLog(), "Acquired image from download for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, downloadedImage); - } else { - as_log_error(ASImageLoadingLog(), "Error downloading image for %@ id: %@ err: %@", strongSelf, nextImageIdentifier, error); - } - finishedLoadingBlock(downloadedImage, nextImageIdentifier, error); +#endif + + if (AS_AVAILABLE_IOS_TVOS(9, 10)) { + // Likewise, if it's a Photos asset, we need to fetch it accordingly. + if (ASPhotosFrameworkImageRequest *request = [ASPhotosFrameworkImageRequest requestWithURL:nextImageURL]) { + [self _loadPHAssetWithRequest:request identifier:nextImageIdentifier completion:^(UIImage *image, NSError *error) { + as_log_verbose(ASImageLoadingLog(), "Acquired image from Photos for %@ %@", weakSelf, nextImageIdentifier); + finishedLoadingBlock(image, nextImageIdentifier, error); }]; - }]; + + return; + } } + + // Otherwise, it's a web URL that we can download. + // First, check the cache. + [self _fetchImageWithIdentifierFromCache:nextImageIdentifier URL:nextImageURL completion:^(UIImage *imageFromCache) { + __typeof__(self) strongSelf = weakSelf; + if (!strongSelf) + return; + + // If we had a cache-hit, we're done. + if (imageFromCache) { + as_log_verbose(ASImageLoadingLog(), "Acquired image from cache for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, imageFromCache); + finishedLoadingBlock(imageFromCache, nextImageIdentifier, nil); + return; + } + + // If the next image to load has changed, bail. + if (!ASObjectIsEqual([strongSelf _nextImageIdentifierToDownload], nextImageIdentifier)) { + finishedLoadingBlock(nil, nil, [NSError errorWithDomain:ASMultiplexImageNodeErrorDomain code:ASMultiplexImageNodeErrorCodeBestImageIdentifierChanged userInfo:nil]); + return; + } + + // Otherwise, we've got to download it. + [strongSelf _downloadImageWithIdentifier:nextImageIdentifier URL:nextImageURL completion:^(UIImage *downloadedImage, NSError *error) { + __typeof__(self) strongSelf = weakSelf; + if (downloadedImage) { + as_log_verbose(ASImageLoadingLog(), "Acquired image from download for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, downloadedImage); + } else { + as_log_error(ASImageLoadingLog(), "Error downloading image for %@ id: %@ err: %@", strongSelf, nextImageIdentifier, error); + } + finishedLoadingBlock(downloadedImage, nextImageIdentifier, error); + }]; + }]; } #if TARGET_OS_IOS - (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock @@ -691,7 +701,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent }]; #pragma clang diagnostic pop } - +#endif - (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock { ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required"); @@ -779,7 +789,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent _phImageRequestOperation = newImageRequestOp; [phImageRequestQueue addOperation:newImageRequestOp]; } -#endif + - (void)_fetchImageWithIdentifierFromCache:(id)imageIdentifier URL:(NSURL *)imageURL completion:(void (^)(UIImage *image))completionBlock { ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required"); diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index 1896b37cf7..5c83084448 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -115,7 +115,9 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; if (node) { self.backgroundColor = node.backgroundColor; self.selectedBackgroundView = node.selectedBackgroundView; +#if TARGET_OS_IOS self.separatorInset = node.separatorInset; +#endif self.selectionStyle = node.selectionStyle; self.focusStyle = node.focusStyle; self.accessoryType = node.accessoryType; @@ -920,6 +922,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; ASCellNode *node = [_dataController.visibleMap elementForItemAtIndexPath:indexPath].node; CGFloat height = node.calculatedSize.height; +#if TARGET_OS_IOS /** * Weirdly enough, Apple expects the return value here to _include_ the height * of the separator, if there is one! So if our node wants to be 43.5, we need @@ -929,6 +932,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; if (tableView.separatorStyle != UITableViewCellSeparatorStyleNone) { height += 1.0 / ASScreenScale(); } +#endif + return height; } @@ -1771,6 +1776,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; } CGRect rect = [self rectForRowAtIndexPath:indexPath]; +#if TARGET_OS_IOS /** * Weirdly enough, Apple expects the return value in tableView:heightForRowAtIndexPath: to _include_ the height * of the separator, if there is one! So if rectForRow would return 44.0 we need to use 43.5. @@ -1778,6 +1784,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; if (self.separatorStyle != UITableViewCellSeparatorStyleNone) { rect.size.height -= 1.0 / ASScreenScale(); } +#endif return (fabs(rect.size.height - size.height) < FLT_EPSILON); } diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index ccbed9c078..768223070e 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -451,10 +451,10 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // Since truncation text matches style of attributedText, invalidate it now. [self _invalidateTruncationText]; - NSUInteger length = attributedText.length; + NSUInteger length = _attributedText.length; if (length > 0) { - self.style.ascender = [[self class] ascenderWithAttributedString:attributedText]; - self.style.descender = [[attributedText attribute:NSFontAttributeName atIndex:attributedText.length - 1 effectiveRange:NULL] descender]; + self.style.ascender = [[self class] ascenderWithAttributedString:_attributedText]; + self.style.descender = [[_attributedText attribute:NSFontAttributeName atIndex:length - 1 effectiveRange:NULL] descender]; } // Tell the display node superclasses that the cached layout is incorrect now @@ -465,7 +465,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // Accessiblity - self.accessibilityLabel = attributedText.string; + self.accessibilityLabel = _attributedText.string; self.isAccessibilityElement = (length != 0); // We're an accessibility element by default if there is a string. } diff --git a/Source/Base/ASAvailability.h b/Source/Base/ASAvailability.h index f78ed9aaf6..f400dea3c4 100644 --- a/Source/Base/ASAvailability.h +++ b/Source/Base/ASAvailability.h @@ -36,9 +36,13 @@ // 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, *) + #define AS_AVAILABLE_IOS(ver) __builtin_available(iOS ver, *) + #define AS_AVAILABLE_TVOS(ver) __builtin_available(tvOS ver, *) + #define AS_AVAILABLE_IOS_TVOS(ver1, ver2) __builtin_available(iOS ver1, tvOS ver2, *) #else - #define AS_AVAILABLE_IOS(ver) AS_AT_LEAST_IOS##ver + #define AS_AVAILABLE_IOS(ver) (TARGET_OS_IOS && AS_AT_LEAST_IOS##ver) + #define AS_AVAILABLE_TVOS(ver) (TARGET_OS_TV && AS_AT_LEAST_IOS##ver) + #define AS_AVAILABLE_IOS_TVOS(ver1, ver2) (AS_AVAILABLE_IOS(ver1) || AS_AVAILABLE_TVOS(ver2)) #endif // If Yoga is available, make it available anywhere we use ASAvailability. diff --git a/Source/Base/ASLog.h b/Source/Base/ASLog.h index c6aba76bac..e87404631d 100644 --- a/Source/Base/ASLog.h +++ b/Source/Base/ASLog.h @@ -132,7 +132,7 @@ ASDISPLAYNODE_EXTERN_C_END #define as_log_create(subsystem, category) ({ \ os_log_t __val; \ -if (AS_AVAILABLE_IOS(9)) { \ +if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ __val = os_log_create(subsystem, category); \ } else { \ __val = (os_log_t)0; \ @@ -141,28 +141,28 @@ __val; \ }) #define as_log_debug(log, format, ...) \ -if (AS_AVAILABLE_IOS(9)) { \ +if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ os_log_debug(log, format, ##__VA_ARGS__); \ } else { \ (void)0; \ } \ #define as_log_info(log, format, ...) \ -if (AS_AVAILABLE_IOS(9)) { \ +if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ os_log_info(log, format, ##__VA_ARGS__); \ } else { \ (void)0; \ } \ #define as_log_error(log, format, ...) \ -if (AS_AVAILABLE_IOS(9)) { \ +if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ os_log_error(log, format, ##__VA_ARGS__); \ } else { \ (void)0; \ } \ #define as_log_fault(log, format, ...) \ -if (AS_AVAILABLE_IOS(9)) { \ +if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ os_log_fault(log, format, ##__VA_ARGS__); \ } else { \ (void)0; \ diff --git a/Source/Details/ASPhotosFrameworkImageRequest.h b/Source/Details/ASPhotosFrameworkImageRequest.h index 1ecd07dec3..54f55047ae 100644 --- a/Source/Details/ASPhotosFrameworkImageRequest.h +++ b/Source/Details/ASPhotosFrameworkImageRequest.h @@ -26,6 +26,7 @@ extern NSString *const ASPhotosURLScheme; @abstract Use ASPhotosFrameworkImageRequest to encapsulate all the information needed to request an image from the Photos framework and store it in a URL. */ +API_AVAILABLE(ios(8.0), tvos(10.0)) @interface ASPhotosFrameworkImageRequest : NSObject - (instancetype)initWithAssetIdentifier:(NSString *)assetIdentifier NS_DESIGNATED_INITIALIZER; diff --git a/Source/Details/ASTraitCollection.m b/Source/Details/ASTraitCollection.m index dba756bafa..8755fc57c9 100644 --- a/Source/Details/ASTraitCollection.m +++ b/Source/Details/ASTraitCollection.m @@ -286,7 +286,7 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai userInterfaceIdiom:userInterfaceIdiom forceTouchCapability:forceTouchCapability layoutDirection:layoutDirection - userInterfaceStyle:userIntefaceStyle + userInterfaceStyle:userInterfaceStyle preferredContentSizeCategory:preferredContentSizeCategory containerSize:windowSize]; } diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 734cf2b7fb..6b34c89a2b 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -85,7 +85,7 @@ static void SortAccessibilityElements(NSMutableArray *elements) accessibilityElement.accessibilityValue = node.accessibilityValue; accessibilityElement.accessibilityTraits = node.accessibilityTraits; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { accessibilityElement.accessibilityAttributedLabel = node.accessibilityAttributedLabel; accessibilityElement.accessibilityAttributedHint = node.accessibilityAttributedHint; accessibilityElement.accessibilityAttributedValue = node.accessibilityAttributedValue; @@ -179,7 +179,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ SortAccessibilityElements(labeledNodes); #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { NSArray *attributedLabels = [labeledNodes valueForKey:@"accessibilityAttributedLabel"]; NSMutableAttributedString *attributedLabel = [NSMutableAttributedString new]; [attributedLabels enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { diff --git a/Source/tvOS/ASControlNode+tvOS.h b/Source/Private/ASControlNode+Private.h similarity index 89% rename from Source/tvOS/ASControlNode+tvOS.h rename to Source/Private/ASControlNode+Private.h index cd05078a72..f3249c11c9 100644 --- a/Source/tvOS/ASControlNode+tvOS.h +++ b/Source/Private/ASControlNode+Private.h @@ -1,5 +1,5 @@ // -// ASControlNode+tvOS.h +// ASControlNode+Private.h // Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. @@ -15,10 +15,12 @@ // http://www.apache.org/licenses/LICENSE-2.0 // -#if TARGET_OS_TV #import -@interface ASControlNode (tvOS) +@interface ASControlNode (Private) + +#if TARGET_OS_TV +- (void)_pressDown; +#endif @end -#endif diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 13e932ef50..21f091c3ff 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -930,7 +930,7 @@ nodeProperty = nodeValueExpr; _setToViewOnly(viewAndPendingViewStateProperty, vi _bridge_prologue_write; _setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityLabel, accessibilityLabel, accessibilityLabel); #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { NSAttributedString *accessibilityAttributedLabel = accessibilityLabel ? [[NSAttributedString alloc] initWithString:accessibilityLabel] : nil; _setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel); } @@ -963,7 +963,7 @@ nodeProperty = nodeValueExpr; _setToViewOnly(viewAndPendingViewStateProperty, vi _bridge_prologue_write; _setAccessibilityToViewAndProperty(_accessibilityHint, accessibilityHint, accessibilityHint, accessibilityHint); #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { NSAttributedString *accessibilityAttributedHint = accessibilityHint ? [[NSAttributedString alloc] initWithString:accessibilityHint] : nil; _setAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint); } @@ -997,7 +997,7 @@ nodeProperty = nodeValueExpr; _setToViewOnly(viewAndPendingViewStateProperty, vi _bridge_prologue_write; _setAccessibilityToViewAndProperty(_accessibilityValue, accessibilityValue, accessibilityValue, accessibilityValue); #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { NSAttributedString *accessibilityAttributedValue = accessibilityValue ? [[NSAttributedString alloc] initWithString:accessibilityValue] : nil; _setAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue); } diff --git a/Source/Private/TextExperiment/String/ASTextAttribute.m b/Source/Private/TextExperiment/String/ASTextAttribute.m index 0cc8e22a72..76ff0df387 100755 --- a/Source/Private/TextExperiment/String/ASTextAttribute.m +++ b/Source/Private/TextExperiment/String/ASTextAttribute.m @@ -63,10 +63,12 @@ ASTextAttributeType ASTextAttributeGetType(NSString *name){ dic[(id)kCTSuperscriptAttributeName] = UIKit; //it's a CoreText attrubite, but only supported by UIKit... dic[NSVerticalGlyphFormAttributeName] = All; dic[(id)kCTGlyphInfoAttributeName] = CoreText_ASText; +#if TARGET_OS_IOS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" dic[(id)kCTCharacterShapeAttributeName] = CoreText_ASText; #pragma clang diagnostic pop +#endif dic[(id)kCTRunDelegateAttributeName] = CoreText_ASText; dic[(id)kCTBaselineClassAttributeName] = CoreText_ASText; dic[(id)kCTBaselineInfoAttributeName] = CoreText_ASText; diff --git a/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.h b/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.h index 31ef75d121..f7734347d0 100755 --- a/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.h +++ b/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.h @@ -1270,7 +1270,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)as_setSuperscript:(nullable NSNumber *)superscript range:(NSRange)range; - (void)as_setGlyphInfo:(nullable CTGlyphInfoRef)glyphInfo range:(NSRange)range; -- (void)as_setCharacterShape:(nullable NSNumber *)characterShape range:(NSRange)range; +- (void)as_setCharacterShape:(nullable NSNumber *)characterShape range:(NSRange)range __TVOS_PROHIBITED; - (void)as_setRunDelegate:(nullable CTRunDelegateRef)runDelegate range:(NSRange)range; - (void)as_setBaselineClass:(nullable CFStringRef)baselineClass range:(NSRange)range; - (void)as_setBaselineInfo:(nullable CFDictionaryRef)baselineInfo range:(NSRange)range; diff --git a/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m b/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m index 327bc41e2c..1b05bbf73a 100755 --- a/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m +++ b/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m @@ -600,10 +600,12 @@ return style. _attr_; dispatch_once(&onceToken, ^{ failSet = [NSMutableSet new]; [failSet addObject:(id)kCTGlyphInfoAttributeName]; +#if TARGET_OS_IOS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [failSet addObject:(id)kCTCharacterShapeAttributeName]; #pragma clang diagnostic pop +#endif [failSet addObject:(id)kCTLanguageAttributeName]; [failSet addObject:(id)kCTRunDelegateAttributeName]; [failSet addObject:(id)kCTBaselineClassAttributeName]; diff --git a/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m b/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m index 3401fcc829..2374e4021a 100755 --- a/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m +++ b/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m @@ -25,6 +25,7 @@ NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; +#if TARGET_OS_IOS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CGFloat lineSpacing; @@ -32,6 +33,7 @@ style.lineSpacing = lineSpacing; } #pragma clang diagnostic pop +#endif CGFloat paragraphSpacing; if (CTParagraphStyleGetValueForSpecifier(CTStyle, kCTParagraphStyleSpecifierParagraphSpacing, sizeof(CGFloat), ¶graphSpacing)) { @@ -114,6 +116,7 @@ CTParagraphStyleSetting set[kCTParagraphStyleSpecifierCount] = { }; int count = 0; +#if TARGET_OS_IOS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CGFloat lineSpacing = self.lineSpacing; @@ -122,6 +125,7 @@ set[count].value = &lineSpacing; count++; #pragma clang diagnostic pop +#endif CGFloat paragraphSpacing = self.paragraphSpacing; set[count].spec = kCTParagraphStyleSpecifierParagraphSpacing; diff --git a/Source/Private/_ASPendingState.mm b/Source/Private/_ASPendingState.mm index a51d564211..d009771bc5 100644 --- a/Source/Private/_ASPendingState.mm +++ b/Source/Private/_ASPendingState.mm @@ -1204,7 +1204,7 @@ static UIColor *defaultTintColor = nil; pendingState.accessibilityHint = view.accessibilityHint; pendingState.accessibilityValue = view.accessibilityValue; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { pendingState.accessibilityAttributedLabel = view.accessibilityAttributedLabel; pendingState.accessibilityAttributedHint = view.accessibilityAttributedHint; pendingState.accessibilityAttributedValue = view.accessibilityAttributedValue; diff --git a/Source/TextKit/ASTextKitCoreTextAdditions.m b/Source/TextKit/ASTextKitCoreTextAdditions.m index 05935db5ca..7f48aff713 100644 --- a/Source/TextKit/ASTextKitCoreTextAdditions.m +++ b/Source/TextKit/ASTextKitCoreTextAdditions.m @@ -39,6 +39,7 @@ BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName) kCTBaselineInfoAttributeName, kCTBaselineReferenceInfoAttributeName, kCTUnderlineColorAttributeName, + kCTParagraphStyleAttributeName, nil]; }); return [coreTextAttributes containsObject:attributeName]; @@ -97,8 +98,13 @@ NSDictionary *NSAttributedStringAttributesForCoreTextAttributes(NSDictionary *co cleanAttributes[NSForegroundColorAttributeName] = [UIColor colorWithCGColor:(CGColorRef)coreTextValue]; } // kCTParagraphStyleAttributeName -> NSParagraphStyleAttributeName - else if ([coreTextKey isEqualToString:(NSString *)kCTParagraphStyleAttributeName] && ![coreTextValue isKindOfClass:[NSParagraphStyle class]]) { - cleanAttributes[NSParagraphStyleAttributeName] = [NSParagraphStyle paragraphStyleWithCTParagraphStyle:(CTParagraphStyleRef)coreTextValue]; + else if ([coreTextKey isEqualToString:(NSString *)kCTParagraphStyleAttributeName]) { + if ([coreTextValue isKindOfClass:[NSParagraphStyle class]]) { + cleanAttributes[NSParagraphStyleAttributeName] = (NSParagraphStyle *)coreTextValue; + } + else { + cleanAttributes[NSParagraphStyleAttributeName] = [NSParagraphStyle paragraphStyleWithCTParagraphStyle:(CTParagraphStyleRef)coreTextValue]; + } } // kCTStrokeWidthAttributeName -> NSStrokeWidthAttributeName else if ([coreTextKey isEqualToString:(NSString *)kCTStrokeWidthAttributeName]) { @@ -170,8 +176,9 @@ NSAttributedString *ASCleanseAttributedStringOfCoreTextAttributes(NSAttributedSt { NSMutableParagraphStyle *newParagraphStyle = [[NSMutableParagraphStyle alloc] init]; - if (!coreTextParagraphStyle) + if (!coreTextParagraphStyle) { return newParagraphStyle; + } // The following paragraph style specifiers are not supported on NSParagraphStyle. Should they become available, we should add them. /* @@ -190,67 +197,145 @@ NSAttributedString *ASCleanseAttributedStringOfCoreTextAttributes(NSAttributedSt // kCTParagraphStyleSpecifierAlignment -> alignment CTTextAlignment coreTextAlignment; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierAlignment, sizeof(coreTextAlignment), &coreTextAlignment)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierAlignment, + sizeof(coreTextAlignment), + &coreTextAlignment)) { newParagraphStyle.alignment = NSTextAlignmentFromCTTextAlignment(coreTextAlignment); + } // kCTParagraphStyleSpecifierFirstLineHeadIndent -> firstLineHeadIndent CGFloat firstLineHeadIndent; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierFirstLineHeadIndent, sizeof(firstLineHeadIndent), &firstLineHeadIndent)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierFirstLineHeadIndent, + sizeof(firstLineHeadIndent), + &firstLineHeadIndent)) { newParagraphStyle.firstLineHeadIndent = firstLineHeadIndent; + } // kCTParagraphStyleSpecifierHeadIndent -> headIndent CGFloat headIndent; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierHeadIndent, sizeof(headIndent), &headIndent)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierHeadIndent, + sizeof(headIndent), + &headIndent)) { newParagraphStyle.headIndent = headIndent; + } // kCTParagraphStyleSpecifierTailIndent -> tailIndent CGFloat tailIndent; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierTailIndent, sizeof(tailIndent), &tailIndent)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierTailIndent, + sizeof(tailIndent), + &tailIndent)) { newParagraphStyle.tailIndent = tailIndent; + } // kCTParagraphStyleSpecifierLineBreakMode -> lineBreakMode CTLineBreakMode coreTextLineBreakMode; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierLineBreakMode, sizeof(coreTextLineBreakMode), &coreTextLineBreakMode)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierLineBreakMode, + sizeof(coreTextLineBreakMode), + &coreTextLineBreakMode)) { newParagraphStyle.lineBreakMode = (NSLineBreakMode)coreTextLineBreakMode; // They're the same enum. + } // kCTParagraphStyleSpecifierLineHeightMultiple -> lineHeightMultiple CGFloat lineHeightMultiple; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierLineHeightMultiple, sizeof(lineHeightMultiple), &lineHeightMultiple)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierLineHeightMultiple, + sizeof(lineHeightMultiple), + &lineHeightMultiple)) { newParagraphStyle.lineHeightMultiple = lineHeightMultiple; + } // kCTParagraphStyleSpecifierMaximumLineHeight -> maximumLineHeight CGFloat maximumLineHeight; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierMaximumLineHeight, sizeof(maximumLineHeight), &maximumLineHeight)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierMaximumLineHeight, + sizeof(maximumLineHeight), + &maximumLineHeight)) { newParagraphStyle.maximumLineHeight = maximumLineHeight; + } // kCTParagraphStyleSpecifierMinimumLineHeight -> minimumLineHeight CGFloat minimumLineHeight; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(minimumLineHeight), &minimumLineHeight)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierMinimumLineHeight, + sizeof(minimumLineHeight), + &minimumLineHeight)) { newParagraphStyle.minimumLineHeight = minimumLineHeight; - - // kCTParagraphStyleSpecifierLineSpacing -> lineSpacing - // Note that kCTParagraphStyleSpecifierLineSpacing is deprecated and will die soon. We should not be using it. + } + + CGFloat lineSpacing = 0; +#if TARGET_OS_IOS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - CGFloat lineSpacing; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierLineSpacing, sizeof(lineSpacing), &lineSpacing)) - newParagraphStyle.lineSpacing = lineSpacing; + // kCTParagraphStyleSpecifierLineSpacing -> lineSpacing + // Note that kCTParagraphStyleSpecifierLineSpacing is deprecated and will die soon. We should not be using it. + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierLineSpacing, + sizeof(lineSpacing), + &lineSpacing)) { + newParagraphStyle.lineSpacing = lineSpacing; + } #pragma clang diagnostic pop +#endif + + // Attempt to weakly map the following onto -[NSParagraphStyle lineSpacing]: + // - kCTParagraphStyleSpecifierMinimumLineSpacing + // - kCTParagraphStyleSpecifierMaximumLineSpacing + // - kCTParagraphStyleSpecifierLineSpacingAdjustment + if (fabs(lineSpacing) <= FLT_EPSILON && + CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierMinimumLineSpacing, + sizeof(lineSpacing), + &lineSpacing)) { + newParagraphStyle.lineSpacing = lineSpacing; + } + + if (fabs(lineSpacing) <= FLT_EPSILON && + CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierMaximumLineSpacing, + sizeof(lineSpacing), + &lineSpacing)) { + newParagraphStyle.lineSpacing = lineSpacing; + } + + if (fabs(lineSpacing) <= FLT_EPSILON && + CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierLineSpacingAdjustment, + sizeof(lineSpacing), + &lineSpacing)) { + newParagraphStyle.lineSpacing = lineSpacing; + } // kCTParagraphStyleSpecifierParagraphSpacing -> paragraphSpacing CGFloat paragraphSpacing; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierParagraphSpacing, sizeof(paragraphSpacing), ¶graphSpacing)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierParagraphSpacing, + sizeof(paragraphSpacing), + ¶graphSpacing)) { newParagraphStyle.paragraphSpacing = paragraphSpacing; + } // kCTParagraphStyleSpecifierParagraphSpacingBefore -> paragraphSpacingBefore CGFloat paragraphSpacingBefore; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierParagraphSpacingBefore, sizeof(paragraphSpacingBefore), ¶graphSpacingBefore)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierParagraphSpacingBefore, + sizeof(paragraphSpacingBefore), + ¶graphSpacingBefore)) { newParagraphStyle.paragraphSpacingBefore = paragraphSpacingBefore; + } // kCTParagraphStyleSpecifierBaseWritingDirection -> baseWritingDirection CTWritingDirection coreTextBaseWritingDirection; - if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierBaseWritingDirection, sizeof(coreTextBaseWritingDirection), &coreTextBaseWritingDirection)) + if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, + kCTParagraphStyleSpecifierBaseWritingDirection, + sizeof(coreTextBaseWritingDirection), + &coreTextBaseWritingDirection)) { newParagraphStyle.baseWritingDirection = (NSWritingDirection)coreTextBaseWritingDirection; // They're the same enum. + } return newParagraphStyle; } diff --git a/Source/tvOS/ASControlNode+tvOS.m b/Source/tvOS/ASControlNode+tvOS.m index 35acbc0457..77e5418629 100644 --- a/Source/tvOS/ASControlNode+tvOS.m +++ b/Source/tvOS/ASControlNode+tvOS.m @@ -16,20 +16,20 @@ // #import - #if TARGET_OS_TV -#import +#import +#import @implementation ASControlNode (tvOS) #pragma mark - tvOS -- (void)pressDown +- (void)_pressDown { - [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationCurveLinear animations:^{ + [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ [self setPressedState]; } completion:^(BOOL finished) { if (finished) { - [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationCurveLinear animations:^{ + [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ [self setFocusedState]; } completion:nil]; } diff --git a/Source/tvOS/ASImageNode+tvOS.h b/Source/tvOS/ASImageNode+tvOS.h deleted file mode 100644 index d808db10ab..0000000000 --- a/Source/tvOS/ASImageNode+tvOS.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// ASImageNode+tvOS.h -// Texture -// -// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -// This source code is licensed under the BSD-style license found in the -// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional -// grant of patent rights can be found in the PATENTS file in the same directory. -// -// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, -// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// - -#if TARGET_OS_TV -#import - -@interface ASImageNode (tvOS) -@end -#endif - diff --git a/Source/tvOS/ASImageNode+tvOS.m b/Source/tvOS/ASImageNode+tvOS.m index d3da889c52..9482fdc8c1 100644 --- a/Source/tvOS/ASImageNode+tvOS.m +++ b/Source/tvOS/ASImageNode+tvOS.m @@ -17,7 +17,8 @@ #import #if TARGET_OS_TV -#import +#import +#import #import #import diff --git a/Texture.podspec b/Texture.podspec index b780df2830..a0d8b84220 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -11,13 +11,13 @@ Pod::Spec.new do |spec| spec.documentation_url = 'http://texturegroup.org/appledoc/' - spec.weak_frameworks = 'Photos','MapKit','AssetsLibrary' + spec.ios.weak_frameworks = 'AssetsLibrary' + spec.weak_frameworks = 'Photos','MapKit' + spec.requires_arc = true spec.ios.deployment_target = '9.0' - - # Uncomment when fixed: issues with tvOS build for release 2.0 - # spec.tvos.deployment_target = '9.0' + spec.tvos.deployment_target = '9.0' # Subspecs spec.subspec 'Core' do |core|