Switch ASTextKitComponents interface C -> ObjC.

This commit is contained in:
Nadine Salter 2015-01-25 16:24:10 -08:00
parent 35d7f43fb6
commit e0f926c861
5 changed files with 50 additions and 47 deletions

View File

@ -74,12 +74,12 @@
_displayingPlaceholder = YES;
// Create the scaffolding for the text view.
_textKitComponents = ASTextKitComponentsCreate(nil, CGSizeZero);
_textKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero];
_textKitComponents.layoutManager.delegate = self;
_wordKerner = [[ASTextNodeWordKerner alloc] init];
// Create the placeholder scaffolding.
_placeholderTextKitComponents = ASTextKitComponentsCreate(nil, CGSizeZero);
_placeholderTextKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero];
_placeholderTextKitComponents.layoutManager.delegate = self;
return self;
@ -134,7 +134,7 @@
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
{
ASTextKitComponents *displayedComponents = [self isDisplayingPlaceholder] ? _placeholderTextKitComponents : _textKitComponents;
CGSize textSize = ASTextKitComponentsSizeForConstrainedWidth(displayedComponents, constrainedSize.width);
CGSize textSize = [displayedComponents sizeForConstrainedWidth:constrainedSize.width];
return CGSizeMake(constrainedSize.width, fminf(textSize.height, constrainedSize.height));
}

View File

@ -505,7 +505,8 @@ static const CGFloat ASTextNodeRendererTextCapHeightPadding = 1.3;
CGRect lastLineRect = [_layoutManager lineFragmentRectForGlyphAtIndex:lastVisibleGlyphIndex effectiveRange:NULL];
// Calculate the bounding rectangle for the truncation message
ASTextKitComponents *truncationComponents = ASTextKitComponentsCreate(_truncationString, constrainedRect.size);
ASTextKitComponents *truncationComponents = [ASTextKitComponents componentsWithAttributedSeedString:_truncationString
textContainerSize:constrainedRect.size];
// Size the truncation message
[truncationComponents.layoutManager ensureLayoutForTextContainer:truncationComponents.textContainer];

View File

@ -13,26 +13,27 @@
@interface ASTextKitComponents : NSObject
/**
@abstract Creates the stack of TextKit components.
@param attributedSeedString The attributed string to seed the returned text storage with, or nil to receive an blank text storage.
@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.
@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:(NSAttributedString *)attributedSeedString
textContainerSize:(CGSize)textContainerSize;
/**
@abstract Returns the bounding size for the text view's text.
@param components The TextKit components to calculate the constrained size of the text for.
@param constrainedWidth The constraining width to be used during text-sizing. Usually, this value should be the receiver's calculated size.
@result A CGSize representing the bounding size for the receiver's text.
*/
- (CGSize)sizeForConstrainedWidth:(CGFloat)constrainedWidth;
@property (nonatomic, strong) NSTextStorage *textStorage;
@property (nonatomic, strong) NSTextContainer *textContainer;
@property (nonatomic, strong) NSLayoutManager *layoutManager;
@property (nonatomic, strong) UITextView *textView;
@end
// Convenience.
/**
@abstract Creates the stack of TextKit components.
@param attributedSeedString The attributed string to sed the returned text storage with, or nil to receive an blank text storage.
@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.
@return A `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.
*/
extern ASTextKitComponents *ASTextKitComponentsCreate(NSAttributedString *attributedSeedString, CGSize textContainerSize);
/**
@abstract Returns the bounding size for the text view's text.
@param components The TextKit components to calculate the constrained size of the text for.
@param constrainedWidth The constraining width to be used during text-sizing. Usually, this value should be the receiver's calculated size.
@result A CGSize representing the bounding size for the receiver's text.
*/
extern CGSize ASTextKitComponentsSizeForConstrainedWidth(ASTextKitComponents *components, CGFloat constrainedWidth);

View File

