Fix text view decorations, setting underline to none was not applied, setting decoration and text immediately was not applying the decoration

This commit is contained in:
Panayot Cankov
2017-02-28 18:24:31 +02:00
parent 4d81670072
commit a2e09d5db0
4 changed files with 52 additions and 65 deletions

View File

@ -126,6 +126,10 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition
callback(text); callback(text);
} }
} }
_setNativeText(): void {
//
}
} }
//Text //Text

View File

@ -87,6 +87,8 @@
* Called when the text property is changed to request layout. * Called when the text property is changed to request layout.
*/ */
_requestLayoutOnTextChanged(): void; _requestLayoutOnTextChanged(): void;
_setNativeText(): void;
//@endprivate //@endprivate
} }

View File

@ -11,10 +11,6 @@ export * from "./text-base-common";
export class TextBase extends TextBaseCommon { export class TextBase extends TextBaseCommon {
private textDecorationSet: boolean;
private textTransformSet: boolean;
private letterSpacingSet: boolean;
public nativeView: UITextField | UITextView | UILabel | UIButton; public nativeView: UITextField | UITextView | UILabel | UIButton;
//Text //Text
@ -26,17 +22,7 @@ export class TextBase extends TextBaseCommon {
return; return;
} }
const newValue = (value === undefined || value === null) ? '' : value.toString(); this._setNativeText();
const nativeView = this.nativeView;
if (this.textDecorationSet || this.textTransformSet || this.letterSpacingSet) {
const style = this.style;
this.setTextDecorationAndTransform(newValue, nativeView, style.textDecoration, style.textTransform, style.letterSpacing, style.color);
} else if (nativeView instanceof UIButton) {
nativeView.setTitleForState(newValue, UIControlState.Normal);
} else {
nativeView.text = newValue;
}
this._requestLayoutOnTextChanged(); this._requestLayoutOnTextChanged();
} }
@ -45,8 +31,7 @@ export class TextBase extends TextBaseCommon {
return null; return null;
} }
set [formattedTextProperty.native](value: FormattedString) { set [formattedTextProperty.native](value: FormattedString) {
const style = this.style; this._setNativeText();
this.setFormattedTextDecorationAndTransform(value, this.nativeView, style.textDecoration, style.textTransform, style.letterSpacing);
textProperty.nativeValueChange(this, !value ? '' : value.toString()); textProperty.nativeValueChange(this, !value ? '' : value.toString());
this._requestLayoutOnTextChanged(); this._requestLayoutOnTextChanged();
} }
@ -128,13 +113,7 @@ export class TextBase extends TextBaseCommon {
return TextDecoration.NONE; return TextDecoration.NONE;
} }
set [textDecorationProperty.native](value: TextDecoration) { set [textDecorationProperty.native](value: TextDecoration) {
this.textDecorationSet = value !== TextDecoration.NONE; this._setNativeText();
const style = this.style;
if (this.formattedText) {
this.setFormattedTextDecorationAndTransform(this.formattedText, this.nativeView, value, style.textTransform, style.letterSpacing);
} else {
this.setTextDecorationAndTransform(this.text, this.nativeView, value, style.textTransform, style.letterSpacing, style.color);
}
} }
//TextTransform //TextTransform
@ -142,13 +121,7 @@ export class TextBase extends TextBaseCommon {
return TextTransform.NONE; return TextTransform.NONE;
} }
set [textTransformProperty.native](value: TextTransform) { set [textTransformProperty.native](value: TextTransform) {
this.textTransformSet = value !== TextTransform.NONE; this._setNativeText();
const style = this.style;
if (this.formattedText) {
this.setFormattedTextDecorationAndTransform(this.formattedText, this.nativeView, style.textDecoration, value, style.letterSpacing);
} else {
this.setTextDecorationAndTransform(this.text, this.nativeView, style.textDecoration, value, style.letterSpacing, style.color);
}
} }
// LetterSpacing. // LetterSpacing.
@ -156,32 +129,36 @@ export class TextBase extends TextBaseCommon {
return 0; return 0;
} }
set [letterSpacingProperty.native](value: number) { set [letterSpacingProperty.native](value: number) {
this.letterSpacingSet = value !== 0; this._setNativeText();
const style = this.style; }
_setNativeText() {
if (this.formattedText) { if (this.formattedText) {
this.setFormattedTextDecorationAndTransform(this.formattedText, this.nativeView, style.textDecoration, style.textTransform, value); this.setFormattedTextDecorationAndTransform();
} else { } else {
this.setTextDecorationAndTransform(this.text, this.nativeView, style.textDecoration, style.textTransform, value, style.color); this.setTextDecorationAndTransform();
} }
} }
setFormattedTextDecorationAndTransform(formattedText: FormattedString, nativeView: UITextField | UITextView | UILabel | UIButton, textDecoration: TextDecoration, textTransform: TextTransform, letterSpacing: number) { setFormattedTextDecorationAndTransform() {
const attrText = this.createNSMutableAttributedString(formattedText); const attrText = this.createNSMutableAttributedString(this.formattedText);
if (letterSpacing !== 0) { if (this.letterSpacing !== 0) {
attrText.addAttributeValueRange(NSKernAttributeName, letterSpacing * nativeView.font.pointSize, { location: 0, length: attrText.length }); attrText.addAttributeValueRange(NSKernAttributeName, this.letterSpacing * this.nativeView.font.pointSize, { location: 0, length: attrText.length });
} }
if (nativeView instanceof UIButton) { if (this.nativeView instanceof UIButton) {
nativeView.setAttributedTitleForState(attrText, UIControlState.Normal); this.nativeView.setAttributedTitleForState(attrText, UIControlState.Normal);
} }
else { else {
nativeView.attributedText = attrText; this.nativeView.attributedText = attrText;
} }
} }
setTextDecorationAndTransform(text: string, nativeView: UITextField | UITextView | UILabel | UIButton, textDecoration: TextDecoration, textTransform: TextTransform, letterSpacing: number, color: Color) { setTextDecorationAndTransform() {
let dict = new Map<string, number>(); const style = this.style;
switch (textDecoration) {
let dict = new Map<string, any>();
switch (style.textDecoration) {
case TextDecoration.NONE: case TextDecoration.NONE:
break; break;
case TextDecoration.UNDERLINE: case TextDecoration.UNDERLINE:
@ -195,35 +172,42 @@ export class TextBase extends TextBaseCommon {
dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.StyleSingle); dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.StyleSingle);
break; break;
default: default:
throw new Error(`Invalid text decoration value: ${textDecoration}. Valid values are: "${TextDecoration.NONE}", "${TextDecoration.UNDERLINE}", "${TextDecoration.LINE_THROUGH}", "${TextDecoration.UNDERLINE_LINE_THROUGH}".`); throw new Error(`Invalid text decoration value: ${style.textDecoration}. Valid values are: "${TextDecoration.NONE}", "${TextDecoration.UNDERLINE}", "${TextDecoration.LINE_THROUGH}", "${TextDecoration.UNDERLINE_LINE_THROUGH}".`);
} }
if (letterSpacing !== 0) { if (style.letterSpacing !== 0) {
dict.set(NSKernAttributeName, letterSpacing * nativeView.font.pointSize); dict.set(NSKernAttributeName, style.letterSpacing * this.nativeView.font.pointSize);
} }
if (color) { if (style.color) {
dict.set(NSForegroundColorAttributeName, color.ios); dict.set(NSForegroundColorAttributeName, style.color.ios);
} }
let source = getTransformedText(text, textTransform); const text = this.text;
if (dict.size > 0) { const string = (text === undefined || text === null) ? '' : text.toString();
const source = getTransformedText(string, this.textTransform);
const isTextView = this.nativeView instanceof UITextView;
if (dict.size > 0 || isTextView) {
if (isTextView) {
// UITextView's font seems to change inside.
dict.set(NSFontAttributeName, this.nativeView.font);
}
let result = NSMutableAttributedString.alloc().initWithString(source); let result = NSMutableAttributedString.alloc().initWithString(source);
result.setAttributesRange(<any>dict, { location: 0, length: source.length }); result.setAttributesRange(<any>dict, { location: 0, length: source.length });
if (nativeView instanceof UIButton) { if (this.nativeView instanceof UIButton) {
nativeView.setAttributedTitleForState(result, UIControlState.Normal); this.nativeView.setAttributedTitleForState(result, UIControlState.Normal);
} else { } else {
nativeView.attributedText = result; this.nativeView.attributedText = result;
} }
} else { } else {
if (nativeView instanceof UIButton) { if (this.nativeView instanceof UIButton) {
// Clear attributedText or title won't be affected. // Clear attributedText or title won't be affected.
nativeView.setAttributedTitleForState(null, UIControlState.Normal); this.nativeView.setAttributedTitleForState(null, UIControlState.Normal);
nativeView.setTitleForState(source, UIControlState.Normal); this.nativeView.setTitleForState(source, UIControlState.Normal);
} else { } else {
// Clear attributedText or text won't be affected. // Clear attributedText or text won't be affected.
nativeView.attributedText = undefined; this.nativeView.attributedText = undefined;
nativeView.text = source; this.nativeView.text = source;
} }
} }
} }

View File

@ -117,11 +117,8 @@ export class TextView extends EditableTextBase implements TextViewDefinition {
} }
public showText() { public showText() {
const nativeView = this.nativeView; this.nativeView.textColor = this.color ? this.color.ios : null;
nativeView.textColor = this.color ? this.color.ios : null; this._setNativeText();
const text = this.text;
const textAsString = (text === null || text === undefined) ? '' : text.toString();
nativeView.text = textAsString;
this._isShowingHint = false; this._isShowingHint = false;
} }