[tvOS] Fixes errors when building against tvOS SDK (#728)

* [tvOS] Fixes errors when building against tvOS SDK

* Update CHANGELOG.md

* [tvOS] Fixes implicit conversion between UIViewAnimationCurve +
UIViewAnimationOptions

* Enable tvOS deployment target in Texture.podspec (for CI)

* [ASMultiplexImageNode] Fixes typo

* [tvOS] Fixes warnings related to @available guards in Xcode 9
[ASMultiplexImageNode] Enables support for Photos framework on tvOS 10+

[ASMultiplexImageNode] Fixes comment depth

[ASAvailability] Adjust logic in AS_AVAILABLE_IOS_TVOS to account for
both versions
Adjusts API_AVAILABLE to minimum deployment target

* [ASAvailability] Update AS_AVAILABLE_XXX fallbacks to function more like
the built-in solution (more accurately target OS by checking target)
Change AS_AVAILABLE_IOS -> AS_AVAILABLE_IOS_TVOS in places that shoud
allow for both

[ASAvailability] Simplify AS_AVAILABLE_IOS_TVOS

* [ASControlNode] Adds missing 'super' call in -[ASControlNode didLoad]
when targeting tvOS

* Fix API_AVAILABLE iOS requirement

* [ASDisplayNode] Fixes last of the linker warnings related to category
overrides. Removes methods already implemented in
ASDisplayNode+UIViewBridge category.
[ASControlNode] Moves tvOS category declaration to ASControlNode header
[ASImageNode] Moves tvOS category declaration to ASImageNode header
[ASControlNode+Private] Adds private category for ASControlNode to
access private selectors

* [NSParagraphStyle+ASText] Fixes typo related to testing

* [ASControlNode] Re-add helpful comment

* [ASTextKitCoreTextAdditions] Adds mappings for kCTParagraphStyleSpecifierMinimumLineSpacing, kCTParagraphStyleSpecifierMaximumLineSpacing, kCTParagraphStyleSpecifierLineSpacingAdjustment when mapping CTParagraphStyle onto NSParagraphStyle
[ASTextNode] Uses CoreText-cleansed attributed string when assigning ascender/descender to avoid crash when a CTParagraphStyle is passed as an attribute

* [AsyncDisplayKit] Update project file to include new/deleted files

* [ASControlNode+tvOS] Add missing Foundation import (whoops!)
[ASImageNode+tvOS] Add missing Foundation import (whoops!)

* Update podspec to only link AssetsLibrary framework on iOS

* [ASTextKitCoreTextAdditions] If kCTParagraphStyleAttributeName key-value
evaluates to an NSParagraphStyle, pass through to cleansed attributes. This
fixes a bug that would occur if a CTParagraphStyle was passed as an
attribute _alone_ (would not be caught by unsupported attributes
check)

* [ASMultiplexImageNode] Bump availability check to support < Xcode 9

* [ASTraitCollection] Fixes typo that was causing build to fail

* Clean up formatting to adhere to character/line limit + braces
This commit is contained in:
Alex Hill 2018-03-11 16:37:27 -07:00 committed by Adlai Holler
parent e0d07d07ef
commit d9d9a29365
29 changed files with 244 additions and 180 deletions

View File

@ -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 = "<group>"; };
690C35631E055C7B00069B91 /* ASDimensionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDimensionInternal.h; sourceTree = "<group>"; };
690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementStylePrivate.h; sourceTree = "<group>"; };
690ED5921E36D118000627C0 /* ASControlNode+tvOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+tvOS.h"; sourceTree = "<group>"; };
690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASControlNode+tvOS.m"; sourceTree = "<group>"; };
690ED5941E36D118000627C0 /* ASImageNode+tvOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+tvOS.h"; sourceTree = "<group>"; };
690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASImageNode+tvOS.m"; sourceTree = "<group>"; };
692510131E74FB44003F2DD0 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
692BE8D61E36B65B00C86D87 /* ASLayoutSpecPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecPrivate.h; sourceTree = "<group>"; };
@ -982,6 +979,7 @@
E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionGalleryLayoutDelegate.mm; sourceTree = "<group>"; 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 = "<group>"; };
FA4FAF14200A850200E735BD /* ASControlNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Private.h"; sourceTree = "<group>"; };
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 = "<group>"; };
/* 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 */,

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -16,6 +16,7 @@
//
#import <AsyncDisplayKit/ASControlNode.h>
#import <AsyncDisplayKit/ASControlNode+Private.h>
#import <AsyncDisplayKit/ASControlNode+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASImageNode.h>
@ -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];
}

View File

@ -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)

View File

@ -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;

View File

@ -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)
/**

View File

@ -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

View File

@ -16,7 +16,10 @@
//
#import <AsyncDisplayKit/ASMultiplexImageNode.h>
#if TARGET_OS_IOS
#import <AssetsLibrary/AssetsLibrary.h>
#endif
#import <AsyncDisplayKit/ASAvailability.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkSubclasses.h>
@ -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");

View File

@ -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);
}

View File

@ -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.
}

View File

@ -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.

View File

@ -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; \

View File

@ -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 <NSCopying>
- (instancetype)initWithAssetIdentifier:(NSString *)assetIdentifier NS_DESIGNATED_INITIALIZER;

View File

@ -286,7 +286,7 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai
userInterfaceIdiom:userInterfaceIdiom
forceTouchCapability:forceTouchCapability
layoutDirection:layoutDirection
userInterfaceStyle:userIntefaceStyle
userInterfaceStyle:userInterfaceStyle
preferredContentSizeCategory:preferredContentSizeCategory
containerSize:windowSize];
}

View File

@ -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) {

View File

@ -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 <AsyncDisplayKit/ASControlNode.h>
@interface ASControlNode (tvOS)
@interface ASControlNode (Private)
#if TARGET_OS_TV
- (void)_pressDown;
#endif
@end
#endif

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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];

View File

@ -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), &paragraphSpacing)) {
@ -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;

View File

@ -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;

View File

@ -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), &paragraphSpacing))
if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle,
kCTParagraphStyleSpecifierParagraphSpacing,
sizeof(paragraphSpacing),
&paragraphSpacing)) {
newParagraphStyle.paragraphSpacing = paragraphSpacing;
}
// kCTParagraphStyleSpecifierParagraphSpacingBefore -> paragraphSpacingBefore
CGFloat paragraphSpacingBefore;
if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle, kCTParagraphStyleSpecifierParagraphSpacingBefore, sizeof(paragraphSpacingBefore), &paragraphSpacingBefore))
if (CTParagraphStyleGetValueForSpecifier(coreTextParagraphStyle,
kCTParagraphStyleSpecifierParagraphSpacingBefore,
sizeof(paragraphSpacingBefore),
&paragraphSpacingBefore)) {
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;
}

View File

@ -16,20 +16,20 @@
//
#import <Foundation/Foundation.h>
#if TARGET_OS_TV
#import <AsyncDisplayKit/ASControlNode+tvOS.h>
#import <AsyncDisplayKit/ASControlNode.h>
#import <AsyncDisplayKit/ASControlNode+Private.h>
@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];
}

View File

@ -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 <AsyncDisplayKit/ASImageNode.h>
@interface ASImageNode (tvOS)
@end
#endif

View File

@ -17,7 +17,8 @@
#import <Foundation/Foundation.h>
#if TARGET_OS_TV
#import <AsyncDisplayKit/ASImageNode+tvOS.h>
#import <AsyncDisplayKit/ASImageNode.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <GLKit/GLKit.h>
#import <tgmath.h>

View File

@ -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|