line break mode for ios

Summary:
What do you think is ```lineBreakMode``` a good name? For android it is called ```ellipsize```.

<img src="https://cloud.githubusercontent.com/assets/1488195/15628555/7372f8d0-250c-11e6-8919-722f28a38d60.png"" width="300" />
Closes https://github.com/facebook/react-native/pull/7819

Differential Revision: D3417256

fbshipit-source-id: 189441a23ff554bf7f6d67fa8510959351e9e5cc
This commit is contained in:
Sokovikov 2016-06-10 04:26:45 -07:00 committed by Facebook Github Bot 3
parent 33dfc9db92
commit c03b166854
9 changed files with 70 additions and 8 deletions

View File

@ -388,6 +388,17 @@ var TextExample = React.createClass({
Demo text shadow
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Line break mode">
<Text numberOfLines={1}>
This very long text should be truncated with dots in the end.
</Text>
<Text lineBreakMode="middle" numberOfLines={1}>
This very long text should be truncated with dots in the middle.
</Text>
<Text lineBreakMode="head" numberOfLines={1}>
This very long text should be truncated with dots in the beginning.
</Text>
</UIExplorerBlock>
</UIExplorerPage>
);
}

View File

@ -444,6 +444,26 @@ exports.examples = [
</View>
);
},
}, {
title: 'Line break mode',
render: function() {
return (
<View>
<Text numberOfLines={1}>
This very long text should be truncated with dots in the end.
</Text>
<Text lineBreakMode="middle" numberOfLines={1}>
This very long text should be truncated with dots in the middle.
</Text>
<Text lineBreakMode="head" numberOfLines={1}>
This very long text should be truncated with dots in the beginning.
</Text>
<Text lineBreakMode="clip" numberOfLines={1}>
This very looooooooooooooooooooooooooooong text should be clipped.
</Text>
</View>
);
},
}];
var styles = StyleSheet.create({

View File

@ -24,6 +24,7 @@ extern NSString *const RCTReactTagAttributeName;
@property (nonatomic, assign) CGFloat letterSpacing;
@property (nonatomic, assign) CGFloat lineHeight;
@property (nonatomic, assign) NSUInteger numberOfLines;
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;
@property (nonatomic, assign) CGSize shadowOffset;
@property (nonatomic, assign) NSTextAlignment textAlign;
@property (nonatomic, assign) NSWritingDirection writingDirection;

View File

@ -17,6 +17,7 @@
#import "RCTShadowRawText.h"
#import "RCTText.h"
#import "RCTUtils.h"
#import "RCTConvert.h"
NSString *const RCTShadowViewAttributeName = @"RCTShadowViewAttributeName";
NSString *const RCTIsHighlightedAttributeName = @"IsHighlightedAttributeName";
@ -166,7 +167,13 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
NSTextContainer *textContainer = [NSTextContainer new];
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = _numberOfLines > 0 ? NSLineBreakByTruncatingTail : NSLineBreakByClipping;
if (_numberOfLines > 0) {
textContainer.lineBreakMode = _lineBreakMode;
} else {
textContainer.lineBreakMode = NSLineBreakByClipping;
}
textContainer.maximumNumberOfLines = _numberOfLines;
textContainer.size = (CGSize){widthMode == CSS_MEASURE_MODE_UNDEFINED ? CGFLOAT_MAX : width, CGFLOAT_MAX};
@ -451,6 +458,7 @@ RCT_TEXT_PROPERTY(IsHighlighted, _isHighlighted, BOOL)
RCT_TEXT_PROPERTY(LetterSpacing, _letterSpacing, CGFloat)
RCT_TEXT_PROPERTY(LineHeight, _lineHeight, CGFloat)
RCT_TEXT_PROPERTY(NumberOfLines, _numberOfLines, NSUInteger)
RCT_TEXT_PROPERTY(LineBreakMode, _lineBreakMode, NSLineBreakMode)
RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment)
RCT_TEXT_PROPERTY(TextDecorationColor, _textDecorationColor, UIColor *);
RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationLineType);

