Merge pull request #1437 from ejensen/editable-text-node-layout-manager

[ASEditableTextNode] Allow TextKit component customization
This commit is contained in:
appleguy 2016-03-31 20:46:19 -07:00
commit ea935456b8
10 changed files with 85 additions and 37 deletions

View File

@ -14,7 +14,8 @@ Pod::Spec.new do |spec|
'AsyncDisplayKit/Details/**/*.h',
'AsyncDisplayKit/Layout/*.h',
'Base/*.h',
'AsyncDisplayKit/TextKit/ASTextNodeTypes.h'
'AsyncDisplayKit/TextKit/ASTextNodeTypes.h',
'AsyncDisplayKit/TextKit/ASTextKitComponents.h'
]
spec.source_files = [

View File

@ -136,7 +136,7 @@
254C6B541BF8FF2A003EC431 /* ASTextKitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 254C6B531BF8FF2A003EC431 /* ASTextKitTests.mm */; };
254C6B731BF94DF4003EC431 /* ASTextKitCoreTextAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */; };
254C6B741BF94DF4003EC431 /* ASTextNodeWordKerner.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754B91BEE458E00737CA5 /* ASTextNodeWordKerner.h */; };
254C6B751BF94DF4003EC431 /* ASTextKitHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BA1BEE458E00737CA5 /* ASTextKitHelpers.h */; };
254C6B751BF94DF4003EC431 /* ASTextKitComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BA1BEE458E00737CA5 /* ASTextKitComponents.h */; settings = {ATTRIBUTES = (Public, ); }; };
254C6B761BF94DF4003EC431 /* ASTextNodeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BC1BEE458E00737CA5 /* ASTextNodeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
254C6B771BF94DF4003EC431 /* ASTextKitAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754951BEE44CD00737CA5 /* ASTextKitAttributes.h */; };
254C6B781BF94DF4003EC431 /* ASTextKitContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754961BEE44CD00737CA5 /* ASTextKitContext.h */; };
@ -148,7 +148,7 @@
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A11BEE44CD00737CA5 /* ASTextKitTailTruncater.h */; };
254C6B7F1BF94DF4003EC431 /* ASTextKitTruncating.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A31BEE44CD00737CA5 /* ASTextKitTruncating.h */; };
254C6B801BF94DF4003EC431 /* ASEqualityHashHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A41BEE44CD00737CA5 /* ASEqualityHashHelpers.h */; };
254C6B821BF94F8A003EC431 /* ASTextKitHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754B71BEE458D00737CA5 /* ASTextKitHelpers.mm */; };
254C6B821BF94F8A003EC431 /* ASTextKitComponents.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754B71BEE458D00737CA5 /* ASTextKitComponents.m */; };
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */; };
254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */; };
254C6B851BF94F8A003EC431 /* ASTextKitAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754941BEE44CD00737CA5 /* ASTextKitAttributes.mm */; };
@ -179,10 +179,10 @@
257754B41BEE44CD00737CA5 /* ASTextKitTailTruncater.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754A21BEE44CD00737CA5 /* ASTextKitTailTruncater.mm */; };
257754B51BEE44CD00737CA5 /* ASTextKitTruncating.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A31BEE44CD00737CA5 /* ASTextKitTruncating.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754B61BEE44CD00737CA5 /* ASEqualityHashHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A41BEE44CD00737CA5 /* ASEqualityHashHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754BE1BEE458E00737CA5 /* ASTextKitHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754B71BEE458D00737CA5 /* ASTextKitHelpers.mm */; };
257754BE1BEE458E00737CA5 /* ASTextKitComponents.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754B71BEE458D00737CA5 /* ASTextKitComponents.m */; };
257754BF1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */; };
257754C01BEE458E00737CA5 /* ASTextNodeWordKerner.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754B91BEE458E00737CA5 /* ASTextNodeWordKerner.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754C11BEE458E00737CA5 /* ASTextKitHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BA1BEE458E00737CA5 /* ASTextKitHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754C11BEE458E00737CA5 /* ASTextKitComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BA1BEE458E00737CA5 /* ASTextKitComponents.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754C21BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754C31BEE458E00737CA5 /* ASTextNodeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BC1BEE458E00737CA5 /* ASTextNodeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
257754C41BEE458E00737CA5 /* ASTextNodeWordKerner.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */; };
@ -712,10 +712,10 @@
257754A21BEE44CD00737CA5 /* ASTextKitTailTruncater.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitTailTruncater.mm; path = TextKit/ASTextKitTailTruncater.mm; sourceTree = "<group>"; };
257754A31BEE44CD00737CA5 /* ASTextKitTruncating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitTruncating.h; path = TextKit/ASTextKitTruncating.h; sourceTree = "<group>"; };
257754A41BEE44CD00737CA5 /* ASEqualityHashHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASEqualityHashHelpers.h; path = TextKit/ASEqualityHashHelpers.h; sourceTree = "<group>"; };
257754B71BEE458D00737CA5 /* ASTextKitHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitHelpers.mm; path = TextKit/ASTextKitHelpers.mm; sourceTree = "<group>"; };
257754B71BEE458D00737CA5 /* ASTextKitComponents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextKitComponents.m; path = TextKit/ASTextKitComponents.m; sourceTree = "<group>"; };
257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextKitCoreTextAdditions.m; path = TextKit/ASTextKitCoreTextAdditions.m; sourceTree = "<group>"; };
257754B91BEE458E00737CA5 /* ASTextNodeWordKerner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextNodeWordKerner.h; path = TextKit/ASTextNodeWordKerner.h; sourceTree = "<group>"; };
257754BA1BEE458E00737CA5 /* ASTextKitHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitHelpers.h; path = TextKit/ASTextKitHelpers.h; sourceTree = "<group>"; };
257754BA1BEE458E00737CA5 /* ASTextKitComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitComponents.h; path = TextKit/ASTextKitComponents.h; sourceTree = "<group>"; };
257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitCoreTextAdditions.h; path = TextKit/ASTextKitCoreTextAdditions.h; sourceTree = "<group>"; };
257754BC1BEE458E00737CA5 /* ASTextNodeTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextNodeTypes.h; path = TextKit/ASTextNodeTypes.h; sourceTree = "<group>"; };
257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextNodeWordKerner.m; path = TextKit/ASTextNodeWordKerner.m; sourceTree = "<group>"; };
@ -1254,11 +1254,11 @@
children = (
B30BF6501C5964B0004FCD53 /* ASLayoutManager.h */,
B30BF6511C5964B0004FCD53 /* ASLayoutManager.m */,
257754B71BEE458D00737CA5 /* ASTextKitHelpers.mm */,
257754BA1BEE458E00737CA5 /* ASTextKitComponents.h */,
257754B71BEE458D00737CA5 /* ASTextKitComponents.m */,
257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */,
257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */,
257754B91BEE458E00737CA5 /* ASTextNodeWordKerner.h */,
257754BA1BEE458E00737CA5 /* ASTextKitHelpers.h */,
257754BC1BEE458E00737CA5 /* ASTextNodeTypes.h */,
257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */,
257754941BEE44CD00737CA5 /* ASTextKitAttributes.mm */,
@ -1500,7 +1500,7 @@
ACF6ED311B17843500DA7C62 /* ASStaticLayoutSpec.h in Headers */,
055F1A3419ABD3E3004DAFF1 /* ASTableView.h in Headers */,
251B8EF71BBB3D690087C538 /* ASCollectionDataController.h in Headers */,
257754C11BEE458E00737CA5 /* ASTextKitHelpers.h in Headers */,
257754C11BEE458E00737CA5 /* ASTextKitComponents.h in Headers */,
B30BF6521C5964B0004FCD53 /* ASLayoutManager.h in Headers */,
0574D5E219C110940097DC25 /* ASTableViewProtocols.h in Headers */,
81EE384F1C8E94F000456208 /* ASRunLoopQueue.h in Headers */,
@ -1621,7 +1621,7 @@
DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */,
68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */,
B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */,
254C6B751BF94DF4003EC431 /* ASTextKitHelpers.h in Headers */,
254C6B751BF94DF4003EC431 /* ASTextKitComponents.h in Headers */,
B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */,
25E327571C16819500A2170C /* ASPagerNode.h in Headers */,
B35062551B010EFD0018CF92 /* ASSentinel.h in Headers */,
@ -1741,6 +1741,7 @@
058D09A4195D04C000B7D73C /* Project object */ = {
isa = PBXProject;
attributes = {
CLASSPREFIX = AS;
LastUpgradeCheck = 0720;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
@ -1947,7 +1948,7 @@
9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */,
ACF6ED301B17843500DA7C62 /* ASStackLayoutSpec.mm in Sources */,
257754BE1BEE458E00737CA5 /* ASTextKitHelpers.mm in Sources */,
257754BE1BEE458E00737CA5 /* ASTextKitComponents.m in Sources */,
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */,
ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */,
@ -2067,7 +2068,7 @@
B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */,
B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */,
B35062031B010EFD0018CF92 /* ASImageNode.mm in Sources */,
254C6B821BF94F8A003EC431 /* ASTextKitHelpers.mm in Sources */,
254C6B821BF94F8A003EC431 /* ASTextKitComponents.m in Sources */,
430E7C921B4C23F100697A4C /* ASIndexPath.m in Sources */,
34EFC7601B701C8B00AD841F /* ASInsetLayoutSpec.mm in Sources */,
34EFC75E1B701BF000AD841F /* ASInternalHelpers.mm in Sources */,

View File

@ -7,6 +7,7 @@
*/
#import <AsyncDisplayKit/ASDisplayNode.h>
#import <AsyncDisplayKit/ASTextKitComponents.h>
NS_ASSUME_NONNULL_BEGIN
@ -18,6 +19,24 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface ASEditableTextNode : ASDisplayNode
/**
* @abstract Initializes an editable text node using default TextKit components.
*
* @returns An initialized ASEditableTextNode.
*/
- (instancetype)init;
/**
* @abstract Initializes an editable text node using the provided TextKit components.
*
* @param textKitComponents The TextKit stack used to render text.
* @param placeholderTextKitComponents The TextKit stack used to render placeholder text.
*
* @returns An initialized ASEditableTextNode.
*/
- (instancetype)initWithTextKitComponents:(ASTextKitComponents *)textKitComponents
placeholderTextKitComponents:(ASTextKitComponents *)placeholderTextKitComponents;
//! @abstract The text node's delegate, which must conform to the <ASEditableTextNodeDelegate> protocol.
@property (nonatomic, readwrite, weak) id <ASEditableTextNodeDelegate> delegate;

View File

@ -12,7 +12,6 @@
#import "ASDisplayNode+Subclasses.h"
#import "ASEqualityHelpers.h"
#import "ASTextKitHelpers.h"
#import "ASTextNodeWordKerner.h"
#import "ASThread.h"
@ -93,6 +92,13 @@
#pragma mark - NSObject Overrides
- (instancetype)init
{
return [self initWithTextKitComponents:[ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero]
placeholderTextKitComponents:[ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero]];
}
- (instancetype)initWithTextKitComponents:(ASTextKitComponents *)textKitComponents
placeholderTextKitComponents:(ASTextKitComponents *)placeholderTextKitComponents
{
if (!(self = [super init]))
return nil;
@ -101,14 +107,14 @@
_scrollEnabled = YES;
// Create the scaffolding for the text view.
_textKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero];
_textKitComponents = textKitComponents;
_textKitComponents.layoutManager.delegate = self;
_wordKerner = [[ASTextNodeWordKerner alloc] init];
_returnKeyType = UIReturnKeyDefault;
_textContainerInset = UIEdgeInsetsZero;
// Create the placeholder scaffolding.
_placeholderTextKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero];
_placeholderTextKitComponents = placeholderTextKitComponents;
_placeholderTextKitComponents.layoutManager.delegate = self;
return self;

View File

@ -6,6 +6,7 @@
// Copyright © 2016 Facebook. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface ASTextNode ()
@ -13,18 +14,19 @@
@abstract An array of descending scale factors that will be applied to this text node to try to make it fit within its constrained size
@default nil (no scaling)
*/
@property (nonatomic, copy) NSArray *pointSizeScaleFactors;
@property (nullable, nonatomic, copy) NSArray *pointSizeScaleFactors;
#pragma mark - ASTextKit Customization
/**
A block to provide a hook to provide a custom NSLayoutManager to the ASTextKitRenderer
*/
@property (nonatomic, copy) NSLayoutManager * (^layoutManagerCreationBlock)(void);
@property (nullable, nonatomic, copy) NSLayoutManager * (^layoutManagerCreationBlock)(void);
/**
A block to provide a hook to provide a NSTextStorage to the Text Kit's layout manager.
A block to provide a hook to provide a NSTextStorage to the TextKit's layout manager.
*/
@property (nonatomic, copy) NSTextStorage * (^textStorageCreationBlock)(NSAttributedString *attributedString);
@property (nullable, nonatomic, copy) NSTextStorage * (^textStorageCreationBlock)(NSAttributedString *_Nullable attributedString);
@end
@end
NS_ASSUME_NONNULL_END

View File

@ -17,7 +17,7 @@
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import "ASTextKitCoreTextAdditions.h"
#import "ASTextKitHelpers.h"
#import "ASTextKitComponents.h"
#import "ASTextKitFontSizeAdjuster.h"
#import "ASTextKitRenderer.h"
#import "ASTextKitRenderer+Positioning.h"

View File

@ -15,7 +15,6 @@
#import <AsyncDisplayKit/ASButtonNode.h>
#import <AsyncDisplayKit/ASMapNode.h>
#import <AsyncDisplayKit/ASVideoNode.h>
#import <AsyncDisplayKit/ASEditableTextNode.h>
#import <AsyncDisplayKit/ASBasicImageDownloader.h>
@ -77,6 +76,7 @@
#import <AsyncDisplayKit/UICollectionViewLayout+ASConvenience.h>
#import <AsyncDisplayKit/UIView+ASConvenience.h>
#import <AsyncDisplayKit/ASRunLoopQueue.h>
#import <AsyncDisplayKit/ASTextKitComponents.h>
#import <AsyncDisplayKit/AsyncDisplayKit+Debug.h>

View File

@ -6,11 +6,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <objc/message.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ASBaseDefines.h"
#import <AsyncDisplayKit/ASBaseDefines.h>
NS_ASSUME_NONNULL_BEGIN
@ -37,8 +34,20 @@ ASDISPLAYNODE_INLINE CGSize ceilSizeValue(CGSize s)
@return An `ASTextKitComponents` containing the created components. The text view component will be nil.
@discussion The returned components will be hooked up together, so they are ready for use as a system upon return.
*/
+ (ASTextKitComponents *)componentsWithAttributedSeedString:(nullable NSAttributedString *)attributedSeedString
textContainerSize:(CGSize)textContainerSize;
+ (instancetype)componentsWithAttributedSeedString:(nullable NSAttributedString *)attributedSeedString
textContainerSize:(CGSize)textContainerSize;
/**
@abstract Creates the stack of TextKit components.
@param textStorage The NSTextStorage to use.
@param textContainerSize The size of the text-container. Typically, size specifies the constraining width of the layout, and FLT_MAX for height. Pass CGSizeZero if these components will be hooked up to a UITextView, which will manage the text container's size itself.
@param layoutManager The NSLayoutManager to use.
@return An `ASTextKitComponents` containing the created components. The text view component will be nil.
@discussion The returned components will be hooked up together, so they are ready for use as a system upon return.
*/
+ (instancetype)componentsWithTextStorage:(NSTextStorage *)textStorage
textContainerSize:(CGSize)textContainerSize
layoutManager:(NSLayoutManager *)layoutManager;
/**
@abstract Returns the bounding size for the text view's text.

View File

@ -6,7 +6,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "ASTextKitHelpers.h"
#import "ASTextKitComponents.h"
@interface ASTextKitComponents ()
@ -19,15 +19,25 @@
@implementation ASTextKitComponents
+ (ASTextKitComponents *)componentsWithAttributedSeedString:(NSAttributedString *)attributedSeedString
textContainerSize:(CGSize)textContainerSize
+ (instancetype)componentsWithAttributedSeedString:(NSAttributedString *)attributedSeedString
textContainerSize:(CGSize)textContainerSize
{
ASTextKitComponents *components = [[ASTextKitComponents alloc] init];
NSTextStorage *textStorage = attributedSeedString ? [[NSTextStorage alloc] initWithAttributedString:attributedSeedString] : [[NSTextStorage alloc] init];
// Create the TextKit component stack with our default configuration.
components.textStorage = (attributedSeedString ? [[NSTextStorage alloc] initWithAttributedString:attributedSeedString] : [[NSTextStorage alloc] init]);
return [self componentsWithTextStorage:textStorage
textContainerSize:textContainerSize
layoutManager:[[NSLayoutManager alloc] init]];
}
components.layoutManager = [[NSLayoutManager alloc] init];
+ (instancetype)componentsWithTextStorage:(NSTextStorage *)textStorage
textContainerSize:(CGSize)textContainerSize
layoutManager:(NSLayoutManager *)layoutManager
{
ASTextKitComponents *components = [[self alloc] init];
components.textStorage = textStorage;
components.layoutManager = layoutManager;
[components.textStorage addLayoutManager:components.layoutManager];
components.textContainer = [[NSTextContainer alloc] initWithSize:textContainerSize];

View File

@ -8,7 +8,7 @@
#import <XCTest/XCTest.h>
#import "ASTextKitHelpers.h"
#import "ASTextKitComponents.h"
#import "ASTextNodeTypes.h"
#import "ASTextNodeWordKerner.h"