@ -10,26 +10,8 @@
@implementation ASTextKitComponents
@end
#pragma mark - Convenience
CGSize ASTextKitComponentsSizeForConstrainedWidth(ASTextKitComponents *components, CGFloat constrainedWidth)
{
// If our text-view's width is already the constrained width, we can use our existing TextKit stack for this sizing calculation.
// Otherwise, we create a temporary stack to size for `constrainedWidth`.
if (CGRectGetWidth(components.textView.bounds) != constrainedWidth) {
components = ASTextKitComponentsCreate(components.textStorage, CGSizeMake(constrainedWidth, FLT_MAX));
}
// Force glyph generation and layout, which may not have happened yet (and isn't triggered by -usedRectForTextContainer:).
[components.layoutManager ensureLayoutForTextContainer:components.textContainer];
CGSize textSize = [components.layoutManager usedRectForTextContainer:components.textContainer].size;
return textSize;
}
ASTextKitComponents *ASTextKitComponentsCreate(NSAttributedString *attributedSeedString, CGSize textContainerSize)
+ (ASTextKitComponents *)componentsWithAttributedSeedString:(NSAttributedString *)attributedSeedString
textContainerSize:(CGSize)textContainerSize
{
ASTextKitComponents *components = [[ASTextKitComponents alloc] init];
@ -45,3 +27,22 @@ ASTextKitComponents *ASTextKitComponentsCreate(NSAttributedString *attributedSee
return components;
}
- (CGSize)sizeForConstrainedWidth:(CGFloat)constrainedWidth
{
ASTextKitComponents *components = self;
// If our text-view's width is already the constrained width, we can use our existing TextKit stack for this sizing calculation.
// Otherwise, we create a temporary stack to size for `constrainedWidth`.
if (CGRectGetWidth(components.textView.bounds) != constrainedWidth) {
components = [ASTextKitComponents componentsWithAttributedSeedString:components.textStorage textContainerSize:CGSizeMake(constrainedWidth, FLT_MAX)];
}
// Force glyph generation and layout, which may not have happened yet (and isn't triggered by -usedRectForTextContainer:).
[components.layoutManager ensureLayoutForTextContainer:components.textContainer];
CGSize textSize = [components.layoutManager usedRectForTextContainer:components.textContainer].size;
return textSize;
}
@end

View File

@ -37,7 +37,7 @@
NSDictionary *attributes = nil;
NSString *seedString = @"Hello world";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:seedString attributes:attributes];
_components = ASTextKitComponentsCreate(attributedString, size);
_components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size];
}
- (void)setupTextKitComponentsWithWordKerning
@ -46,7 +46,7 @@
NSDictionary *attributes = @{ASTextNodeWordKerningAttributeName: @".5"};
NSString *seedString = @"Hello world";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:seedString attributes:attributes];
_components = ASTextKitComponentsCreate(attributedString, size);
_components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size];
}
- (void)setupTextKitComponentsWithWordKerningDifferentFontSizes
@ -59,7 +59,7 @@
UIFont *normalFont = [UIFont systemFontOfSize:12];
[attributedString addAttribute:NSFontAttributeName value:bigFont range:NSMakeRange(0, 1)];
[attributedString addAttribute:NSFontAttributeName value:normalFont range:NSMakeRange(1, 1)];
_components = ASTextKitComponentsCreate(attributedString, size);
_components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size];
}
- (void)testSomeGlyphsToChangeIfWordKerning
@ -76,7 +76,7 @@
UIFont *font = [UIFont systemFontOfSize:12.0];
NSDictionary *attributes = @{NSFontAttributeName : font};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@" " attributes:attributes];
_components = ASTextKitComponentsCreate(attributedString, size);
_components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size];
CGFloat expectedWidth = [@" " sizeWithAttributes:@{ NSFontAttributeName : font }].width;
CGRect boundingBox = [_layoutManagerDelegate layoutManager:_components.layoutManager boundingBoxForControlGlyphAtIndex:0 forTextContainer:_components.textContainer proposedLineFragment:CGRectZero glyphPosition:CGPointZero characterIndex:0];
@ -93,7 +93,7 @@
NSDictionary *attributes = @{ASTextNodeWordKerningAttributeName: @(kernValue),
NSFontAttributeName : font};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@" " attributes:attributes];
_components = ASTextKitComponentsCreate(attributedString, size);
_components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size];
CGFloat expectedWidth = [@" " sizeWithAttributes:@{ NSFontAttributeName : font }].width + kernValue;
CGRect boundingBox = [_layoutManagerDelegate layoutManager:_components.layoutManager boundingBoxForControlGlyphAtIndex:0 forTextContainer:_components.textContainer proposedLineFragment:CGRectZero glyphPosition:CGPointZero characterIndex:0];
@ -137,7 +137,7 @@
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:seedString attributes:attributes];
UIFont *normalFont = [UIFont systemFontOfSize:12];
[attributedString addAttribute:NSFontAttributeName value:normalFont range:NSMakeRange(0, 1)];
_components = ASTextKitComponentsCreate(attributedString, size);
_components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size];
CGPoint glyphPosition = CGPointMake(42, 54);