View File

@ -64,6 +64,7 @@ RCT_EXPORT_SHADOW_PROPERTY(isHighlighted, BOOL)
RCT_EXPORT_SHADOW_PROPERTY(letterSpacing, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(lineHeight, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(numberOfLines, NSUInteger)
RCT_EXPORT_SHADOW_PROPERTY(lineBreakMode, NSLineBreakMode)
RCT_EXPORT_SHADOW_PROPERTY(textAlign, NSTextAlignment)
RCT_EXPORT_SHADOW_PROPERTY(textDecorationStyle, NSUnderlineStyle)
RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, UIColor)

View File

@ -29,6 +29,7 @@ const viewConfig = {
validAttributes: merge(ReactNativeViewAttributes.UIView, {
isHighlighted: true,
numberOfLines: true,
lineBreakMode: true,
allowFontScaling: true,
}),
uiViewClassName: 'RCTText',
@ -69,6 +70,11 @@ const viewConfig = {
const Text = React.createClass({
propTypes: {
/**
* Line Break mode. Works only with numberOfLines.
* clip is working only for iOS
*/
lineBreakMode: React.PropTypes.oneOf(['head', 'middle', 'tail', 'clip']),
/**
* Used to truncate the text with an ellipsis after computing the text
* layout, including line wrapping, such that the total number of lines
@ -110,6 +116,7 @@ const Text = React.createClass({
return {
accessible: true,
allowFontScaling: true,
lineBreakMode: 'tail',
};
},
getInitialState: function(): Object {

View File

@ -248,13 +248,11 @@ NSNumber *RCTConvertMultiEnumValue(const char *typeName, NSDictionary *mapping,
}
RCT_ENUM_CONVERTER(NSLineBreakMode, (@{
@"wordWrapping": @(NSLineBreakByWordWrapping),
@"charWrapping": @(NSLineBreakByCharWrapping),
@"clipping": @(NSLineBreakByClipping),
@"truncatingHead": @(NSLineBreakByTruncatingHead),
@"truncatingTail": @(NSLineBreakByTruncatingTail),
@"truncatingMiddle": @(NSLineBreakByTruncatingMiddle),
}), NSLineBreakByWordWrapping, integerValue)
@"clip": @(NSLineBreakByClipping),
@"head": @(NSLineBreakByTruncatingHead),
@"tail": @(NSLineBreakByTruncatingTail),
@"middle": @(NSLineBreakByTruncatingMiddle),
}), NSLineBreakByTruncatingTail, integerValue)
RCT_ENUM_CONVERTER(NSTextAlignment, (@{
@"auto": @(NSTextAlignmentNatural),

View File

@ -67,6 +67,7 @@ public class ViewProps {
public static final String LINE_HEIGHT = "lineHeight";
public static final String NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
public static final String NUMBER_OF_LINES = "numberOfLines";
public static final String LINE_BREAK_MODE = "lineBreakMode";
public static final String ON = "on";
public static final String RESIZE_MODE = "resizeMode";
public static final String TEXT_ALIGN = "textAlign";

View File

@ -73,6 +73,21 @@ public class ReactTextViewManager extends BaseViewManager<ReactTextView, ReactTe
}
}
@ReactProp(name = ViewProps.LINE_BREAK_MODE)
public void setLineBreakMode(ReactTextView view, @Nullable String lineBreakMode) {
if(lineBreakMode == null) {
return;
}
if (lineBreakMode.equals("head")) {
view.setEllipsize(TextUtils.TruncateAt.START);
} else if (lineBreakMode.equals("middle")) {
view.setEllipsize(TextUtils.TruncateAt.MIDDLE);
} else if (lineBreakMode.equals("tail")) {
view.setEllipsize(TextUtils.TruncateAt.END);
}
}
@ReactProp(name = ViewProps.TEXT_ALIGN_VERTICAL)
public void setTextAlignVertical(ReactTextView view, @Nullable String textAlignVertical) {
if (textAlignVertical == null || "auto".equals(textAlignVertical)) {