mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-13 18:00:17 +00:00
[ASTraitCollection] Add missing properties to ASTraitCollection (#625)
* [ASTraitCollection] Add missing properties to ASTraitCollection * ASTraitCollection now completely reflects UITraitCollection * Add ASContentSizeCategory enum that corresponds to UIContentSizeCategory and can be used inside a struct. * * Remove enum ASContentSizeCategory. * Use __unsafe_unretained UIContentSizeCategory instead of the enum. * Added ASPrimitiveTraitCollection lifetime test * Changes requested at code review: * Restore one of the ASTraitCollection constructors with a deprecation notice. * Clean up API by the separation of tvOS-specific interfaces. * Use [NSString -isEqualToString:] for ASPrimitiveContentSizeCategory equality tests for better readability. * Encapsulate fallback logic for UIContentSizeCategoryUnspecified. * Fix failing test
This commit is contained in:
parent
193be32bcf
commit
a3136b0225
@ -99,6 +99,7 @@
|
||||
3917EBD41E9C2FC400D04A01 /* _ASCollectionReusableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.m */; };
|
||||
3C9C128519E616EF00E942A0 /* ASTableViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */; };
|
||||
4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */; };
|
||||
4E9127691F64157600499623 /* ASRunLoopQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E9127681F64157600499623 /* ASRunLoopQueueTests.m */; };
|
||||
509E68601B3AED8E009B9150 /* ASScrollDirection.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E111B371BD7007741D0 /* ASScrollDirection.m */; };
|
||||
509E68611B3AEDA0009B9150 /* ASAbstractLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E171B37339C007741D0 /* ASAbstractLayoutController.h */; };
|
||||
@ -634,6 +635,7 @@
|
||||
3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCollectionReusableView.h; sourceTree = "<group>"; };
|
||||
3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ASCollectionReusableView.m; sourceTree = "<group>"; };
|
||||
3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTableViewTests.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTraitCollectionTests.m; sourceTree = "<group>"; };
|
||||
464052191A3F83C40061C0BA /* ASDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDataController.h; sourceTree = "<group>"; };
|
||||
4640521A1A3F83C40061C0BA /* ASDataController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDataController.mm; sourceTree = "<group>"; };
|
||||
4640521B1A3F83C40061C0BA /* ASTableLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTableLayoutController.h; sourceTree = "<group>"; };
|
||||
@ -1256,6 +1258,7 @@
|
||||
695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */,
|
||||
699B83501E3C1BA500433FA4 /* ASLayoutSpecTests.m */,
|
||||
4E9127681F64157600499623 /* ASRunLoopQueueTests.m */,
|
||||
4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */,
|
||||
);
|
||||
path = Tests;
|
||||
sourceTree = "<group>";
|
||||
@ -2163,6 +2166,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */,
|
||||
4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.m in Sources */,
|
||||
29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */,
|
||||
CC583AD71EF9BDC100134156 /* NSInvocation+ASTestHelpers.m in Sources */,
|
||||
CC051F1F1D7A286A006434CB /* ASCALayerTests.m in Sources */,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
## master
|
||||
* Add your own contributions to the next release on the line below this with your name.
|
||||
- [ASTraitCollection] Add new properties of UITraitCollection to ASTraitCollection. [Yevgen Pogribnyi](https://github.com/ypogribnyi)
|
||||
- [ASRectMap] Replace implementation of ASRectTable with a simpler one based on unordered_map.[Scott Goodson](https://github.com/appleguy) [#719](https://github.com/TextureGroup/Texture/pull/719)
|
||||
- [ASCollectionView] Add missing flags for ASCollectionDelegate [Ilya Zheleznikov](https://github.com/ilyailya) [#718](https://github.com/TextureGroup/Texture/pull/718)
|
||||
- [ASNetworkImageNode] Deprecates .URLs in favor of .URL [Garrett Moon](https://github.com/garrettmoon) [#699](https://github.com/TextureGroup/Texture/pull/699)
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||
|
||||
@class ASTraitCollection;
|
||||
@ -27,14 +28,51 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||
|
||||
#pragma mark - ASPrimitiveContentSizeCategory
|
||||
|
||||
/**
|
||||
* ASPrimitiveContentSizeCategory is a UIContentSizeCategory that can be used inside a struct.
|
||||
*
|
||||
* We need an unretained pointer because ARC can't manage struct memory.
|
||||
*
|
||||
* WARNING: DO NOT cast UIContentSizeCategory values to ASPrimitiveContentSizeCategory directly.
|
||||
* Use ASPrimitiveContentSizeCategoryMake(UIContentSizeCategory) instead.
|
||||
* This is because we make some assumptions about the lifetime of the object it points to.
|
||||
* Also note that cast from ASPrimitiveContentSizeCategory to UIContentSizeCategory is always safe.
|
||||
*/
|
||||
typedef __unsafe_unretained UIContentSizeCategory ASPrimitiveContentSizeCategory;
|
||||
|
||||
/**
|
||||
* Safely casts from UIContentSizeCategory to ASPrimitiveContentSizeCategory.
|
||||
*
|
||||
* The UIKit documentation doesn't specify if we can receive a copy of the UIContentSizeCategory constant. While getting
|
||||
* copies is fine with ARC, usage of unretained pointers requires us to ensure the lifetime of the object it points to.
|
||||
* Manual retain&release of the UIContentSizeCategory object is not an option because it would require us to do that
|
||||
* everywhere ASPrimitiveTraitCollection is used. This is error-prone and can lead to crashes and memory leaks. So, we
|
||||
* explicitly limit possible values of ASPrimitiveContentSizeCategory to the predetermined set of global constants with
|
||||
* known lifetime.
|
||||
*
|
||||
* @return a pointer to one of the UIContentSizeCategory constants.
|
||||
*/
|
||||
extern ASPrimitiveContentSizeCategory ASPrimitiveContentSizeCategoryMake(UIContentSizeCategory sizeCategory);
|
||||
|
||||
#pragma mark - ASPrimitiveTraitCollection
|
||||
|
||||
typedef struct ASPrimitiveTraitCollection {
|
||||
CGFloat displayScale;
|
||||
UIUserInterfaceSizeClass horizontalSizeClass;
|
||||
UIUserInterfaceIdiom userInterfaceIdiom;
|
||||
UIUserInterfaceSizeClass verticalSizeClass;
|
||||
|
||||
CGFloat displayScale;
|
||||
UIDisplayGamut displayGamut;
|
||||
|
||||
UIUserInterfaceIdiom userInterfaceIdiom;
|
||||
UIForceTouchCapability forceTouchCapability;
|
||||
UITraitEnvironmentLayoutDirection layoutDirection;
|
||||
#if TARGET_OS_TV
|
||||
UIUserInterfaceStyle userInterfaceStyle;
|
||||
#endif
|
||||
|
||||
ASPrimitiveContentSizeCategory preferredContentSizeCategory;
|
||||
|
||||
CGSize containerSize;
|
||||
} ASPrimitiveTraitCollection;
|
||||
@ -124,11 +162,21 @@ ASDISPLAYNODE_EXTERN_C_END
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASTraitCollection : NSObject
|
||||
|
||||
@property (nonatomic, assign, readonly) CGFloat displayScale;
|
||||
@property (nonatomic, assign, readonly) UIUserInterfaceSizeClass horizontalSizeClass;
|
||||
@property (nonatomic, assign, readonly) UIUserInterfaceIdiom userInterfaceIdiom;
|
||||
@property (nonatomic, assign, readonly) UIUserInterfaceSizeClass verticalSizeClass;
|
||||
|
||||
@property (nonatomic, assign, readonly) CGFloat displayScale;
|
||||
@property (nonatomic, assign, readonly) UIDisplayGamut displayGamut;
|
||||
|
||||
@property (nonatomic, assign, readonly) UIUserInterfaceIdiom userInterfaceIdiom;
|
||||
@property (nonatomic, assign, readonly) UIForceTouchCapability forceTouchCapability;
|
||||
@property (nonatomic, assign, readonly) UITraitEnvironmentLayoutDirection layoutDirection;
|
||||
#if TARGET_OS_TV
|
||||
@property (nonatomic, assign, readonly) UIUserInterfaceStyle userInterfaceStyle;
|
||||
#endif
|
||||
|
||||
@property (nonatomic, assign, readonly) UIContentSizeCategory preferredContentSizeCategory;
|
||||
|
||||
@property (nonatomic, assign, readonly) CGSize containerSize;
|
||||
|
||||
+ (ASTraitCollection *)traitCollectionWithASPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traits;
|
||||
@ -136,18 +184,48 @@ AS_SUBCLASSING_RESTRICTED
|
||||
+ (ASTraitCollection *)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection
|
||||
containerSize:(CGSize)windowSize;
|
||||
|
||||
+ (ASTraitCollection *)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection
|
||||
containerSize:(CGSize)windowSize
|
||||
fallbackContentSizeCategory:(UIContentSizeCategory)fallbackContentSizeCategory;
|
||||
|
||||
+ (ASTraitCollection *)traitCollectionWithDisplayScale:(CGFloat)displayScale
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
containerSize:(CGSize)windowSize;
|
||||
|
||||
#if TARGET_OS_TV
|
||||
+ (ASTraitCollection *)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
displayScale:(CGFloat)displayScale
|
||||
displayGamut:(UIDisplayGamut)displayGamut
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection
|
||||
userInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory
|
||||
containerSize:(CGSize)windowSize;
|
||||
#else
|
||||
+ (ASTraitCollection *)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
displayScale:(CGFloat)displayScale
|
||||
displayGamut:(UIDisplayGamut)displayGamut
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory
|
||||
containerSize:(CGSize)windowSize;
|
||||
#endif
|
||||
|
||||
- (ASPrimitiveTraitCollection)primitiveTraitCollection;
|
||||
- (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection;
|
||||
|
||||
@end
|
||||
|
||||
@interface ASTraitCollection (Deprecated)
|
||||
|
||||
+ (ASTraitCollection *)traitCollectionWithDisplayScale:(CGFloat)displayScale
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
containerSize:(CGSize)windowSize
|
||||
ASDISPLAYNODE_DEPRECATED_MSG("Use full version of this method instead.");
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -20,6 +20,60 @@
|
||||
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>
|
||||
#import <AsyncDisplayKit/ASLayoutElement.h>
|
||||
|
||||
#pragma mark - ASPrimitiveContentSizeCategory
|
||||
|
||||
// UIContentSizeCategoryUnspecified is available only in iOS 10.0 and later.
|
||||
// This is used for compatibility with older iOS versions.
|
||||
ASDISPLAYNODE_INLINE UIContentSizeCategory AS_UIContentSizeCategoryUnspecified() {
|
||||
if (AS_AVAILABLE_IOS(10)) {
|
||||
return UIContentSizeCategoryUnspecified;
|
||||
} else {
|
||||
return @"_UICTContentSizeCategoryUnspecified";
|
||||
}
|
||||
}
|
||||
|
||||
ASPrimitiveContentSizeCategory ASPrimitiveContentSizeCategoryMake(UIContentSizeCategory sizeCategory) {
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraSmall]) {
|
||||
return UIContentSizeCategoryExtraSmall;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategorySmall]) {
|
||||
return UIContentSizeCategorySmall;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryMedium]) {
|
||||
return UIContentSizeCategoryMedium;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryLarge]) {
|
||||
return UIContentSizeCategoryLarge;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraLarge]) {
|
||||
return UIContentSizeCategoryExtraLarge;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge]) {
|
||||
return UIContentSizeCategoryExtraExtraLarge;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge]) {
|
||||
return UIContentSizeCategoryExtraExtraExtraLarge;
|
||||
}
|
||||
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityMedium]) {
|
||||
return UIContentSizeCategoryAccessibilityMedium;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityLarge]) {
|
||||
return UIContentSizeCategoryAccessibilityLarge;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraLarge]) {
|
||||
return UIContentSizeCategoryAccessibilityExtraLarge;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraLarge]) {
|
||||
return UIContentSizeCategoryAccessibilityExtraExtraLarge;
|
||||
}
|
||||
if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraExtraLarge]) {
|
||||
return UIContentSizeCategoryAccessibilityExtraExtraExtraLarge;
|
||||
}
|
||||
|
||||
return AS_UIContentSizeCategoryUnspecified();
|
||||
}
|
||||
|
||||
#pragma mark - ASPrimitiveTraitCollection
|
||||
|
||||
extern void ASTraitCollectionPropagateDown(id<ASLayoutElement> element, ASPrimitiveTraitCollection traitCollection) {
|
||||
@ -32,36 +86,57 @@ extern void ASTraitCollectionPropagateDown(id<ASLayoutElement> element, ASPrimit
|
||||
}
|
||||
}
|
||||
|
||||
ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault()
|
||||
{
|
||||
ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() {
|
||||
return (ASPrimitiveTraitCollection) {
|
||||
// Default values can be defined in here
|
||||
.displayGamut = UIDisplayGamutUnspecified,
|
||||
.userInterfaceIdiom = UIUserInterfaceIdiomUnspecified,
|
||||
.layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified,
|
||||
.preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(AS_UIContentSizeCategoryUnspecified()),
|
||||
.containerSize = CGSizeZero,
|
||||
};
|
||||
}
|
||||
|
||||
ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection *traitCollection)
|
||||
{
|
||||
ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection *traitCollection) {
|
||||
ASPrimitiveTraitCollection environmentTraitCollection = ASPrimitiveTraitCollectionMakeDefault();
|
||||
environmentTraitCollection.displayScale = traitCollection.displayScale;
|
||||
environmentTraitCollection.horizontalSizeClass = traitCollection.horizontalSizeClass;
|
||||
environmentTraitCollection.verticalSizeClass = traitCollection.verticalSizeClass;
|
||||
environmentTraitCollection.displayScale = traitCollection.displayScale;
|
||||
environmentTraitCollection.userInterfaceIdiom = traitCollection.userInterfaceIdiom;
|
||||
if (AS_AVAILABLE_IOS(9)) {
|
||||
environmentTraitCollection.forceTouchCapability = traitCollection.forceTouchCapability;
|
||||
environmentTraitCollection.forceTouchCapability = traitCollection.forceTouchCapability;
|
||||
if (AS_AVAILABLE_IOS(10)) {
|
||||
environmentTraitCollection.displayGamut = traitCollection.displayGamut;
|
||||
environmentTraitCollection.layoutDirection = traitCollection.layoutDirection;
|
||||
|
||||
// preferredContentSizeCategory is also available on older iOS versions, but only via UIApplication class.
|
||||
// It should be noted that [UIApplication sharedApplication] is unavailable because Texture is built with only extension-safe API.
|
||||
environmentTraitCollection.preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(traitCollection.preferredContentSizeCategory);
|
||||
|
||||
#if TARGET_OS_TV
|
||||
environmentTraitCollection.userInterfaceStyle = traitCollection.userInterfaceStyle;
|
||||
#endif
|
||||
}
|
||||
return environmentTraitCollection;
|
||||
}
|
||||
|
||||
BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs)
|
||||
{
|
||||
BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs) {
|
||||
UIContentSizeCategory leftSizeCategory = (UIContentSizeCategory)lhs.preferredContentSizeCategory;
|
||||
UIContentSizeCategory rightSizeCategory = (UIContentSizeCategory)rhs.preferredContentSizeCategory;
|
||||
|
||||
return
|
||||
lhs.verticalSizeClass == rhs.verticalSizeClass &&
|
||||
lhs.horizontalSizeClass == rhs.horizontalSizeClass &&
|
||||
lhs.displayScale == rhs.displayScale &&
|
||||
lhs.displayGamut == rhs.displayGamut &&
|
||||
lhs.userInterfaceIdiom == rhs.userInterfaceIdiom &&
|
||||
lhs.forceTouchCapability == rhs.forceTouchCapability &&
|
||||
lhs.layoutDirection == rhs.layoutDirection &&
|
||||
#if TARGET_OS_TV
|
||||
lhs.userInterfaceStyle == rhs.userInterfaceStyle &&
|
||||
#endif
|
||||
|
||||
[leftSizeCategory isEqualToString:rightSizeCategory] && // Simple pointer comparison should be sufficient here
|
||||
|
||||
CGSizeEqualToSize(lhs.containerSize, rhs.containerSize);
|
||||
}
|
||||
|
||||
@ -105,14 +180,58 @@ ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIUserInterfaceSizeClass(UIUserInt
|
||||
}
|
||||
}
|
||||
|
||||
NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection traits)
|
||||
{
|
||||
// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline
|
||||
ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIDisplayGamut(UIDisplayGamut displayGamut) {
|
||||
switch (displayGamut) {
|
||||
case UIDisplayGamutSRGB:
|
||||
return @"sRGB";
|
||||
case UIDisplayGamutP3:
|
||||
return @"P3";
|
||||
default:
|
||||
return @"Unspecified";
|
||||
}
|
||||
}
|
||||
|
||||
// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline
|
||||
ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentLayoutDirection(UITraitEnvironmentLayoutDirection layoutDirection) {
|
||||
switch (layoutDirection) {
|
||||
case UITraitEnvironmentLayoutDirectionLeftToRight:
|
||||
return @"LeftToRight";
|
||||
case UITraitEnvironmentLayoutDirectionRightToLeft:
|
||||
return @"RightToLeft";
|
||||
default:
|
||||
return @"Unspecified";
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV
|
||||
// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline
|
||||
ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIUserInterfaceStyle(UIUserInterfaceStyle userInterfaceStyle) {
|
||||
switch (userInterfaceStyle) {
|
||||
case UIUserInterfaceStyleLight:
|
||||
return @"Light";
|
||||
case UIUserInterfaceStyleDark:
|
||||
return @"Dark";
|
||||
default:
|
||||
return @"Unspecified";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection traits) {
|
||||
NSMutableArray<NSDictionary *> *props = [NSMutableArray array];
|
||||
[props addObject:@{ @"userInterfaceIdiom": AS_NSStringFromUIUserInterfaceIdiom(traits.userInterfaceIdiom) }];
|
||||
[props addObject:@{ @"containerSize": NSStringFromCGSize(traits.containerSize) }];
|
||||
[props addObject:@{ @"horizontalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.horizontalSizeClass) }];
|
||||
[props addObject:@{ @"verticalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.verticalSizeClass) }];
|
||||
[props addObject:@{ @"horizontalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.horizontalSizeClass) }];
|
||||
[props addObject:@{ @"displayScale": [NSString stringWithFormat: @"%.0lf", (double)traits.displayScale] }];
|
||||
[props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }];
|
||||
[props addObject:@{ @"userInterfaceIdiom": AS_NSStringFromUIUserInterfaceIdiom(traits.userInterfaceIdiom) }];
|
||||
[props addObject:@{ @"forceTouchCapability": AS_NSStringFromUIForceTouchCapability(traits.forceTouchCapability) }];
|
||||
[props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }];
|
||||
#if TARGET_OS_TV
|
||||
[props addObject:@{ @"userInterfaceStyle": AS_NSStringFromUIUserInterfaceStyle(traits.userInterfaceStyle) }];
|
||||
#endif
|
||||
[props addObject:@{ @"preferredContentSizeCategory": (UIContentSizeCategory)traits.preferredContentSizeCategory }];
|
||||
[props addObject:@{ @"containerSize": NSStringFromCGSize(traits.containerSize) }];
|
||||
return ASObjectDescriptionMakeWithoutObject(props);
|
||||
}
|
||||
|
||||
@ -120,69 +239,238 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai
|
||||
|
||||
@implementation ASTraitCollection
|
||||
|
||||
- (instancetype)initWithDisplayScale:(CGFloat)displayScale
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
containerSize:(CGSize)windowSize
|
||||
#if TARGET_OS_TV
|
||||
|
||||
- (instancetype)initWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
displayScale:(CGFloat)displayScale
|
||||
displayGamut:(UIDisplayGamut)displayGamut
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection
|
||||
userInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory
|
||||
containerSize:(CGSize)windowSize
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_displayScale = displayScale;
|
||||
_userInterfaceIdiom = userInterfaceIdiom;
|
||||
_horizontalSizeClass = horizontalSizeClass;
|
||||
_verticalSizeClass = verticalSizeClass;
|
||||
_displayScale = displayScale;
|
||||
_displayGamut = displayGamut;
|
||||
_userInterfaceIdiom = userInterfaceIdiom;
|
||||
_forceTouchCapability = forceTouchCapability;
|
||||
_layoutDirection = layoutDirection;
|
||||
_userInterfaceStyle = userInterfaceStyle;
|
||||
_preferredContentSizeCategory = preferredContentSizeCategory;
|
||||
_containerSize = windowSize;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)traitCollectionWithDisplayScale:(CGFloat)displayScale
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
containerSize:(CGSize)windowSize
|
||||
+ (instancetype)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
displayScale:(CGFloat)displayScale
|
||||
displayGamut:(UIDisplayGamut)displayGamut
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection
|
||||
userInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory
|
||||
containerSize:(CGSize)windowSize
|
||||
{
|
||||
return [[self alloc] initWithDisplayScale:displayScale
|
||||
userInterfaceIdiom:userInterfaceIdiom
|
||||
horizontalSizeClass:horizontalSizeClass
|
||||
verticalSizeClass:verticalSizeClass
|
||||
forceTouchCapability:forceTouchCapability
|
||||
containerSize:windowSize];
|
||||
return [[self alloc] initWithHorizontalSizeClass:horizontalSizeClass
|
||||
verticalSizeClass:verticalSizeClass
|
||||
displayScale:displayScale
|
||||
displayGamut:displayGamut
|
||||
userInterfaceIdiom:userInterfaceIdiom
|
||||
forceTouchCapability:forceTouchCapability
|
||||
layoutDirection:layoutDirection
|
||||
userInterfaceStyle:userIntefaceStyle
|
||||
preferredContentSizeCategory:preferredContentSizeCategory
|
||||
containerSize:windowSize];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
- (instancetype)initWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
displayScale:(CGFloat)displayScale
|
||||
displayGamut:(UIDisplayGamut)displayGamut
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory
|
||||
containerSize:(CGSize)windowSize
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_horizontalSizeClass = horizontalSizeClass;
|
||||
_verticalSizeClass = verticalSizeClass;
|
||||
_displayScale = displayScale;
|
||||
_displayGamut = displayGamut;
|
||||
_userInterfaceIdiom = userInterfaceIdiom;
|
||||
_forceTouchCapability = forceTouchCapability;
|
||||
_layoutDirection = layoutDirection;
|
||||
_preferredContentSizeCategory = preferredContentSizeCategory;
|
||||
_containerSize = windowSize;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
displayScale:(CGFloat)displayScale
|
||||
displayGamut:(UIDisplayGamut)displayGamut
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory
|
||||
containerSize:(CGSize)windowSize
|
||||
{
|
||||
return [[self alloc] initWithHorizontalSizeClass:horizontalSizeClass
|
||||
verticalSizeClass:verticalSizeClass
|
||||
displayScale:displayScale
|
||||
displayGamut:displayGamut
|
||||
userInterfaceIdiom:userInterfaceIdiom
|
||||
forceTouchCapability:forceTouchCapability
|
||||
layoutDirection:layoutDirection
|
||||
preferredContentSizeCategory:preferredContentSizeCategory
|
||||
containerSize:windowSize];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+ (ASTraitCollection *)traitCollectionWithDisplayScale:(CGFloat)displayScale
|
||||
userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass
|
||||
verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass
|
||||
forceTouchCapability:(UIForceTouchCapability)forceTouchCapability
|
||||
containerSize:(CGSize)windowSize
|
||||
{
|
||||
#if TARGET_OS_TV
|
||||
return [self traitCollectionWithHorizontalSizeClass:horizontalSizeClass
|
||||
verticalSizeClass:verticalSizeClass
|
||||
displayScale:displayScale
|
||||
displayGamut:UIDisplayGamutUnspecified
|
||||
userInterfaceIdiom:userInterfaceIdiom
|
||||
forceTouchCapability:forceTouchCapability
|
||||
layoutDirection:UITraitEnvironmentLayoutDirectionUnspecified
|
||||
userInterfaceStyle:UIUserInterfaceStyleUnspecified
|
||||
preferredContentSizeCategory:AS_UIContentSizeCategoryUnspecified()
|
||||
containerSize:windowSize];
|
||||
#else
|
||||
return [self traitCollectionWithHorizontalSizeClass:horizontalSizeClass
|
||||
verticalSizeClass:verticalSizeClass
|
||||
displayScale:displayScale
|
||||
displayGamut:UIDisplayGamutUnspecified
|
||||
userInterfaceIdiom:userInterfaceIdiom
|
||||
forceTouchCapability:forceTouchCapability
|
||||
layoutDirection:UITraitEnvironmentLayoutDirectionUnspecified
|
||||
preferredContentSizeCategory:AS_UIContentSizeCategoryUnspecified()
|
||||
containerSize:windowSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (instancetype)traitCollectionWithASPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traits
|
||||
{
|
||||
return [self traitCollectionWithDisplayScale:traits.displayScale
|
||||
userInterfaceIdiom:traits.userInterfaceIdiom
|
||||
horizontalSizeClass:traits.horizontalSizeClass
|
||||
verticalSizeClass:traits.verticalSizeClass
|
||||
forceTouchCapability:traits.forceTouchCapability
|
||||
containerSize:traits.containerSize];
|
||||
#if TARGET_OS_TV
|
||||
return [self traitCollectionWithHorizontalSizeClass:traits.horizontalSizeClass
|
||||
verticalSizeClass:traits.verticalSizeClass
|
||||
displayScale:traits.displayScale
|
||||
displayGamut:traits.displayGamut
|
||||
userInterfaceIdiom:traits.userInterfaceIdiom
|
||||
forceTouchCapability:traits.forceTouchCapability
|
||||
layoutDirection:traits.layoutDirection
|
||||
userInterfaceStyle:traits.userInterfaceStyle
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)traits.preferredContentSizeCategory
|
||||
containerSize:traits.containerSize];
|
||||
#else
|
||||
return [self traitCollectionWithHorizontalSizeClass:traits.horizontalSizeClass
|
||||
verticalSizeClass:traits.verticalSizeClass
|
||||
displayScale:traits.displayScale
|
||||
displayGamut:traits.displayGamut
|
||||
userInterfaceIdiom:traits.userInterfaceIdiom
|
||||
forceTouchCapability:traits.forceTouchCapability
|
||||
layoutDirection:traits.layoutDirection
|
||||
preferredContentSizeCategory:(UIContentSizeCategory)traits.preferredContentSizeCategory
|
||||
containerSize:traits.containerSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (instancetype)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection
|
||||
containerSize:(CGSize)windowSize
|
||||
containerSize:(CGSize)windowSize
|
||||
{
|
||||
return [self traitCollectionWithDisplayScale:traitCollection.displayScale
|
||||
userInterfaceIdiom:traitCollection.userInterfaceIdiom
|
||||
horizontalSizeClass:traitCollection.horizontalSizeClass
|
||||
verticalSizeClass:traitCollection.verticalSizeClass
|
||||
forceTouchCapability:traitCollection.forceTouchCapability
|
||||
containerSize:windowSize];
|
||||
return [self traitCollectionWithUITraitCollection:traitCollection
|
||||
containerSize:windowSize
|
||||
fallbackContentSizeCategory:AS_UIContentSizeCategoryUnspecified()];
|
||||
}
|
||||
|
||||
|
||||
+ (instancetype)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection
|
||||
containerSize:(CGSize)windowSize
|
||||
fallbackContentSizeCategory:(UIContentSizeCategory)fallbackContentSizeCategory
|
||||
{
|
||||
UIDisplayGamut displayGamut;
|
||||
UITraitEnvironmentLayoutDirection layoutDirection;
|
||||
UIContentSizeCategory sizeCategory;
|
||||
#if TARGET_OS_TV
|
||||
UIUserInterfaceStyle userInterfaceStyle;
|
||||
#endif
|
||||
if (AS_AVAILABLE_IOS(10)) {
|
||||
displayGamut = traitCollection.displayGamut;
|
||||
layoutDirection = traitCollection.layoutDirection;
|
||||
sizeCategory = traitCollection.preferredContentSizeCategory;
|
||||
#if TARGET_OS_TV
|
||||
userInterfaceStyle = traitCollection.userInterfaceStyle;
|
||||
#endif
|
||||
} else {
|
||||
displayGamut = UIDisplayGamutUnspecified;
|
||||
layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified;
|
||||
sizeCategory = fallbackContentSizeCategory;
|
||||
#if TARGET_OS_TV
|
||||
userInterfaceStyle = UIUserInterfaceStyleUnspecified;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV
|
||||
return [self traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass
|
||||
verticalSizeClass:traitCollection.verticalSizeClass
|
||||
displayScale:traitCollection.displayScale
|
||||
displayGamut:displayGamut
|
||||
userInterfaceIdiom:traitCollection.userInterfaceIdiom
|
||||
forceTouchCapability:traitCollection.forceTouchCapability
|
||||
layoutDirection:layoutDirection
|
||||
userInterfaceStyle:userInterfaceStyle
|
||||
preferredContentSizeCategory:sizeCategory
|
||||
containerSize:windowSize];
|
||||
#else
|
||||
return [self traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass
|
||||
verticalSizeClass:traitCollection.verticalSizeClass
|
||||
displayScale:traitCollection.displayScale
|
||||
displayGamut:displayGamut
|
||||
userInterfaceIdiom:traitCollection.userInterfaceIdiom
|
||||
forceTouchCapability:traitCollection.forceTouchCapability
|
||||
layoutDirection:layoutDirection
|
||||
preferredContentSizeCategory:sizeCategory
|
||||
containerSize:windowSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (ASPrimitiveTraitCollection)primitiveTraitCollection
|
||||
{
|
||||
return (ASPrimitiveTraitCollection) {
|
||||
.displayScale = self.displayScale,
|
||||
.horizontalSizeClass = self.horizontalSizeClass,
|
||||
.userInterfaceIdiom = self.userInterfaceIdiom,
|
||||
.verticalSizeClass = self.verticalSizeClass,
|
||||
.displayScale = self.displayScale,
|
||||
.displayGamut = self.displayGamut,
|
||||
.userInterfaceIdiom = self.userInterfaceIdiom,
|
||||
.forceTouchCapability = self.forceTouchCapability,
|
||||
.layoutDirection = self.layoutDirection,
|
||||
#if TARGET_OS_TV
|
||||
.userInterfaceStyle = self.userInterfaceStyle,
|
||||
#endif
|
||||
.preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(self.preferredContentSizeCategory),
|
||||
.containerSize = self.containerSize,
|
||||
};
|
||||
}
|
||||
@ -193,12 +481,19 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai
|
||||
return YES;
|
||||
}
|
||||
|
||||
return self.displayScale == traitCollection.displayScale &&
|
||||
self.horizontalSizeClass == traitCollection.horizontalSizeClass &&
|
||||
self.verticalSizeClass == traitCollection.verticalSizeClass &&
|
||||
self.userInterfaceIdiom == traitCollection.userInterfaceIdiom &&
|
||||
CGSizeEqualToSize(self.containerSize, traitCollection.containerSize) &&
|
||||
self.forceTouchCapability == traitCollection.forceTouchCapability;
|
||||
return
|
||||
self.horizontalSizeClass == traitCollection.horizontalSizeClass &&
|
||||
self.verticalSizeClass == traitCollection.verticalSizeClass &&
|
||||
self.displayScale == traitCollection.displayScale &&
|
||||
self.displayGamut == traitCollection.displayGamut &&
|
||||
self.userInterfaceIdiom == traitCollection.userInterfaceIdiom &&
|
||||
self.forceTouchCapability == traitCollection.forceTouchCapability &&
|
||||
self.layoutDirection == traitCollection.layoutDirection &&
|
||||
#if TARGET_OS_TV
|
||||
self.userInterfaceStyle == traitCollection.userInterfaceStyle &&
|
||||
#endif
|
||||
[self.preferredContentSizeCategory isEqualToString:traitCollection.preferredContentSizeCategory] &&
|
||||
CGSizeEqualToSize(self.containerSize, traitCollection.containerSize);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -1097,7 +1097,7 @@
|
||||
[window layoutIfNeeded];
|
||||
|
||||
// The initial reload is async, changing the trait collection here should be "mid-update"
|
||||
ASPrimitiveTraitCollection traitCollection;
|
||||
ASPrimitiveTraitCollection traitCollection = ASPrimitiveTraitCollectionMakeDefault();
|
||||
traitCollection.displayScale = cn.primitiveTraitCollection.displayScale + 1; // Just a dummy change
|
||||
traitCollection.containerSize = screenBounds.size;
|
||||
cn.primitiveTraitCollection = traitCollection;
|
||||
|
||||
34
Tests/ASTraitCollectionTests.m
Normal file
34
Tests/ASTraitCollectionTests.m
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// ASTraitCollectionTests.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
|
||||
// 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
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import <AsyncDisplayKit/ASTraitCollection.h>
|
||||
|
||||
@interface ASTraitCollectionTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASTraitCollectionTests
|
||||
|
||||
- (void)testPrimitiveContentSizeCategoryLifetime
|
||||
{
|
||||
ASPrimitiveContentSizeCategory primitiveContentSize;
|
||||
@autoreleasepool {
|
||||
// Make sure the compiler won't optimize string alloc/dealloc
|
||||
NSString *contentSizeCategory = [NSString stringWithCString:"UICTContentSizeCategoryL" encoding:NSUTF8StringEncoding];
|
||||
primitiveContentSize = ASPrimitiveContentSizeCategoryMake(contentSizeCategory);
|
||||
}
|
||||
|
||||
XCTAssertEqual(primitiveContentSize, UIContentSizeCategoryLarge);
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
x
Reference in New Issue
Block a user