From ac28aeda18444d26a256d9fa5e735e37f1fbff21 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Fri, 20 Jul 2018 19:11:16 +0200 Subject: [PATCH 01/33] define and use nativeTextViewProtected for all text configuration related operations. This is to separate layout operations from text operations --- .../editable-text-base.android.ts | 42 +++++------ .../editable-text-base.ios.ts | 18 ++--- tns-core-modules/ui/label/label.android.ts | 3 +- tns-core-modules/ui/label/label.ios.ts | 26 +++---- .../ui/text-base/text-base-common.ts | 5 +- .../ui/text-base/text-base.android.ts | 69 +++++++++--------- tns-core-modules/ui/text-base/text-base.d.ts | 2 + .../ui/text-base/text-base.ios.ts | 57 +++++++-------- .../ui/text-field/text-field.ios.ts | 20 +++--- .../ui/text-view/text-view.android.ts | 2 +- .../ui/text-view/text-view.ios.ts | 70 +++++++++---------- 11 files changed, 161 insertions(+), 153 deletions(-) diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts index 0767442e9c..29f787e161 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts @@ -177,13 +177,13 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { public disposeNativeView(): void { super.disposeNativeView(); - (this.nativeViewProtected).listener.owner = null; + (this.nativeTextViewProtected).listener.owner = null; this._keyListenerCache = null; } public resetNativeView(): void { super.resetNativeView(); - this.nativeViewProtected.setInputType(this._inputType); + this.nativeTextViewProtected.setInputType(this._inputType); } public onUnloaded() { @@ -192,7 +192,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public dismissSoftInput() { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (!nativeView) { return; } @@ -201,21 +201,21 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public focus(): boolean { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (!nativeView) { return; } const result = super.focus(); if (result) { - ad.showSoftInput(this.nativeViewProtected); + ad.showSoftInput(this.nativeTextViewProtected); } return result; } public _setInputType(inputType: number): void { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; try { this._changeFromCode = true; nativeView.setInputType(inputType); @@ -248,7 +248,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } [keyboardTypeProperty.getDefault](): number { - return this.nativeViewProtected.getInputType(); + return this.nativeTextViewProtected.getInputType(); } [keyboardTypeProperty.setNative](value: "datetime" | "phone" | "number" | "url" | "email" | number) { let newInputType; @@ -282,7 +282,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } [returnKeyTypeProperty.getDefault](): "done" | "next" | "go" | "search" | "send" | string { - let ime = this.nativeViewProtected.getImeOptions(); + let ime = this.nativeTextViewProtected.getImeOptions(); switch (ime) { case android.view.inputmethod.EditorInfo.IME_ACTION_DONE: return "done"; @@ -331,11 +331,11 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { break; } - this.nativeViewProtected.setImeOptions(newImeOptions); + this.nativeTextViewProtected.setImeOptions(newImeOptions); } [editableProperty.setNative](value: boolean) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (value) { nativeView.setKeyListener(this._keyListenerCache); } else { @@ -347,7 +347,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } [autocapitalizationTypeProperty.getDefault](): "none" | "words" | "sentences" | "allcharacters" | string { - let inputType = this.nativeViewProtected.getInputType(); + let inputType = this.nativeTextViewProtected.getInputType(); if ((inputType & android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS) === android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS) { return "words"; } else if ((inputType & android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) === android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) { @@ -359,7 +359,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } } [autocapitalizationTypeProperty.setNative](value: string) { - let inputType = this.nativeViewProtected.getInputType(); + let inputType = this.nativeTextViewProtected.getInputType(); inputType = inputType & ~28672; //28672 (0x00070000) 13,14,15bits (111 0000 0000 0000) switch (value) { @@ -390,7 +390,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } [autocorrectProperty.getDefault](): boolean { - let autocorrect = this.nativeViewProtected.getInputType(); + let autocorrect = this.nativeTextViewProtected.getInputType(); if ((autocorrect & android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) === android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) { return true; } @@ -398,7 +398,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { return false; } [autocorrectProperty.setNative](value: boolean) { - let inputType = this.nativeViewProtected.getInputType(); + let inputType = this.nativeTextViewProtected.getInputType(); switch (value) { case true: inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE; @@ -419,19 +419,19 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } [hintProperty.getDefault](): string { - return this.nativeViewProtected.getHint(); + return this.nativeTextViewProtected.getHint(); } [hintProperty.setNative](value: string) { const text = (value === null || value === undefined) ? null : value.toString(); - this.nativeViewProtected.setHint(text); + this.nativeTextViewProtected.setHint(text); } [placeholderColorProperty.getDefault](): android.content.res.ColorStateList { - return this.nativeViewProtected.getHintTextColors(); + return this.nativeTextViewProtected.getHintTextColors(); } [placeholderColorProperty.setNative](value: Color | android.content.res.ColorStateList) { const color = value instanceof Color ? value.android : value; - this.nativeViewProtected.setHintTextColor(color); + this.nativeTextViewProtected.setHintTextColor(color); } [textTransformProperty.setNative](value: "default") { @@ -440,10 +440,10 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { [maxLengthProperty.setNative](value: number) { if (value === Number.POSITIVE_INFINITY) { - this.nativeViewProtected.setFilters([]); + this.nativeTextViewProtected.setFilters([]); } else { const lengthFilter = new android.text.InputFilter.LengthFilter(value); - const filters = this.nativeViewProtected.getFilters(); + const filters = this.nativeTextViewProtected.getFilters(); const newFilters = []; // retain existing filters @@ -455,7 +455,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } newFilters.push(lengthFilter); - this.nativeViewProtected.setFilters(newFilters); + this.nativeTextViewProtected.setFilters(newFilters); } } } diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.ios.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.ios.ts index 1cd401f938..189e796aa3 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.ios.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.ios.ts @@ -9,12 +9,12 @@ export * from "./editable-text-base-common"; export abstract class EditableTextBase extends EditableTextBaseCommon { public nativeViewProtected: UITextField | UITextView; public dismissSoftInput() { - this.nativeViewProtected.resignFirstResponder(); + this.nativeTextViewProtected.resignFirstResponder(); this.notify({ eventName: EditableTextBase.blurEvent, object: this }); } [keyboardTypeProperty.getDefault](): "datetime" | "phone" | "number" | "url" | "email" | string { - let keyboardType = this.nativeViewProtected.keyboardType; + let keyboardType = this.nativeTextViewProtected.keyboardType; switch (keyboardType) { case UIKeyboardType.NumbersAndPunctuation: return "number"; @@ -65,11 +65,11 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { break; } - this.nativeViewProtected.keyboardType = newKeyboardType; + this.nativeTextViewProtected.keyboardType = newKeyboardType; } [returnKeyTypeProperty.getDefault](): "done" | "next" | "go" | "search" | "send" | string { - let returnKeyType = this.nativeViewProtected.returnKeyType; + let returnKeyType = this.nativeTextViewProtected.returnKeyType; switch (returnKeyType) { case UIReturnKeyType.Done: return "done"; @@ -118,11 +118,11 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { break; } - this.nativeViewProtected.returnKeyType = newValue; + this.nativeTextViewProtected.returnKeyType = newValue; } [autocapitalizationTypeProperty.getDefault](): "none" | "words" | "sentences" | "allcharacters" { - let autocapitalizationType = this.nativeViewProtected.autocapitalizationType; + let autocapitalizationType = this.nativeTextViewProtected.autocapitalizationType; switch (autocapitalizationType) { case UITextAutocapitalizationType.None: return "none"; @@ -160,11 +160,11 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { break; } - this.nativeViewProtected.autocapitalizationType = newValue; + this.nativeTextViewProtected.autocapitalizationType = newValue; } [autocorrectProperty.getDefault](): boolean | number { - let autocorrectionType = this.nativeViewProtected.autocorrectionType; + let autocorrectionType = this.nativeTextViewProtected.autocorrectionType; switch (autocorrectionType) { case UITextAutocorrectionType.Yes: return true; @@ -184,7 +184,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { newValue = UITextAutocorrectionType.No; } - this.nativeViewProtected.autocorrectionType = newValue; + this.nativeTextViewProtected.autocorrectionType = newValue; } } diff --git a/tns-core-modules/ui/label/label.android.ts b/tns-core-modules/ui/label/label.android.ts index 96fca113d8..4052bb1250 100644 --- a/tns-core-modules/ui/label/label.android.ts +++ b/tns-core-modules/ui/label/label.android.ts @@ -9,6 +9,7 @@ let TextView: typeof android.widget.TextView; @CSSType("Label") export class Label extends TextBase implements LabelDefinition { nativeViewProtected: android.widget.TextView; + nativeTextViewProtected: android.widget.TextView; get textWrap(): boolean { return this.style.whiteSpace === "normal"; @@ -31,7 +32,7 @@ export class Label extends TextBase implements LabelDefinition { public initNativeView(): void { super.initNativeView(); - const textView = this.nativeViewProtected; + const textView = this.nativeTextViewProtected; textView.setSingleLine(true); textView.setEllipsize(android.text.TextUtils.TruncateAt.END); } diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index e35c13297d..ffca126b57 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -31,7 +31,7 @@ export class Label extends TextBase implements LabelDefinition { } get ios(): TNSLabel { - return this.nativeViewProtected; + return this.nativeTextViewProtected; } get textWrap(): boolean { @@ -57,7 +57,7 @@ export class Label extends TextBase implements LabelDefinition { } public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { - let nativeView = this.nativeViewProtected; + let nativeView = this.nativeTextViewProtected; if (nativeView) { const width = layout.getMeasureSpecSize(widthMeasureSpec); const widthMode = layout.getMeasureSpecMode(widthMeasureSpec); @@ -90,7 +90,7 @@ export class Label extends TextBase implements LabelDefinition { } private _measureNativeView(width: number, widthMode: number, height: number, heightMode: number): { width: number, height: number } { - const view = this.nativeViewProtected; + const view = this.nativeTextViewProtected; const nativeSize = view.textRectForBoundsLimitedToNumberOfLines( CGRectMake( @@ -106,7 +106,7 @@ export class Label extends TextBase implements LabelDefinition { } [whiteSpaceProperty.setNative](value: WhiteSpace) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; switch (value) { case "normal": nativeView.lineBreakMode = NSLineBreakMode.ByWordWrapping; @@ -124,7 +124,7 @@ export class Label extends TextBase implements LabelDefinition { if (value instanceof Background) { ios.createBackgroundUIColor(this, (color: UIColor) => { const cgColor = color ? color.CGColor : null; - this.nativeViewProtected.layer.backgroundColor = cgColor; + this.nativeTextViewProtected.layer.backgroundColor = cgColor; }, true); } @@ -132,7 +132,7 @@ export class Label extends TextBase implements LabelDefinition { } [borderTopWidthProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; nativeView.borderThickness = { top: layout.toDeviceIndependentPixels(this.effectiveBorderTopWidth), @@ -143,7 +143,7 @@ export class Label extends TextBase implements LabelDefinition { } [borderRightWidthProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; nativeView.borderThickness = { top: border.top, @@ -154,7 +154,7 @@ export class Label extends TextBase implements LabelDefinition { } [borderBottomWidthProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; nativeView.borderThickness = { top: border.top, @@ -165,7 +165,7 @@ export class Label extends TextBase implements LabelDefinition { } [borderLeftWidthProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; nativeView.borderThickness = { top: border.top, @@ -176,7 +176,7 @@ export class Label extends TextBase implements LabelDefinition { } [paddingTopProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const padding = nativeView.padding; nativeView.padding = { top: layout.toDeviceIndependentPixels(this.effectivePaddingTop), @@ -187,7 +187,7 @@ export class Label extends TextBase implements LabelDefinition { } [paddingRightProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const padding = nativeView.padding; nativeView.padding = { top: padding.top, @@ -198,7 +198,7 @@ export class Label extends TextBase implements LabelDefinition { } [paddingBottomProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const padding = nativeView.padding; nativeView.padding = { top: padding.top, @@ -209,7 +209,7 @@ export class Label extends TextBase implements LabelDefinition { } [paddingLeftProperty.setNative](value: Length) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; const padding = nativeView.padding; nativeView.padding = { top: padding.top, diff --git a/tns-core-modules/ui/text-base/text-base-common.ts b/tns-core-modules/ui/text-base/text-base-common.ts index ee7482bebe..4826bd0957 100644 --- a/tns-core-modules/ui/text-base/text-base-common.ts +++ b/tns-core-modules/ui/text-base/text-base-common.ts @@ -15,11 +15,14 @@ const CHILD_FORMATTED_TEXT = "formattedText"; const CHILD_FORMATTED_STRING = "FormattedString"; export abstract class TextBaseCommon extends View implements TextBaseDefinition { - public _isSingleLine: boolean; public text: string; public formattedText: FormattedString; + get nativeTextViewProtected() { + return this.nativeViewProtected; + } + get fontFamily(): string { return this.style.fontFamily; } diff --git a/tns-core-modules/ui/text-base/text-base.android.ts b/tns-core-modules/ui/text-base/text-base.android.ts index 07a8d8a077..e6ade7fb7e 100644 --- a/tns-core-modules/ui/text-base/text-base.android.ts +++ b/tns-core-modules/ui/text-base/text-base.android.ts @@ -49,6 +49,7 @@ function initializeTextTransformation(): void { export class TextBase extends TextBaseCommon { nativeViewProtected: android.widget.TextView; + nativeTextViewProtected: android.widget.TextView; private _defaultTransformationMethod: android.text.method.TransformationMethod; private _paintFlags: number; private _minHeight: number; @@ -58,7 +59,7 @@ export class TextBase extends TextBaseCommon { public initNativeView(): void { initializeTextTransformation(); - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; this._defaultTransformationMethod = nativeView.getTransformationMethod(); this._minHeight = nativeView.getMinHeight(); this._maxHeight = nativeView.getMaxHeight(); @@ -69,7 +70,7 @@ export class TextBase extends TextBaseCommon { public resetNativeView(): void { super.resetNativeView(); - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; // We reset it here too because this could be changed by multiple properties - whiteSpace, secure, textTransform nativeView.setSingleLine(this._isSingleLine); nativeView.setTransformationMethod(this._defaultTransformationMethod); @@ -111,7 +112,7 @@ export class TextBase extends TextBaseCommon { } [formattedTextProperty.setNative](value: FormattedString) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (!value) { if (nativeView instanceof android.widget.Button && nativeView.getTransformationMethod() instanceof TextTransformation) { @@ -140,7 +141,7 @@ export class TextBase extends TextBaseCommon { [textTransformProperty.setNative](value: TextTransform) { if (value === "initial") { - this.nativeViewProtected.setTransformationMethod(this._defaultTransformationMethod); + this.nativeTextViewProtected.setTransformationMethod(this._defaultTransformationMethod); return; } @@ -149,26 +150,26 @@ export class TextBase extends TextBaseCommon { return; } - this.nativeViewProtected.setTransformationMethod(new TextTransformation(this)); + this.nativeTextViewProtected.setTransformationMethod(new TextTransformation(this)); } [textAlignmentProperty.getDefault](): TextAlignment { return "initial"; } [textAlignmentProperty.setNative](value: TextAlignment) { - let verticalGravity = this.nativeViewProtected.getGravity() & android.view.Gravity.VERTICAL_GRAVITY_MASK; + let verticalGravity = this.nativeTextViewProtected.getGravity() & android.view.Gravity.VERTICAL_GRAVITY_MASK; switch (value) { case "initial": case "left": - this.nativeViewProtected.setGravity(android.view.Gravity.START | verticalGravity); + this.nativeTextViewProtected.setGravity(android.view.Gravity.START | verticalGravity); break; case "center": - this.nativeViewProtected.setGravity(android.view.Gravity.CENTER_HORIZONTAL | verticalGravity); + this.nativeTextViewProtected.setGravity(android.view.Gravity.CENTER_HORIZONTAL | verticalGravity); break; case "right": - this.nativeViewProtected.setGravity(android.view.Gravity.END | verticalGravity); + this.nativeTextViewProtected.setGravity(android.view.Gravity.END | verticalGravity); break; } } @@ -176,7 +177,7 @@ export class TextBase extends TextBaseCommon { // Overridden in TextField because setSingleLine(false) will remove methodTransformation. // and we don't want to allow TextField to be multiline [whiteSpaceProperty.setNative](value: WhiteSpace) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; switch (value) { case "initial": case "normal": @@ -191,109 +192,109 @@ export class TextBase extends TextBaseCommon { } [colorProperty.getDefault](): android.content.res.ColorStateList { - return this.nativeViewProtected.getTextColors(); + return this.nativeTextViewProtected.getTextColors(); } [colorProperty.setNative](value: Color | android.content.res.ColorStateList) { if (!this.formattedText || !(value instanceof Color)) { if (value instanceof Color) { - this.nativeViewProtected.setTextColor(value.android); + this.nativeTextViewProtected.setTextColor(value.android); } else { - this.nativeViewProtected.setTextColor(value); + this.nativeTextViewProtected.setTextColor(value); } } } [fontSizeProperty.getDefault](): { nativeSize: number } { - return { nativeSize: this.nativeViewProtected.getTextSize() }; + return { nativeSize: this.nativeTextViewProtected.getTextSize() }; } [fontSizeProperty.setNative](value: number | { nativeSize: number }) { if (!this.formattedText || (typeof value !== "number")) { if (typeof value === "number") { - this.nativeViewProtected.setTextSize(value); + this.nativeTextViewProtected.setTextSize(value); } else { - this.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize); + this.nativeTextViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize); } } } [lineHeightProperty.getDefault](): number { - return this.nativeViewProtected.getLineSpacingExtra() / layout.getDisplayDensity(); + return this.nativeTextViewProtected.getLineSpacingExtra() / layout.getDisplayDensity(); } [lineHeightProperty.setNative](value: number) { - this.nativeViewProtected.setLineSpacing(value * layout.getDisplayDensity(), 1); + this.nativeTextViewProtected.setLineSpacing(value * layout.getDisplayDensity(), 1); } [fontInternalProperty.getDefault](): android.graphics.Typeface { - return this.nativeViewProtected.getTypeface(); + return this.nativeTextViewProtected.getTypeface(); } [fontInternalProperty.setNative](value: Font | android.graphics.Typeface) { if (!this.formattedText || !(value instanceof Font)) { - this.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value); + this.nativeTextViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value); } } [textDecorationProperty.getDefault](value: number) { - return this._paintFlags = this.nativeViewProtected.getPaintFlags(); + return this._paintFlags = this.nativeTextViewProtected.getPaintFlags(); } [textDecorationProperty.setNative](value: number | TextDecoration) { switch (value) { case "none": - this.nativeViewProtected.setPaintFlags(0); + this.nativeTextViewProtected.setPaintFlags(0); break; case "underline": - this.nativeViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG); + this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG); break; case "line-through": - this.nativeViewProtected.setPaintFlags(android.graphics.Paint.STRIKE_THRU_TEXT_FLAG); + this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.STRIKE_THRU_TEXT_FLAG); break; case "underline line-through": - this.nativeViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG | android.graphics.Paint.STRIKE_THRU_TEXT_FLAG); + this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG | android.graphics.Paint.STRIKE_THRU_TEXT_FLAG); break; default: - this.nativeViewProtected.setPaintFlags(value); + this.nativeTextViewProtected.setPaintFlags(value); break; } } [letterSpacingProperty.getDefault](): number { - return org.nativescript.widgets.ViewHelper.getLetterspacing(this.nativeViewProtected); + return org.nativescript.widgets.ViewHelper.getLetterspacing(this.nativeTextViewProtected); } [letterSpacingProperty.setNative](value: number) { - org.nativescript.widgets.ViewHelper.setLetterspacing(this.nativeViewProtected, value); + org.nativescript.widgets.ViewHelper.setLetterspacing(this.nativeTextViewProtected, value); } [paddingTopProperty.getDefault](): Length { return { value: this._defaultPaddingTop, unit: "px" } } [paddingTopProperty.setNative](value: Length) { - org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0)); + org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0)); } [paddingRightProperty.getDefault](): Length { return { value: this._defaultPaddingRight, unit: "px" } } [paddingRightProperty.setNative](value: Length) { - org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0)); + org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0)); } [paddingBottomProperty.getDefault](): Length { return { value: this._defaultPaddingBottom, unit: "px" } } [paddingBottomProperty.setNative](value: Length) { - org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0)); + org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0)); } [paddingLeftProperty.getDefault](): Length { return { value: this._defaultPaddingLeft, unit: "px" } } [paddingLeftProperty.setNative](value: Length) { - org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0)); + org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0)); } _setNativeText(reset: boolean = false): void { if (reset) { - this.nativeViewProtected.setText(null); + this.nativeTextViewProtected.setText(null); return; } @@ -306,7 +307,7 @@ export class TextBase extends TextBaseCommon { transformedText = getTransformedText(stringValue, this.textTransform); } - this.nativeViewProtected.setText(transformedText); + this.nativeTextViewProtected.setText(transformedText); } } diff --git a/tns-core-modules/ui/text-base/text-base.d.ts b/tns-core-modules/ui/text-base/text-base.d.ts index 002e078dd0..6920ade23d 100644 --- a/tns-core-modules/ui/text-base/text-base.d.ts +++ b/tns-core-modules/ui/text-base/text-base.d.ts @@ -9,6 +9,8 @@ export * from "../core/view"; export { FormattedString } from "../../text/formatted-string"; export class TextBase extends View implements AddChildFromBuilder { + + public readonly nativeTextViewProtected: any; /** * Gets or sets the text. */ diff --git a/tns-core-modules/ui/text-base/text-base.ios.ts b/tns-core-modules/ui/text-base/text-base.ios.ts index 5e109800a0..49d14afb10 100644 --- a/tns-core-modules/ui/text-base/text-base.ios.ts +++ b/tns-core-modules/ui/text-base/text-base.ios.ts @@ -11,6 +11,7 @@ export * from "./text-base-common"; export class TextBase extends TextBaseCommon { public nativeViewProtected: UITextField | UITextView | UILabel | UIButton; + public nativeTextViewProtected: UITextField | UITextView | UILabel | UIButton; [textProperty.getDefault](): number | symbol { return resetSymbol; @@ -32,7 +33,7 @@ export class TextBase extends TextBaseCommon { } [colorProperty.getDefault](): UIColor { - let nativeView = this.nativeViewProtected; + let nativeView = this.nativeTextViewProtected; if (nativeView instanceof UIButton) { return nativeView.titleColorForState(UIControlState.Normal); } else { @@ -41,7 +42,7 @@ export class TextBase extends TextBaseCommon { } [colorProperty.setNative](value: Color | UIColor) { const color = value instanceof Color ? value.ios : value; - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (nativeView instanceof UIButton) { nativeView.setTitleColorForState(color, UIControlState.Normal); nativeView.titleLabel.textColor = color; @@ -51,13 +52,13 @@ export class TextBase extends TextBaseCommon { } [fontInternalProperty.getDefault](): UIFont { - let nativeView = this.nativeViewProtected; + let nativeView = this.nativeTextViewProtected; nativeView = nativeView instanceof UIButton ? nativeView.titleLabel : nativeView; return nativeView.font; } [fontInternalProperty.setNative](value: Font | UIFont) { if (!(value instanceof Font) || !this.formattedText) { - let nativeView = this.nativeViewProtected; + let nativeView = this.nativeTextViewProtected; nativeView = nativeView instanceof UIButton ? nativeView.titleLabel : nativeView; const font = value instanceof Font ? value.getUIFont(nativeView.font) : value; nativeView.font = font; @@ -65,7 +66,7 @@ export class TextBase extends TextBaseCommon { } [textAlignmentProperty.setNative](value: TextAlignment) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; switch (value) { case "initial": case "left": @@ -98,7 +99,7 @@ export class TextBase extends TextBaseCommon { _setNativeText(reset: boolean = false): void { if (reset) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (nativeView instanceof UIButton) { // Clear attributedText or title won't be affected. nativeView.setAttributedTitleForState(null, UIControlState.Normal); @@ -123,26 +124,26 @@ export class TextBase extends TextBaseCommon { const attrText = this.createNSMutableAttributedString(this.formattedText); // TODO: letterSpacing should be applied per Span. if (this.letterSpacing !== 0) { - attrText.addAttributeValueRange(NSKernAttributeName, this.letterSpacing * this.nativeViewProtected.font.pointSize, { location: 0, length: attrText.length }); + attrText.addAttributeValueRange(NSKernAttributeName, this.letterSpacing * this.nativeTextViewProtected.font.pointSize, { location: 0, length: attrText.length }); } if (this.style.lineHeight) { const paragraphStyle = NSMutableParagraphStyle.alloc().init(); paragraphStyle.lineSpacing = this.lineHeight; // make sure a possible previously set text alignment setting is not lost when line height is specified - paragraphStyle.alignment = (this.nativeViewProtected).textAlignment; - if (this.nativeViewProtected instanceof UILabel) { + paragraphStyle.alignment = (this.nativeTextViewProtected).textAlignment; + if (this.nativeTextViewProtected instanceof UILabel) { // make sure a possible previously set line break mode is not lost when line height is specified - paragraphStyle.lineBreakMode = this.nativeViewProtected.lineBreakMode; + paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode; } attrText.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, { location: 0, length: attrText.length }); } - if (this.nativeViewProtected instanceof UIButton) { - this.nativeViewProtected.setAttributedTitleForState(attrText, UIControlState.Normal); + if (this.nativeTextViewProtected instanceof UIButton) { + this.nativeTextViewProtected.setAttributedTitleForState(attrText, UIControlState.Normal); } else { - this.nativeViewProtected.attributedText = attrText; + this.nativeTextViewProtected.attributedText = attrText; } } @@ -167,22 +168,22 @@ export class TextBase extends TextBaseCommon { } if (style.letterSpacing !== 0) { - dict.set(NSKernAttributeName, style.letterSpacing * this.nativeViewProtected.font.pointSize); + dict.set(NSKernAttributeName, style.letterSpacing * this.nativeTextViewProtected.font.pointSize); } if (style.lineHeight) { const paragraphStyle = NSMutableParagraphStyle.alloc().init(); paragraphStyle.lineSpacing = style.lineHeight; // make sure a possible previously set text alignment setting is not lost when line height is specified - paragraphStyle.alignment = (this.nativeViewProtected).textAlignment; - if (this.nativeViewProtected instanceof UILabel) { + paragraphStyle.alignment = (this.nativeTextViewProtected).textAlignment; + if (this.nativeTextViewProtected instanceof UILabel) { // make sure a possible previously set line break mode is not lost when line height is specified - paragraphStyle.lineBreakMode = this.nativeViewProtected.lineBreakMode; + paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode; } dict.set(NSParagraphStyleAttributeName, paragraphStyle); } - const isTextView = this.nativeViewProtected instanceof UITextView; + const isTextView = this.nativeTextViewProtected instanceof UITextView; if (style.color && (dict.size > 0 || isTextView)) { dict.set(NSForegroundColorAttributeName, style.color.ios); } @@ -193,25 +194,25 @@ export class TextBase extends TextBaseCommon { if (dict.size > 0 || isTextView) { if (isTextView) { // UITextView's font seems to change inside. - dict.set(NSFontAttributeName, this.nativeViewProtected.font); + dict.set(NSFontAttributeName, this.nativeTextViewProtected.font); } const result = NSMutableAttributedString.alloc().initWithString(source); result.setAttributesRange(dict, { location: 0, length: source.length }); - if (this.nativeViewProtected instanceof UIButton) { - this.nativeViewProtected.setAttributedTitleForState(result, UIControlState.Normal); + if (this.nativeTextViewProtected instanceof UIButton) { + this.nativeTextViewProtected.setAttributedTitleForState(result, UIControlState.Normal); } else { - this.nativeViewProtected.attributedText = result; + this.nativeTextViewProtected.attributedText = result; } } else { - if (this.nativeViewProtected instanceof UIButton) { + if (this.nativeTextViewProtected instanceof UIButton) { // Clear attributedText or title won't be affected. - this.nativeViewProtected.setAttributedTitleForState(null, UIControlState.Normal); - this.nativeViewProtected.setTitleForState(source, UIControlState.Normal); + this.nativeTextViewProtected.setAttributedTitleForState(null, UIControlState.Normal); + this.nativeTextViewProtected.setTitleForState(source, UIControlState.Normal); } else { // Clear attributedText or text won't be affected. - this.nativeViewProtected.attributedText = undefined; - this.nativeViewProtected.text = source; + this.nativeTextViewProtected.attributedText = undefined; + this.nativeTextViewProtected.text = source; } } } @@ -237,7 +238,7 @@ export class TextBase extends TextBaseCommon { } createMutableStringForSpan(span: Span, text: string): NSMutableAttributedString { - const viewFont = this.nativeViewProtected.font; + const viewFont = this.nativeTextViewProtected.font; let attrDict = <{ key: string, value: any }>{}; const style = span.style; const bold = isBold(style.fontWeight); diff --git a/tns-core-modules/ui/text-field/text-field.ios.ts b/tns-core-modules/ui/text-field/text-field.ios.ts index 59a02d8881..bfe644a739 100644 --- a/tns-core-modules/ui/text-field/text-field.ios.ts +++ b/tns-core-modules/ui/text-field/text-field.ios.ts @@ -169,33 +169,33 @@ export class TextField extends TextFieldBase { } [hintProperty.getDefault](): string { - return this.nativeViewProtected.placeholder; + return this.nativeTextViewProtected.placeholder; } [hintProperty.setNative](value: string) { this._updateAttributedPlaceholder(); } [secureProperty.getDefault](): boolean { - return this.nativeViewProtected.secureTextEntry; + return this.nativeTextViewProtected.secureTextEntry; } [secureProperty.setNative](value: boolean) { - this.nativeViewProtected.secureTextEntry = value; + this.nativeTextViewProtected.secureTextEntry = value; } [colorProperty.getDefault](): { textColor: UIColor, tintColor: UIColor } { return { - textColor: this.nativeViewProtected.textColor, - tintColor: this.nativeViewProtected.tintColor + textColor: this.nativeTextViewProtected.textColor, + tintColor: this.nativeTextViewProtected.tintColor }; } [colorProperty.setNative](value: Color | { textColor: UIColor, tintColor: UIColor }) { if (value instanceof Color) { let color = value instanceof Color ? value.ios : value; - this.nativeViewProtected.textColor = color; - this.nativeViewProtected.tintColor = color; + this.nativeTextViewProtected.textColor = color; + this.nativeTextViewProtected.tintColor = color; } else { - this.nativeViewProtected.textColor = value.textColor; - this.nativeViewProtected.tintColor = value.tintColor; + this.nativeTextViewProtected.textColor = value.textColor; + this.nativeTextViewProtected.tintColor = value.tintColor; } } @@ -223,7 +223,7 @@ export class TextField extends TextFieldBase { attributes[NSForegroundColorAttributeName] = this.style.placeholderColor.ios; } const attributedPlaceholder = NSAttributedString.alloc().initWithStringAttributes(stringValue, attributes); - this.nativeViewProtected.attributedPlaceholder = attributedPlaceholder; + this.nativeTextViewProtected.attributedPlaceholder = attributedPlaceholder; } [paddingTopProperty.getDefault](): Length { diff --git a/tns-core-modules/ui/text-view/text-view.android.ts b/tns-core-modules/ui/text-view/text-view.android.ts index dafc308024..8c316d6191 100644 --- a/tns-core-modules/ui/text-view/text-view.android.ts +++ b/tns-core-modules/ui/text-view/text-view.android.ts @@ -13,7 +13,7 @@ export class TextView extends EditableTextBase implements TextViewDefinition { public resetNativeView(): void { super.resetNativeView(); - this.nativeViewProtected.setGravity(android.view.Gravity.TOP | android.view.Gravity.START); + this.nativeTextViewProtected.setGravity(android.view.Gravity.TOP | android.view.Gravity.START); } } diff --git a/tns-core-modules/ui/text-view/text-view.ios.ts b/tns-core-modules/ui/text-view/text-view.ios.ts index 9486945ce7..ad5faf84b9 100644 --- a/tns-core-modules/ui/text-view/text-view.ios.ts +++ b/tns-core-modules/ui/text-view/text-view.ios.ts @@ -138,7 +138,7 @@ export class TextView extends EditableTextBase implements TextViewDefinition { this.showHint(hint); } else { this._isShowingHint = false; - this.nativeViewProtected.text = ""; + this.nativeTextViewProtected.text = ""; } } @@ -148,28 +148,28 @@ export class TextView extends EditableTextBase implements TextViewDefinition { const color = this.style.color; if (placeholderColor) { - this.nativeViewProtected.textColor = placeholderColor.ios; + this.nativeTextViewProtected.textColor = placeholderColor.ios; } else if (color) { // Use semi-transparent version of color for back-compatibility - this.nativeViewProtected.textColor = color.ios.colorWithAlphaComponent(0.22); + this.nativeTextViewProtected.textColor = color.ios.colorWithAlphaComponent(0.22); } else { - this.nativeViewProtected.textColor = UIColor.blackColor.colorWithAlphaComponent(0.22); + this.nativeTextViewProtected.textColor = UIColor.blackColor.colorWithAlphaComponent(0.22); } } else { const color = this.style.color; if (color) { - this.nativeViewProtected.textColor = color.ios; - this.nativeViewProtected.tintColor = color.ios; + this.nativeTextViewProtected.textColor = color.ios; + this.nativeTextViewProtected.tintColor = color.ios; } else { - this.nativeViewProtected.textColor = null; - this.nativeViewProtected.tintColor = null; + this.nativeTextViewProtected.textColor = null; + this.nativeTextViewProtected.tintColor = null; } } } public showHint(hint: string) { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; this._isShowingHint = true; this._refreshColor(); @@ -200,10 +200,10 @@ export class TextView extends EditableTextBase implements TextViewDefinition { } [editableProperty.getDefault](): boolean { - return this.nativeViewProtected.editable; + return this.nativeTextViewProtected.editable; } [editableProperty.setNative](value: boolean) { - this.nativeViewProtected.editable = value; + this.nativeTextViewProtected.editable = value; } [colorProperty.setNative](color: Color) { @@ -215,97 +215,97 @@ export class TextView extends EditableTextBase implements TextViewDefinition { [borderTopWidthProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.top, + value: this.nativeTextViewProtected.textContainerInset.top, unit: "px" }; } [borderTopWidthProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth); - this.nativeViewProtected.textContainerInset = { top: top, left: inset.left, bottom: inset.bottom, right: inset.right }; + this.nativeTextViewProtected.textContainerInset = { top: top, left: inset.left, bottom: inset.bottom, right: inset.right }; } [borderRightWidthProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.right, + value: this.nativeTextViewProtected.textContainerInset.right, unit: "px" }; } [borderRightWidthProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth); - this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: inset.bottom, right: right }; + this.nativeTextViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: inset.bottom, right: right }; } [borderBottomWidthProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.bottom, + value: this.nativeTextViewProtected.textContainerInset.bottom, unit: "px" }; } [borderBottomWidthProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth); - this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: bottom, right: inset.right }; + this.nativeTextViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: bottom, right: inset.right }; } [borderLeftWidthProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.left, + value: this.nativeTextViewProtected.textContainerInset.left, unit: "px" }; } [borderLeftWidthProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth); - this.nativeViewProtected.textContainerInset = { top: inset.top, left: left, bottom: inset.bottom, right: inset.right }; + this.nativeTextViewProtected.textContainerInset = { top: inset.top, left: left, bottom: inset.bottom, right: inset.right }; } [paddingTopProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.top, + value: this.nativeTextViewProtected.textContainerInset.top, unit: "px" }; } [paddingTopProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth); - this.nativeViewProtected.textContainerInset = { top: top, left: inset.left, bottom: inset.bottom, right: inset.right }; + this.nativeTextViewProtected.textContainerInset = { top: top, left: inset.left, bottom: inset.bottom, right: inset.right }; } [paddingRightProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.right, + value: this.nativeTextViewProtected.textContainerInset.right, unit: "px" }; } [paddingRightProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth); - this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: inset.bottom, right: right }; + this.nativeTextViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: inset.bottom, right: right }; } [paddingBottomProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.bottom, + value: this.nativeTextViewProtected.textContainerInset.bottom, unit: "px" }; } [paddingBottomProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth); - this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: bottom, right: inset.right }; + this.nativeTextViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: bottom, right: inset.right }; } [paddingLeftProperty.getDefault](): Length { return { - value: this.nativeViewProtected.textContainerInset.left, + value: this.nativeTextViewProtected.textContainerInset.left, unit: "px" }; } [paddingLeftProperty.setNative](value: Length) { - let inset = this.nativeViewProtected.textContainerInset; + let inset = this.nativeTextViewProtected.textContainerInset; let left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth); - this.nativeViewProtected.textContainerInset = { top: inset.top, left: left, bottom: inset.bottom, right: inset.right }; + this.nativeTextViewProtected.textContainerInset = { top: inset.top, left: left, bottom: inset.bottom, right: inset.right }; } } From bb67da7063fd1532ed9811f6b6ad0815143b4a72 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Fri, 20 Jul 2018 19:11:36 +0200 Subject: [PATCH 02/33] separate createNativeView from nativeview delegate creations --- .../editable-text-base.android.ts | 19 +++++++++---------- tns-core-modules/ui/label/label.ios.ts | 8 ++++++-- .../ui/text-field/text-field.ios.ts | 10 +++++++++- .../ui/text-view/text-view.ios.ts | 8 +++++++- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts index 29f787e161..b0c979a3cc 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts @@ -156,23 +156,22 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public createNativeView() { - initializeEditTextListeners(); const editText = new android.widget.EditText(this._context); - this._configureEditText(editText); + return editText; + } + public initNativeView(): void { + super.initNativeView(); + const editText = this.nativeTextViewProtected; + this._configureEditText(editText); + initializeEditTextListeners(); const listeners = new EditTextListeners(this); editText.addTextChangedListener(listeners); editText.setOnFocusChangeListener(listeners); editText.setOnEditorActionListener(listeners); (editText).listener = listeners; - return editText; - } - - public initNativeView(): void { - super.initNativeView(); - const nativeView = this.nativeViewProtected; - (nativeView).listener.owner = this; - this._inputType = nativeView.getInputType(); + (editText).listener.owner = this; + this._inputType = editText.getInputType(); } public disposeNativeView(): void { diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index ffca126b57..e207e6d271 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -25,11 +25,15 @@ export class Label extends TextBase implements LabelDefinition { constructor() { super(); + } - this.nativeViewProtected = TNSLabel.new(); - this.nativeViewProtected.userInteractionEnabled = true; + public createNativeView() { + const view = TNSLabel.new(); + view.userInteractionEnabled = true; + return view; } + get ios(): TNSLabel { return this.nativeTextViewProtected; } diff --git a/tns-core-modules/ui/text-field/text-field.ios.ts b/tns-core-modules/ui/text-field/text-field.ios.ts index bfe644a739..177baadb3c 100644 --- a/tns-core-modules/ui/text-field/text-field.ios.ts +++ b/tns-core-modules/ui/text-field/text-field.ios.ts @@ -147,10 +147,18 @@ export class TextField extends TextFieldBase { constructor() { super(); + + } + + createNativeView() { let weakRef = new WeakRef(this); this._ios = UITextFieldImpl.initWithOwner(weakRef); + this.createDelegate(weakRef); + return this._ios; + } + + createDelegate(weakRef: WeakRef) { this._delegate = UITextFieldDelegateImpl.initWithOwner(weakRef); - this.nativeViewProtected = this._ios; } @profile diff --git a/tns-core-modules/ui/text-view/text-view.ios.ts b/tns-core-modules/ui/text-view/text-view.ios.ts index ad5faf84b9..f0cfafd279 100644 --- a/tns-core-modules/ui/text-view/text-view.ios.ts +++ b/tns-core-modules/ui/text-view/text-view.ios.ts @@ -104,11 +104,17 @@ export class TextView extends EditableTextBase implements TextViewDefinition { constructor() { super(); + } - const textView = this.nativeViewProtected = this._ios = UITextView.new(); + createNativeView() { + const textView = this._ios = UITextView.new(); if (!textView.font) { textView.font = UIFont.systemFontOfSize(12); } + this.createDelegate(); + return textView; + } + createDelegate() { this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this)); } From 5839cb5e5edcd55435ca86d31dacd2f28a880f1b Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Sat, 21 Jul 2018 11:42:02 +0200 Subject: [PATCH 03/33] fixed lint error --- tns-core-modules/ui/label/label.ios.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index e207e6d271..00eda73f60 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -33,7 +33,6 @@ export class Label extends TextBase implements LabelDefinition { return view; } - get ios(): TNSLabel { return this.nativeTextViewProtected; } From 5bad5f6e2f4c9d1dbb38b18f10cf4d12deecb19f Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Sat, 21 Jul 2018 11:46:33 +0200 Subject: [PATCH 04/33] button refactoring --- tns-core-modules/ui/button/button.android.ts | 8 ++++++-- tns-core-modules/ui/button/button.ios.ts | 11 +++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/tns-core-modules/ui/button/button.android.ts b/tns-core-modules/ui/button/button.android.ts index 091cdbd113..975a276f87 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -49,12 +49,16 @@ export class Button extends ButtonBase { @profile public createNativeView() { - initializeClickListener(); const button = new AndroidButton(this._context); + this.createDelegate(button); + return button; + } + + public createDelegate(button: android.widget.Button) { + initializeClickListener(); const clickListener = new ClickListener(this); button.setOnClickListener(clickListener); (button).clickListener = clickListener; - return button; } public initNativeView(): void { diff --git a/tns-core-modules/ui/button/button.ios.ts b/tns-core-modules/ui/button/button.ios.ts index f66a7b84c1..e9c18c939b 100644 --- a/tns-core-modules/ui/button/button.ios.ts +++ b/tns-core-modules/ui/button/button.ios.ts @@ -16,10 +16,17 @@ export class Button extends ButtonBase { constructor() { super(); - this.nativeViewProtected = UIButton.buttonWithType(UIButtonType.System); + } + + createNativeView() { + const view = UIButton.buttonWithType(UIButtonType.System); + this.createDelegate(view); + return view; + } + createDelegate(view: UIButton) { + view.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this)); - this.nativeViewProtected.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); } get ios() { From db752b18f1e14e4d5ba890f8dafd9975c749a3b8 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Sat, 21 Jul 2018 11:46:39 +0200 Subject: [PATCH 05/33] better that way? --- .../ui/editable-text-base/editable-text-base.android.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts index b0c979a3cc..1459b92bfd 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts @@ -160,9 +160,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { return editText; } - public initNativeView(): void { - super.initNativeView(); - const editText = this.nativeTextViewProtected; + public createDelegate(editText: android.widget.EditText) { this._configureEditText(editText); initializeEditTextListeners(); const listeners = new EditTextListeners(this); @@ -170,6 +168,11 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { editText.setOnFocusChangeListener(listeners); editText.setOnEditorActionListener(listeners); (editText).listener = listeners; + } + + public initNativeView(): void { + super.initNativeView(); + const editText = this.nativeTextViewProtected; (editText).listener.owner = this; this._inputType = editText.getInputType(); } From 24b8f3826bfd524ef684e46849f73c391d210452 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 24 Jul 2018 10:19:38 +0200 Subject: [PATCH 06/33] fixed ios view creation as createNativeView is not fully supported on IOS --- tns-core-modules/ui/button/button.ios.ts | 8 ++++++-- tns-core-modules/ui/label/label.ios.ts | 6 +++++- tns-core-modules/ui/text-field/text-field.ios.ts | 7 +++++-- tns-core-modules/ui/text-view/text-view.ios.ts | 6 +++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tns-core-modules/ui/button/button.ios.ts b/tns-core-modules/ui/button/button.ios.ts index e9c18c939b..e02b0bb7c3 100644 --- a/tns-core-modules/ui/button/button.ios.ts +++ b/tns-core-modules/ui/button/button.ios.ts @@ -16,17 +16,21 @@ export class Button extends ButtonBase { constructor() { super(); + this.createNativeView(); } createNativeView() { - const view = UIButton.buttonWithType(UIButtonType.System); + if (this.nativeViewProtected) { + return this.nativeViewProtected; + } + const view = this.nativeViewProtected = UIButton.buttonWithType(UIButtonType.System); this.createDelegate(view); return view; } createDelegate(view: UIButton) { - view.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this)); + view.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); } get ios() { diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index 00eda73f60..262403b9b2 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -25,10 +25,14 @@ export class Label extends TextBase implements LabelDefinition { constructor() { super(); + this.createNativeView(); } public createNativeView() { - const view = TNSLabel.new(); + if (this.nativeViewProtected) { + return this.nativeViewProtected; + } + const view = this.nativeViewProtected = TNSLabel.new(); view.userInteractionEnabled = true; return view; } diff --git a/tns-core-modules/ui/text-field/text-field.ios.ts b/tns-core-modules/ui/text-field/text-field.ios.ts index 177baadb3c..c926982708 100644 --- a/tns-core-modules/ui/text-field/text-field.ios.ts +++ b/tns-core-modules/ui/text-field/text-field.ios.ts @@ -147,12 +147,15 @@ export class TextField extends TextFieldBase { constructor() { super(); - + this.createNativeView(); } createNativeView() { + if (this.nativeViewProtected) { + return this.nativeViewProtected; + } let weakRef = new WeakRef(this); - this._ios = UITextFieldImpl.initWithOwner(weakRef); + this._ios = this.nativeViewProtected = UITextFieldImpl.initWithOwner(weakRef); this.createDelegate(weakRef); return this._ios; } diff --git a/tns-core-modules/ui/text-view/text-view.ios.ts b/tns-core-modules/ui/text-view/text-view.ios.ts index f0cfafd279..2a66a8c6b4 100644 --- a/tns-core-modules/ui/text-view/text-view.ios.ts +++ b/tns-core-modules/ui/text-view/text-view.ios.ts @@ -104,10 +104,14 @@ export class TextView extends EditableTextBase implements TextViewDefinition { constructor() { super(); + this.createNativeView(); } createNativeView() { - const textView = this._ios = UITextView.new(); + if (this.nativeViewProtected) { + return this.nativeViewProtected; + } + const textView = this._ios = this.nativeViewProtected = UITextView.new(); if (!textView.font) { textView.font = UIFont.systemFontOfSize(12); } From 58fc92c683baf649df46f6dd43e75ae7feb06a36 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 24 Jul 2018 21:43:26 +0200 Subject: [PATCH 07/33] prevent undefined error --- tns-core-modules/ui/button/button.android.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tns-core-modules/ui/button/button.android.ts b/tns-core-modules/ui/button/button.android.ts index 975a276f87..9bb450bf90 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -68,7 +68,9 @@ export class Button extends ButtonBase { } public disposeNativeView() { - (this.nativeViewProtected).clickListener.owner = null; + if (this.nativeViewProtected) { + (this.nativeViewProtected).clickListener.owner = null; + } super.disposeNativeView(); } From a2f914a54376db5261e7792ba5ad53db5cd50d10 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Mon, 30 Jul 2018 14:22:28 +0200 Subject: [PATCH 08/33] update based on comments --- tns-core-modules/ui/button/button.android.ts | 6 ++---- tns-core-modules/ui/button/button.ios.ts | 14 ++------------ .../ui/core/view-base/view-base.d.ts | 5 +++++ tns-core-modules/ui/core/view-base/view-base.ts | 5 +++++ .../editable-text-base.android.ts | 5 ++--- tns-core-modules/ui/label/label.ios.ts | 5 ----- tns-core-modules/ui/text-base/text-base.d.ts | 5 +++++ .../ui/text-field/text-field.ios.ts | 17 +++-------------- tns-core-modules/ui/text-view/text-view.ios.ts | 8 +------- 9 files changed, 25 insertions(+), 45 deletions(-) diff --git a/tns-core-modules/ui/button/button.android.ts b/tns-core-modules/ui/button/button.android.ts index 9bb450bf90..9c9ed7f095 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -49,12 +49,10 @@ export class Button extends ButtonBase { @profile public createNativeView() { - const button = new AndroidButton(this._context); - this.createDelegate(button); - return button; + return new AndroidButton(this._context); } - public createDelegate(button: android.widget.Button) { + public initNativeViewDelegates(button: android.widget.Button) { initializeClickListener(); const clickListener = new ClickListener(this); button.setOnClickListener(clickListener); diff --git a/tns-core-modules/ui/button/button.ios.ts b/tns-core-modules/ui/button/button.ios.ts index e02b0bb7c3..94cfbd3437 100644 --- a/tns-core-modules/ui/button/button.ios.ts +++ b/tns-core-modules/ui/button/button.ios.ts @@ -14,21 +14,11 @@ export class Button extends ButtonBase { private _tapHandler: NSObject; private _stateChangedHandler: ControlStateChangeListener; - constructor() { - super(); - this.createNativeView(); - } - createNativeView() { - if (this.nativeViewProtected) { - return this.nativeViewProtected; - } - const view = this.nativeViewProtected = UIButton.buttonWithType(UIButtonType.System); - this.createDelegate(view); - return view; + return UIButton.buttonWithType(UIButtonType.System); } - createDelegate(view: UIButton) { + initNativeViewDelegates(view: UIButton) { this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this)); view.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); } diff --git a/tns-core-modules/ui/core/view-base/view-base.d.ts b/tns-core-modules/ui/core/view-base/view-base.d.ts index e780386dcb..588b54cf24 100644 --- a/tns-core-modules/ui/core/view-base/view-base.d.ts +++ b/tns-core-modules/ui/core/view-base/view-base.d.ts @@ -319,6 +319,11 @@ export abstract class ViewBase extends Observable { */ createNativeView(): Object; + /** + * Creates any delegate needed by the nativeView. Could be delegates on iOS or listeners on Android. + */ + initNativeViewDelegates(view: Object); + /** * Initializes properties/listeners of the native view. */ diff --git a/tns-core-modules/ui/core/view-base/view-base.ts b/tns-core-modules/ui/core/view-base/view-base.ts index e1196636fd..c3c1c8fbf1 100644 --- a/tns-core-modules/ui/core/view-base/view-base.ts +++ b/tns-core-modules/ui/core/view-base/view-base.ts @@ -642,6 +642,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition return undefined; } + public initNativeViewDelegates(view: Object) { + // + } + public disposeNativeView() { // } @@ -696,6 +700,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition if (!nativeView) { nativeView = this.createNativeView(); + this.initNativeViewDelegates(nativeView); } this._androidView = nativeView; diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts index 1459b92bfd..6d3ea7142e 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts @@ -156,11 +156,10 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public createNativeView() { - const editText = new android.widget.EditText(this._context); - return editText; + return new android.widget.EditText(this._context); } - public createDelegate(editText: android.widget.EditText) { + public initNativeViewDelegates(editText: android.widget.EditText) { this._configureEditText(editText); initializeEditTextListeners(); const listeners = new EditTextListeners(this); diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index 262403b9b2..977f7bd0f1 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -23,11 +23,6 @@ export class Label extends TextBase implements LabelDefinition { nativeViewProtected: TNSLabel; private _fixedSize: FixedSize; - constructor() { - super(); - this.createNativeView(); - } - public createNativeView() { if (this.nativeViewProtected) { return this.nativeViewProtected; diff --git a/tns-core-modules/ui/text-base/text-base.d.ts b/tns-core-modules/ui/text-base/text-base.d.ts index 6920ade23d..3918cf2135 100644 --- a/tns-core-modules/ui/text-base/text-base.d.ts +++ b/tns-core-modules/ui/text-base/text-base.d.ts @@ -10,7 +10,12 @@ export { FormattedString } from "../../text/formatted-string"; export class TextBase extends View implements AddChildFromBuilder { + /** + * Gets of the text widget. In some cases(android TextInputLayout) the TextView is made of 2 views: the layout and the text view + * So we need a different getter for the layout and text functions + */ public readonly nativeTextViewProtected: any; + /** * Gets or sets the text. */ diff --git a/tns-core-modules/ui/text-field/text-field.ios.ts b/tns-core-modules/ui/text-field/text-field.ios.ts index c926982708..b61bd3019c 100644 --- a/tns-core-modules/ui/text-field/text-field.ios.ts +++ b/tns-core-modules/ui/text-field/text-field.ios.ts @@ -145,23 +145,12 @@ export class TextField extends TextFieldBase { private _delegate: UITextFieldDelegateImpl; nativeViewProtected: UITextField; - constructor() { - super(); - this.createNativeView(); - } - createNativeView() { - if (this.nativeViewProtected) { - return this.nativeViewProtected; - } - let weakRef = new WeakRef(this); - this._ios = this.nativeViewProtected = UITextFieldImpl.initWithOwner(weakRef); - this.createDelegate(weakRef); - return this._ios; + return UITextFieldImpl.initWithOwner(new WeakRef(this)); } - createDelegate(weakRef: WeakRef) { - this._delegate = UITextFieldDelegateImpl.initWithOwner(weakRef); + initNativeViewDelegates(view: UITextFieldImpl) { + this._delegate = UITextFieldDelegateImpl.initWithOwner(new WeakRef(this)); } @profile diff --git a/tns-core-modules/ui/text-view/text-view.ios.ts b/tns-core-modules/ui/text-view/text-view.ios.ts index 2a66a8c6b4..2a3e4480f1 100644 --- a/tns-core-modules/ui/text-view/text-view.ios.ts +++ b/tns-core-modules/ui/text-view/text-view.ios.ts @@ -102,11 +102,6 @@ export class TextView extends EditableTextBase implements TextViewDefinition { private _isShowingHint: boolean; public _isEditing: boolean; - constructor() { - super(); - this.createNativeView(); - } - createNativeView() { if (this.nativeViewProtected) { return this.nativeViewProtected; @@ -115,10 +110,9 @@ export class TextView extends EditableTextBase implements TextViewDefinition { if (!textView.font) { textView.font = UIFont.systemFontOfSize(12); } - this.createDelegate(); return textView; } - createDelegate() { + initNativeViewDelegates(view: UITextView) { this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this)); } From 48f7b66959e20154051f12a875cedf725f13b178 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 31 Jul 2018 10:14:02 +0200 Subject: [PATCH 09/33] fixed missing delegate call on ios --- tns-core-modules/ui/core/view-base/view-base.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tns-core-modules/ui/core/view-base/view-base.ts b/tns-core-modules/ui/core/view-base/view-base.ts index c3c1c8fbf1..3a359f3754 100644 --- a/tns-core-modules/ui/core/view-base/view-base.ts +++ b/tns-core-modules/ui/core/view-base/view-base.ts @@ -700,7 +700,6 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition if (!nativeView) { nativeView = this.createNativeView(); - this.initNativeViewDelegates(nativeView); } this._androidView = nativeView; @@ -736,13 +735,14 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition } } else { // TODO: Implement _createNativeView for iOS - nativeView = this.createNativeView(); - this._iosView = nativeView || this.nativeViewProtected; + nativeView = this.createNativeView() || this.nativeViewProtected; + this._iosView = nativeView; } + this.initNativeViewDelegates(nativeView); // This will account for nativeView that is created in createNativeView, recycled // or for backward compatability - set before _setupUI in iOS contructor. - this.setNativeView(nativeView || this.nativeViewProtected); + this.setNativeView(nativeView); if (this.parent) { const nativeIndex = this.parent._childIndexToNativeChildIndex(atIndex); From 2ae113391738ce7fe960dd2fd634de7a24e48fbc Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Sat, 11 Aug 2018 16:09:54 +0200 Subject: [PATCH 10/33] refactored all UI widgets for better use of createNativeView/initNativeView --- .../ui/action-bar/action-bar.android.ts | 14 ++--- .../activity-indicator.ios.ts | 10 ++-- tns-core-modules/ui/button/button.android.ts | 15 ++--- tns-core-modules/ui/button/button.ios.ts | 11 +++- .../ui/core/view-base/view-base.d.ts | 5 -- .../ui/core/view-base/view-base.ts | 5 -- tns-core-modules/ui/core/view/view.ios.ts | 5 +- .../ui/date-picker/date-picker.android.ts | 12 ++-- .../ui/date-picker/date-picker.ios.ts | 20 +++++-- .../editable-text-base.android.ts | 13 ++-- .../ui/html-view/html-view.ios.ts | 18 +++--- tns-core-modules/ui/image/image.android.ts | 15 +++-- tns-core-modules/ui/image/image.ios.ts | 11 ++-- tns-core-modules/ui/label/label.ios.ts | 3 - .../ui/list-picker/list-picker.android.ts | 31 ++++------ .../ui/list-picker/list-picker.ios.ts | 41 ++++++++----- .../ui/list-view/list-view.android.ts | 27 ++++----- .../ui/list-view/list-view.ios.ts | 60 +++++++++++-------- tns-core-modules/ui/progress/progress.ios.ts | 27 ++++----- .../ui/scroll-view/scroll-view.android.ts | 1 + .../ui/scroll-view/scroll-view.ios.ts | 9 ++- .../ui/search-bar/search-bar.android.ts | 18 +++--- .../ui/search-bar/search-bar.ios.ts | 29 +++++---- .../ui/segmented-bar/segmented-bar.android.ts | 13 ++-- .../ui/segmented-bar/segmented-bar.ios.ts | 31 ++++++---- tns-core-modules/ui/slider/slider.android.ts | 21 ++++--- tns-core-modules/ui/slider/slider.ios.ts | 41 +++++++------ tns-core-modules/ui/switch/switch.android.ts | 15 +++-- tns-core-modules/ui/switch/switch.ios.ts | 20 +++++-- tns-core-modules/ui/tab-view/tab-view.ios.ts | 11 +++- .../ui/text-base/text-base.android.ts | 2 +- .../ui/text-field/text-field.ios.ts | 17 ++++-- .../ui/text-view/text-view.ios.ts | 22 ++++--- .../ui/time-picker/time-picker.android.ts | 17 +++--- .../ui/time-picker/time-picker.ios.ts | 28 +++++---- .../ui/web-view/web-view.android.ts | 12 ++-- tns-core-modules/ui/web-view/web-view.ios.ts | 18 ++++-- 37 files changed, 365 insertions(+), 303 deletions(-) diff --git a/tns-core-modules/ui/action-bar/action-bar.android.ts b/tns-core-modules/ui/action-bar/action-bar.android.ts index 036d739adb..f4ea736ebd 100644 --- a/tns-core-modules/ui/action-bar/action-bar.android.ts +++ b/tns-core-modules/ui/action-bar/action-bar.android.ts @@ -131,21 +131,21 @@ export class ActionBar extends ActionBarBase { } public createNativeView() { - initializeMenuItemClickListener(); - const toolbar = new android.support.v7.widget.Toolbar(this._context); - const menuItemClickListener = new MenuItemClickListener(this); - toolbar.setOnMenuItemClickListener(menuItemClickListener); - (toolbar).menuItemClickListener = menuItemClickListener; - return toolbar; + return new android.support.v7.widget.Toolbar(this._context); } public initNativeView(): void { super.initNativeView(); - (this.nativeViewProtected).menuItemClickListener.owner = this; + const nativeView = this.nativeViewProtected; + initializeMenuItemClickListener(); + const menuItemClickListener = new MenuItemClickListener(this); + nativeView.setOnMenuItemClickListener(menuItemClickListener); + (toolbar).menuItemClickListener = menuItemClickListener; } public disposeNativeView() { (this.nativeViewProtected).menuItemClickListener.owner = null; + (this.nativeViewProtected).menuItemClickListener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/activity-indicator/activity-indicator.ios.ts b/tns-core-modules/ui/activity-indicator/activity-indicator.ios.ts index 97773f5311..ba44172974 100644 --- a/tns-core-modules/ui/activity-indicator/activity-indicator.ios.ts +++ b/tns-core-modules/ui/activity-indicator/activity-indicator.ios.ts @@ -4,11 +4,11 @@ export * from "./activity-indicator-common"; export class ActivityIndicator extends ActivityIndicatorBase { nativeViewProtected: UIActivityIndicatorView; - - constructor() { - super(); - this.nativeViewProtected = UIActivityIndicatorView.alloc().initWithActivityIndicatorStyle(UIActivityIndicatorViewStyle.Gray); - this.nativeViewProtected.hidesWhenStopped = true; + + createNativeView() { + const view = UIActivityIndicatorView.alloc().initWithActivityIndicatorStyle(UIActivityIndicatorViewStyle.Gray); + view.hidesWhenStopped = true; + return view; } get ios(): UIActivityIndicatorView { diff --git a/tns-core-modules/ui/button/button.android.ts b/tns-core-modules/ui/button/button.android.ts index 9c9ed7f095..50417e0bbb 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -52,22 +52,19 @@ export class Button extends ButtonBase { return new AndroidButton(this._context); } - public initNativeViewDelegates(button: android.widget.Button) { - initializeClickListener(); - const clickListener = new ClickListener(this); - button.setOnClickListener(clickListener); - (button).clickListener = clickListener; - } - public initNativeView(): void { - const nativeView = this.nativeViewProtected; - (nativeView).clickListener.owner = this; super.initNativeView(); + const nativeView = this.nativeViewProtected; + initializeClickListener(); + const clickListener = new ClickListener(this); + nativeView.setOnClickListener(clickListener); + (nativeView).clickListener = clickListener; } public disposeNativeView() { if (this.nativeViewProtected) { (this.nativeViewProtected).clickListener.owner = null; + (this.nativeViewProtected).clickListener = null; } super.disposeNativeView(); } diff --git a/tns-core-modules/ui/button/button.ios.ts b/tns-core-modules/ui/button/button.ios.ts index 94cfbd3437..a994e8180b 100644 --- a/tns-core-modules/ui/button/button.ios.ts +++ b/tns-core-modules/ui/button/button.ios.ts @@ -18,9 +18,16 @@ export class Button extends ButtonBase { return UIButton.buttonWithType(UIButtonType.System); } - initNativeViewDelegates(view: UIButton) { + public initNativeView(): void { + super.initNativeView(); + const nativeView = this.nativeViewProtected; this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this)); - view.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); + nativeView.addTargetActionForControlEvents(this._tapHandler, "tap", UIControlEvents.TouchUpInside); + } + + public disposeNativeView(): void { + this._tapHandler = null; + super.disposeNativeView(); } get ios() { diff --git a/tns-core-modules/ui/core/view-base/view-base.d.ts b/tns-core-modules/ui/core/view-base/view-base.d.ts index 588b54cf24..e780386dcb 100644 --- a/tns-core-modules/ui/core/view-base/view-base.d.ts +++ b/tns-core-modules/ui/core/view-base/view-base.d.ts @@ -319,11 +319,6 @@ export abstract class ViewBase extends Observable { */ createNativeView(): Object; - /** - * Creates any delegate needed by the nativeView. Could be delegates on iOS or listeners on Android. - */ - initNativeViewDelegates(view: Object); - /** * Initializes properties/listeners of the native view. */ diff --git a/tns-core-modules/ui/core/view-base/view-base.ts b/tns-core-modules/ui/core/view-base/view-base.ts index 3a359f3754..2a5de38577 100644 --- a/tns-core-modules/ui/core/view-base/view-base.ts +++ b/tns-core-modules/ui/core/view-base/view-base.ts @@ -642,10 +642,6 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition return undefined; } - public initNativeViewDelegates(view: Object) { - // - } - public disposeNativeView() { // } @@ -738,7 +734,6 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition nativeView = this.createNativeView() || this.nativeViewProtected; this._iosView = nativeView; } - this.initNativeViewDelegates(nativeView); // This will account for nativeView that is created in createNativeView, recycled // or for backward compatability - set before _setupUI in iOS contructor. diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index a50543d972..48dfccd8be 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -536,9 +536,8 @@ export class CustomLayoutView extends View { nativeViewProtected: UIView; - constructor() { - super(); - this.nativeViewProtected = UIView.alloc().initWithFrame(iosUtils.getter(UIScreen, UIScreen.mainScreen).bounds); + createNativeView() { + return UIView.alloc().initWithFrame(iosUtils.getter(UIScreen, UIScreen.mainScreen).bounds); } get ios(): UIView { diff --git a/tns-core-modules/ui/date-picker/date-picker.android.ts b/tns-core-modules/ui/date-picker/date-picker.android.ts index f52954a863..802bd778d6 100644 --- a/tns-core-modules/ui/date-picker/date-picker.android.ts +++ b/tns-core-modules/ui/date-picker/date-picker.android.ts @@ -54,23 +54,23 @@ export class DatePicker extends DatePickerBase { nativeViewProtected: android.widget.DatePicker; public createNativeView() { - initializeDateChangedListener(); const picker = new android.widget.DatePicker(this._context); picker.setCalendarViewShown(false); - const listener = new DateChangedListener(this); - - picker.init(this.year, this.month - 1, this.day, listener); - (picker).listener = listener; return picker; } public initNativeView(): void { super.initNativeView(); - (this.nativeViewProtected).listener.owner = this; + initializeDateChangedListener(); + const nativeView = this.nativeViewProtected; + const listener = new DateChangedListener(this); + nativeView.init(this.year, this.month - 1, this.day, listener); + (nativeView).listener = listener; } public disposeNativeView() { (this.nativeViewProtected).listener.owner = null; + (this.nativeViewProtected).listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/date-picker/date-picker.ios.ts b/tns-core-modules/ui/date-picker/date-picker.ios.ts index 64a0049c33..3d2533ef01 100644 --- a/tns-core-modules/ui/date-picker/date-picker.ios.ts +++ b/tns-core-modules/ui/date-picker/date-picker.ios.ts @@ -11,14 +11,22 @@ export class DatePicker extends DatePickerBase { private _changeHandler: NSObject; public nativeViewProtected: UIDatePicker; - constructor() { - super(); - - this.nativeViewProtected = UIDatePicker.new(); - this.nativeViewProtected.datePickerMode = UIDatePickerMode.Date; + public createNativeView() { + const picker = UIDatePicker.new(); + picker.datePickerMode = UIDatePickerMode.Date; + return picker; + } + public initNativeView(): void { + super.initNativeView(); + const nativeView = this.nativeViewProtected; this._changeHandler = UIDatePickerChangeHandlerImpl.initWithOwner(new WeakRef(this)); - this.nativeViewProtected.addTargetActionForControlEvents(this._changeHandler, "valueChanged", UIControlEvents.ValueChanged); + nativeView.addTargetActionForControlEvents(this._changeHandler, "valueChanged", UIControlEvents.ValueChanged); + } + + public disposeNativeView() { + this._changeHandler = null; + super.disposeNativeView(); } get ios(): UIDatePicker { diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts index 6d3ea7142e..f1996af386 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts @@ -159,7 +159,9 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { return new android.widget.EditText(this._context); } - public initNativeViewDelegates(editText: android.widget.EditText) { + public initNativeView(): void { + super.initNativeView(); + const editText = this.nativeTextViewProtected; this._configureEditText(editText); initializeEditTextListeners(); const listeners = new EditTextListeners(this); @@ -167,19 +169,14 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { editText.setOnFocusChangeListener(listeners); editText.setOnEditorActionListener(listeners); (editText).listener = listeners; - } - - public initNativeView(): void { - super.initNativeView(); - const editText = this.nativeTextViewProtected; - (editText).listener.owner = this; this._inputType = editText.getInputType(); } public disposeNativeView(): void { - super.disposeNativeView(); (this.nativeTextViewProtected).listener.owner = null; + (this.nativeTextViewProtected).listener = null; this._keyListenerCache = null; + super.disposeNativeView(); } public resetNativeView(): void { diff --git a/tns-core-modules/ui/html-view/html-view.ios.ts b/tns-core-modules/ui/html-view/html-view.ios.ts index d460877018..1be43ea754 100644 --- a/tns-core-modules/ui/html-view/html-view.ios.ts +++ b/tns-core-modules/ui/html-view/html-view.ios.ts @@ -7,16 +7,14 @@ export * from "./html-view-common"; export class HtmlView extends HtmlViewBase { nativeViewProtected: UITextView; - constructor() { - super(); - const nativeView = UITextView.new() - nativeView.scrollEnabled = false; - nativeView.editable = false; - nativeView.selectable = true; - nativeView.userInteractionEnabled = true; - nativeView.dataDetectorTypes = UIDataDetectorTypes.All; - - this.nativeViewProtected = nativeView; + public createNativeView() { + const view = UITextView.new(); + view.scrollEnabled = false; + view.editable = false; + view.selectable = true; + view.userInteractionEnabled = true; + view.dataDetectorTypes = UIDataDetectorTypes.All; + return view; } get ios(): UITextView { diff --git a/tns-core-modules/ui/image/image.android.ts b/tns-core-modules/ui/image/image.android.ts index 0b28d34d8c..759cbc8407 100644 --- a/tns-core-modules/ui/image/image.android.ts +++ b/tns-core-modules/ui/image/image.android.ts @@ -49,23 +49,22 @@ export class Image extends ImageBase { if (!AndroidImageView) { AndroidImageView = org.nativescript.widgets.ImageView; } - initializeImageLoadedListener(); - - const imageView = new AndroidImageView(this._context); - const listener = new ImageLoadedListener(this); - imageView.setImageLoadedListener(listener); - (imageView).listener = listener; - return imageView; + return new AndroidImageView(this._context); } public initNativeView(): void { super.initNativeView(); - (this.nativeViewProtected).listener.owner = this; + initializeImageLoadedListener(); + const nativeView = this.nativeViewProtected; + const listener = new ImageLoadedListener(this); + nativeView.setImageLoadedListener(listener); + (nativeView).listener = listener; } public disposeNativeView() { (this.nativeViewProtected).listener.owner = null; + (this.nativeViewProtected).listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/image/image.ios.ts b/tns-core-modules/ui/image/image.ios.ts index 19839148f0..1806185081 100644 --- a/tns-core-modules/ui/image/image.ios.ts +++ b/tns-core-modules/ui/image/image.ios.ts @@ -10,15 +10,18 @@ export class Image extends ImageBase { private _imageSourceAffectsLayout: boolean = true; private _templateImageWasCreated: boolean; - constructor() { - super(); - - //TODO: Think of unified way of setting all the default values. + public createNativeView() { const imageView = UIImageView.new(); imageView.contentMode = UIViewContentMode.ScaleAspectFit; imageView.userInteractionEnabled = true; this.nativeViewProtected = imageView; this._setNativeClipToBounds(); + return imageView; + } + + public initNativeView(): void { + super.initNativeView(); + this._setNativeClipToBounds(); } private setTintColor(value: Color) { diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index 977f7bd0f1..4e0b2288fb 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -24,9 +24,6 @@ export class Label extends TextBase implements LabelDefinition { private _fixedSize: FixedSize; public createNativeView() { - if (this.nativeViewProtected) { - return this.nativeViewProtected; - } const view = this.nativeViewProtected = TNSLabel.new(); view.userInteractionEnabled = true; return view; diff --git a/tns-core-modules/ui/list-picker/list-picker.android.ts b/tns-core-modules/ui/list-picker/list-picker.android.ts index faed19a5d9..79db08e0db 100644 --- a/tns-core-modules/ui/list-picker/list-picker.android.ts +++ b/tns-core-modules/ui/list-picker/list-picker.android.ts @@ -74,40 +74,31 @@ export class ListPicker extends ListPickerBase { private _selectorWheelPaint: android.graphics.Paint; public createNativeView() { - initializeNativeClasses(); const picker = new android.widget.NumberPicker(this._context); - picker.setDescendantFocusability(android.widget.NumberPicker.FOCUS_BLOCK_DESCENDANTS); picker.setMinValue(0); picker.setMaxValue(0); picker.setValue(0); - - const formatter = new Formatter(this); - picker.setFormatter(formatter); - (picker).formatter = formatter; - - const valueChangedListener = new ValueChangeListener(this); - picker.setOnValueChangedListener(valueChangedListener); - (picker).valueChangedListener = valueChangedListener; - - const editText = getEditText(picker); - if (editText) { - (picker).editText = editText; - } - picker.setWrapSelectorWheel(false); return picker; } public initNativeView(): void { super.initNativeView(); + initializeNativeClasses(); const nativeView = this.nativeViewProtected; this._selectorWheelPaint = getSelectorWheelPaint(nativeView); - (nativeView).formatter.owner = this; - (nativeView).valueChangedListener.owner = this; - const editText = (nativeView).editText; + const formatter = new Formatter(this); + nativeView.setFormatter(formatter); + (nativeView).formatter = formatter; + + const valueChangedListener = new ValueChangeListener(this); + nativeView.setOnValueChangedListener(valueChangedListener); + (nativeView).valueChangedListener = valueChangedListener; + const editText = getEditText(nativeView); if (editText) { + (nativeView).editText = editText; //Fix the disappearing selected item. //HACK: http://stackoverflow.com/questions/17708325/android-numberpicker-with-formatter-does-not-format-on-first-rendering/26797732 editText.setFilters([]); @@ -120,7 +111,9 @@ export class ListPicker extends ListPickerBase { public disposeNativeView() { const nativeView = this.nativeViewProtected; (nativeView).formatter.owner = null; + (nativeView).formatter = null; (nativeView).valueChangedListener.owner = null; + (nativeView).valueChangedListener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/list-picker/list-picker.ios.ts b/tns-core-modules/ui/list-picker/list-picker.ios.ts index 77d65800aa..935b2d084f 100644 --- a/tns-core-modules/ui/list-picker/list-picker.ios.ts +++ b/tns-core-modules/ui/list-picker/list-picker.ios.ts @@ -5,33 +5,42 @@ import { profile } from "../../profiling"; export * from "./list-picker-common"; export class ListPicker extends ListPickerBase { - private _ios: UIPickerView; + nativeViewProtected: UIPickerView; private _dataSource: ListPickerDataSource; private _delegate: ListPickerDelegateImpl; + + createNativeView() { + return UIPickerView.new(); + } - constructor() { - super(); - - this.nativeViewProtected = this._ios = UIPickerView.new(); - this._ios.dataSource = this._dataSource = ListPickerDataSource.initWithOwner(new WeakRef(this)); + initNativeView() { + super.initNativeView(); + const nativeView = this.nativeViewProtected; + nativeView.dataSource = this._dataSource = ListPickerDataSource.initWithOwner(new WeakRef(this)); this._delegate = ListPickerDelegateImpl.initWithOwner(new WeakRef(this)); } + public disposeNativeView() { + this._dataSource = null; + this._delegate = null; + super.disposeNativeView(); + } + + get ios() { + return this.nativeViewProtected; + } + @profile public onLoaded() { super.onLoaded(); - this._ios.delegate = this._delegate; + this.ios.delegate = this._delegate; } public onUnloaded() { - this._ios.delegate = null; + this.ios.delegate = null; super.onUnloaded(); } - get ios(): UIPickerView { - return this._ios; - } - [selectedIndexProperty.getDefault](): number { return -1; } @@ -52,17 +61,17 @@ export class ListPicker extends ListPickerBase { } [backgroundColorProperty.getDefault](): UIColor { - return this._ios.backgroundColor; + return this.ios.backgroundColor; } [backgroundColorProperty.setNative](value: UIColor | Color) { - this._ios.backgroundColor = value instanceof Color ? value.ios : value; + this.ios.backgroundColor = value instanceof Color ? value.ios : value; } [colorProperty.getDefault](): UIColor { - return this._ios.tintColor; + return this.ios.tintColor; } [colorProperty.setNative](value: UIColor | Color) { - this._ios.tintColor = value instanceof Color ? value.ios : value; + this.ios.tintColor = value instanceof Color ? value.ios : value; } } diff --git a/tns-core-modules/ui/list-view/list-view.android.ts b/tns-core-modules/ui/list-view/list-view.android.ts index 46023cf5a3..92cdeae042 100644 --- a/tns-core-modules/ui/list-view/list-view.android.ts +++ b/tns-core-modules/ui/list-view/list-view.android.ts @@ -51,23 +51,12 @@ export class ListView extends ListViewBase { @profile public createNativeView() { - initializeItemClickListener(); - const listView = new android.widget.ListView(this._context); listView.setDescendantFocusability(android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS); // Fixes issue with black random black items when scrolling listView.setCacheColorHint(android.graphics.Color.TRANSPARENT); - ensureListViewAdapterClass(); - const adapter = new ListViewAdapterClass(this); - listView.setAdapter(adapter); - (listView).adapter = adapter; - - const itemClickListener = new ItemClickListener(this); - listView.setOnItemClickListener(itemClickListener); - (listView).itemClickListener = itemClickListener; - return listView; } @@ -75,11 +64,17 @@ export class ListView extends ListViewBase { super.initNativeView(); this.updateEffectiveRowHeight(); - const nativeView: any = this.nativeViewProtected; - (nativeView).itemClickListener.owner = this; - const adapter = (nativeView).adapter; - adapter.owner = this; + const nativeView = this.nativeViewProtected; + initializeItemClickListener(); + ensureListViewAdapterClass(); + const adapter = new ListViewAdapterClass(this); nativeView.setAdapter(adapter); + (nativeView).adapter = adapter; + + const itemClickListener = new ItemClickListener(this); + nativeView.setOnItemClickListener(itemClickListener); + (nativeView).itemClickListener = itemClickListener; + if (this._androidViewId < 0) { this._androidViewId = android.view.View.generateViewId(); } @@ -90,7 +85,9 @@ export class ListView extends ListViewBase { const nativeView = this.nativeViewProtected; nativeView.setAdapter(null); (nativeView).itemClickListener.owner = null; + (nativeView).itemClickListener = null; (nativeView).adapter.owner = null; + (nativeView).adapter = null; this.clearRealizedCells(); super.disposeNativeView(); } diff --git a/tns-core-modules/ui/list-view/list-view.ios.ts b/tns-core-modules/ui/list-view/list-view.ios.ts index 8417d8682d..da68e50977 100644 --- a/tns-core-modules/ui/list-view/list-view.ios.ts +++ b/tns-core-modules/ui/list-view/list-view.ios.ts @@ -199,7 +199,7 @@ class UITableViewRowHeightDelegateImpl extends NSObject implements UITableViewDe } export class ListView extends ListViewBase { - public _ios: UITableView; + public nativeViewProtected: UITableView; private _dataSource; private _delegate; private _heights: Array; @@ -208,22 +208,32 @@ export class ListView extends ListViewBase { private _map: Map; widthMeasureSpec: number = 0; - constructor() { - super(); - this.nativeViewProtected = this._ios = UITableView.new(); - this._ios.registerClassForCellReuseIdentifier(ListViewCell.class(), this._defaultTemplate.key); - this._ios.estimatedRowHeight = DEFAULT_HEIGHT; - this._ios.rowHeight = UITableViewAutomaticDimension; - this._ios.dataSource = this._dataSource = DataSource.initWithOwner(new WeakRef(this)); + createNativeView() { + return UITableView.new(); + } + + initNativeView() { + super.initNativeView(); + const nativeView = this.nativeViewProtected; + nativeView.registerClassForCellReuseIdentifier(ListViewCell.class(), this._defaultTemplate.key); + nativeView.estimatedRowHeight = DEFAULT_HEIGHT; + nativeView.rowHeight = UITableViewAutomaticDimension; + nativeView.dataSource = this._dataSource = DataSource.initWithOwner(new WeakRef(this)); this._delegate = UITableViewDelegateImpl.initWithOwner(new WeakRef(this)); this._heights = new Array(); this._map = new Map(); this._setNativeClipToBounds(); } + disposeNativeView() { + this._delegate = null; + this._dataSource = null; + super.disposeNativeView(); + } + _setNativeClipToBounds() { // Always set clipsToBounds for list-view - this._ios.clipsToBounds = true; + this.ios.clipsToBounds = true; } @profile @@ -232,16 +242,16 @@ export class ListView extends ListViewBase { if (this._isDataDirty) { this.refresh(); } - this._ios.delegate = this._delegate; + this.ios.delegate = this._delegate; } public onUnloaded() { - this._ios.delegate = null; + this.ios.delegate = null; super.onUnloaded(); } get ios(): UITableView { - return this._ios; + return this.nativeViewProtected; } get _childrenCount(): number { @@ -255,15 +265,15 @@ export class ListView extends ListViewBase { } public scrollToIndex(index: number) { - if (this._ios) { - this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), + if (this.ios) { + this.ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), UITableViewScrollPosition.Top, false); } } public scrollToIndexAnimated(index: number) { - if (this._ios) { - this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), + if (this.ios) { + this.ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), UITableViewScrollPosition.Top, true); } } @@ -277,7 +287,7 @@ export class ListView extends ListViewBase { }); if (this.isLoaded) { - this._ios.reloadData(); + this.ios.reloadData(); this.requestLayout(); this._isDataDirty = false; } else { @@ -286,7 +296,7 @@ export class ListView extends ListViewBase { } public isItemAtIndexVisible(itemIndex: number): boolean { - const indexes: NSIndexPath[] = Array.from(this._ios.indexPathsForVisibleRows); + const indexes: NSIndexPath[] = Array.from(this.ios.indexPathsForVisibleRows); return indexes.some(visIndex => visIndex.row === itemIndex); } @@ -300,7 +310,7 @@ export class ListView extends ListViewBase { public _onRowHeightPropertyChanged(oldValue: Length, newValue: Length) { const value = layout.toDeviceIndependentPixels(this._effectiveRowHeight); - const nativeView = this._ios; + const nativeView = this.ios; if (value < 0) { nativeView.rowHeight = UITableViewAutomaticDimension; nativeView.estimatedRowHeight = DEFAULT_HEIGHT; @@ -331,7 +341,7 @@ export class ListView extends ListViewBase { var changed = this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec); super.measure(widthMeasureSpec, heightMeasureSpec); if (changed) { - this._ios.reloadData(); + this.ios.reloadData(); } } @@ -345,7 +355,7 @@ export class ListView extends ListViewBase { return height; } - return this._ios.estimatedRowHeight; + return this.ios.estimatedRowHeight; } public _prepareCell(cell: ListViewCell, indexPath: NSIndexPath): number { @@ -408,10 +418,10 @@ export class ListView extends ListViewBase { } [separatorColorProperty.getDefault](): UIColor { - return this._ios.separatorColor; + return this.ios.separatorColor; } [separatorColorProperty.setNative](value: Color | UIColor) { - this._ios.separatorColor = value instanceof Color ? value.ios : value; + this.ios.separatorColor = value instanceof Color ? value.ios : value; } [itemTemplatesProperty.getDefault](): KeyedTemplate[] { @@ -421,7 +431,7 @@ export class ListView extends ListViewBase { this._itemTemplatesInternal = new Array(this._defaultTemplate); if (value) { for (let i = 0, length = value.length; i < length; i++) { - this._ios.registerClassForCellReuseIdentifier(ListViewCell.class(), value[i].key); + this.ios.registerClassForCellReuseIdentifier(ListViewCell.class(), value[i].key); } this._itemTemplatesInternal = this._itemTemplatesInternal.concat(value); } @@ -433,7 +443,7 @@ export class ListView extends ListViewBase { return DEFAULT_HEIGHT; } [iosEstimatedRowHeightProperty.setNative](value: Length) { - const nativeView = this._ios; + const nativeView = this.ios; const estimatedHeight = Length.toDevicePixels(value, 0); nativeView.estimatedRowHeight = estimatedHeight < 0 ? DEFAULT_HEIGHT : estimatedHeight; } diff --git a/tns-core-modules/ui/progress/progress.ios.ts b/tns-core-modules/ui/progress/progress.ios.ts index e5c0f4d6f5..6801520909 100644 --- a/tns-core-modules/ui/progress/progress.ios.ts +++ b/tns-core-modules/ui/progress/progress.ios.ts @@ -6,48 +6,43 @@ export * from "./progress-common"; export class Progress extends ProgressBase { - private _ios: UIProgressView; + nativeViewProtected: UIProgressView; - constructor() { - super(); - this.nativeViewProtected = this._ios = UIProgressView.new(); + createNativeView() { + return UIProgressView.new(); } - get ios(): UIProgressView { - return this._ios; + get ios() { + return this.nativeViewProtected; } - // get nativeView(): UIProgressView { - // return this._ios; - // } - [valueProperty.getDefault](): number { return 0; } [valueProperty.setNative](value: number) { - this._ios.progress = value / this.maxValue; + this.ios.progress = value / this.maxValue; } [maxValueProperty.getDefault](): number { return 100; } [maxValueProperty.setNative](value: number) { - this._ios.progress = this.value / value; + this.ios.progress = this.value / value; } [colorProperty.getDefault](): UIColor { - return this._ios.progressTintColor; + return this.ios.progressTintColor; } [colorProperty.setNative](value: Color | UIColor) { - this._ios.progressTintColor = value instanceof Color ? value.ios : value; + this.ios.progressTintColor = value instanceof Color ? value.ios : value; } [backgroundColorProperty.getDefault](): UIColor { - return this._ios.trackTintColor; + return this.ios.trackTintColor; } [backgroundColorProperty.setNative](value: UIColor | Color) { let color = value instanceof Color ? value.ios : value; - this._ios.trackTintColor = color; + this.ios.trackTintColor = color; } [backgroundInternalProperty.getDefault](): UIColor { diff --git a/tns-core-modules/ui/scroll-view/scroll-view.android.ts b/tns-core-modules/ui/scroll-view/scroll-view.android.ts index 85a5553a62..f2f33e0e7e 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.android.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.android.ts @@ -86,6 +86,7 @@ export class ScrollView extends ScrollViewBase { } public initNativeView(): void { + super.initNativeView(); if (this._androidViewId < 0) { this._androidViewId = android.view.View.generateViewId(); } diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index f7cfe5aa9a..d5de1e82e0 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -38,10 +38,13 @@ export class ScrollView extends ScrollViewBase { private _contentMeasuredWidth: number = 0; private _contentMeasuredHeight: number = 0; private _delegate: UIScrollViewDelegateImpl; + + public createNativeView() { + return UIScrollView.new(); + } - constructor() { - super(); - this.nativeViewProtected = UIScrollView.new(); + initNativeView() { + super.initNativeView(); this._setNativeClipToBounds(); } diff --git a/tns-core-modules/ui/search-bar/search-bar.android.ts b/tns-core-modules/ui/search-bar/search-bar.android.ts index 9b7982b6fa..d0960125f5 100644 --- a/tns-core-modules/ui/search-bar/search-bar.android.ts +++ b/tns-core-modules/ui/search-bar/search-bar.android.ts @@ -95,10 +95,15 @@ export class SearchBar extends SearchBarBase { } public createNativeView() { - initializeNativeClasses(); const nativeView = new android.support.v7.widget.SearchView(this._context) nativeView.setIconified(false); + return nativeView; + } + public initNativeView(): void { + super.initNativeView(); + const nativeView = this.nativeViewProtected; + initializeNativeClasses(); const queryTextListener = new QueryTextListener(this); nativeView.setOnQueryTextListener(queryTextListener); (nativeView).queryTextListener = queryTextListener; @@ -106,21 +111,14 @@ export class SearchBar extends SearchBarBase { const closeListener = new CloseListener(this); nativeView.setOnCloseListener(closeListener); (nativeView).closeListener = closeListener; - - return nativeView; - } - - public initNativeView(): void { - super.initNativeView(); - const nativeView: any = this.nativeViewProtected; - nativeView.closeListener.owner = this; - nativeView.queryTextListener.owner = this; } public disposeNativeView() { const nativeView: any = this.nativeViewProtected; nativeView.closeListener.owner = null; + nativeView.closeListener = null; nativeView.queryTextListener.owner = null; + nativeView.queryTextListener = null; this._searchPlate = null; this._searchTextView = null; super.disposeNativeView(); diff --git a/tns-core-modules/ui/search-bar/search-bar.ios.ts b/tns-core-modules/ui/search-bar/search-bar.ios.ts index d7d2f73502..2b85cb7105 100644 --- a/tns-core-modules/ui/search-bar/search-bar.ios.ts +++ b/tns-core-modules/ui/search-bar/search-bar.ios.ts @@ -68,25 +68,32 @@ class UISearchBarImpl extends UISearchBar { } export class SearchBar extends SearchBarBase { - private _ios: UISearchBar; + nativeViewProtected: UISearchBar; private _delegate; private __textField: UITextField; private __placeholderLabel: UILabel; - constructor() { - super(); + createNativeView() { + return UISearchBarImpl.new(); + } - this.nativeViewProtected = this._ios = UISearchBarImpl.new(); + initNativeView() { + super.initNativeView(); this._delegate = UISearchBarDelegateImpl.initWithOwner(new WeakRef(this)); } + disposeNativeView() { + this._delegate = null; + super.disposeNativeView(); + } + public onLoaded() { super.onLoaded(); - this._ios.delegate = this._delegate; + this.ios.delegate = this._delegate; } public onUnloaded() { - this._ios.delegate = null; + this.ios.delegate = null; super.onUnloaded(); } @@ -95,7 +102,7 @@ export class SearchBar extends SearchBarBase { } get ios(): UISearchBar { - return this._ios; + return this.nativeViewProtected; } get _textField(): UITextField { @@ -117,11 +124,11 @@ export class SearchBar extends SearchBarBase { } [backgroundColorProperty.getDefault](): UIColor { - return this._ios.barTintColor; + return this.ios.barTintColor; } [backgroundColorProperty.setNative](value: UIColor | Color) { let color: UIColor = value instanceof Color ? value.ios : value; - this._ios.barTintColor = color; + this.ios.barTintColor = color; } [colorProperty.getDefault](): UIColor { @@ -163,7 +170,7 @@ export class SearchBar extends SearchBarBase { } [textProperty.setNative](value: string) { const text = (value === null || value === undefined) ? "" : value.toString(); - this._ios.text = text; + this.ios.text = text; } [hintProperty.getDefault](): string { @@ -171,7 +178,7 @@ export class SearchBar extends SearchBarBase { } [hintProperty.setNative](value: string) { const text = (value === null || value === undefined) ? "" : value.toString(); - this._ios.placeholder = text; + this.ios.placeholder = text; } [textFieldBackgroundColorProperty.getDefault](): UIColor { diff --git a/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts b/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts index c0c9ac774d..06c2f6039b 100644 --- a/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts +++ b/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts @@ -213,24 +213,23 @@ export class SegmentedBar extends SegmentedBarBase { tabHostLayout.addView(frame); nativeView.addView(tabHostLayout); - - const listener = new TabChangeListener(this); - nativeView.setOnTabChangedListener(listener); - (nativeView).listener = listener; - nativeView.setup(); return nativeView; } public initNativeView(): void { super.initNativeView(); - const nativeView: any = this.nativeViewProtected; - nativeView.listener.owner = this; + const nativeView = this.nativeViewProtected; + const listener = new TabChangeListener(this); + nativeView.setOnTabChangedListener(listener); + (nativeView).listener = listener; + nativeView.setup(); this._tabContentFactory = this._tabContentFactory || new TabContentFactory(this); } public disposeNativeView() { const nativeView: any = this.nativeViewProtected; nativeView.listener.owner = null; + nativeView.listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/segmented-bar/segmented-bar.ios.ts b/tns-core-modules/ui/segmented-bar/segmented-bar.ios.ts index c7a7ec16ae..aa7e87c750 100644 --- a/tns-core-modules/ui/segmented-bar/segmented-bar.ios.ts +++ b/tns-core-modules/ui/segmented-bar/segmented-bar.ios.ts @@ -21,33 +21,40 @@ export class SegmentedBarItem extends SegmentedBarItemBase { } export class SegmentedBar extends SegmentedBarBase { - private _ios: UISegmentedControl; + nativeViewProtected: UISegmentedControl; private _selectionHandler: NSObject; - constructor() { - super(); - this.nativeViewProtected = this._ios = UISegmentedControl.new(); + createNativeView() { + return UISegmentedControl.new(); + } + initNativeView() { + super.initNativeView(); this._selectionHandler = SelectionHandlerImpl.initWithOwner(new WeakRef(this)); - this._ios.addTargetActionForControlEvents(this._selectionHandler, "selected", UIControlEvents.ValueChanged); + this.nativeViewProtected.addTargetActionForControlEvents(this._selectionHandler, "selected", UIControlEvents.ValueChanged); + } + + disposeNativeView() { + this._selectionHandler = null; + super.disposeNativeView(); } get ios(): UISegmentedControl { - return this._ios; + return this.nativeViewProtected; } [selectedIndexProperty.getDefault](): number { return -1; } [selectedIndexProperty.setNative](value: number) { - this._ios.selectedSegmentIndex = value; + this.ios.selectedSegmentIndex = value; } [itemsProperty.getDefault](): SegmentedBarItem[] { return null; } [itemsProperty.setNative](value: SegmentedBarItem[]) { - const segmentedControl = this._ios; + const segmentedControl = this.ios; segmentedControl.removeAllSegments(); const newItems = value; @@ -63,11 +70,11 @@ export class SegmentedBar extends SegmentedBarBase { } [selectedBackgroundColorProperty.getDefault](): UIColor { - return this._ios.tintColor; + return this.ios.tintColor; } [selectedBackgroundColorProperty.setNative](value: UIColor | Color) { let color = value instanceof Color ? value.ios : value; - this._ios.tintColor = color; + this.ios.tintColor = color; } [colorProperty.getDefault](): UIColor { @@ -75,7 +82,7 @@ export class SegmentedBar extends SegmentedBarBase { } [colorProperty.setNative](value: Color | UIColor) { let color = value instanceof Color ? value.ios : value; - let bar = this._ios; + let bar = this.ios; let currentAttrs = bar.titleTextAttributesForState(UIControlState.Normal); let attrs = currentAttrs ? currentAttrs.mutableCopy() : NSMutableDictionary.new(); attrs.setValueForKey(color, NSForegroundColorAttributeName); @@ -87,7 +94,7 @@ export class SegmentedBar extends SegmentedBarBase { } [fontInternalProperty.setNative](value: Font) { let font: UIFont = value ? value.getUIFont(UIFont.systemFontOfSize(ios.getter(UIFont, UIFont.labelFontSize))) : null; - let bar = this._ios; + let bar = this.ios; let currentAttrs = bar.titleTextAttributesForState(UIControlState.Normal); let attrs = currentAttrs ? currentAttrs.mutableCopy() : NSMutableDictionary.new(); attrs.setValueForKey(font, NSFontAttributeName); diff --git a/tns-core-modules/ui/slider/slider.android.ts b/tns-core-modules/ui/slider/slider.android.ts index 4a4edbb34e..e7d4a9e2e3 100644 --- a/tns-core-modules/ui/slider/slider.android.ts +++ b/tns-core-modules/ui/slider/slider.android.ts @@ -13,11 +13,8 @@ interface OwnerSeekBar extends android.widget.SeekBar { let SeekBar: typeof android.widget.SeekBar; let SeekBarChangeListener: android.widget.SeekBar.OnSeekBarChangeListener; -function initializeModule(): void { - if (!SeekBar) { - SeekBar = android.widget.SeekBar; - } - +function initializeListenerClass(): void { + if (!SeekBarChangeListener) { @Interfaces([android.widget.SeekBar.OnSeekBarChangeListener]) class SeekBarChangeListenerImpl extends java.lang.Object implements android.widget.SeekBar.OnSeekBarChangeListener { @@ -56,16 +53,18 @@ export class Slider extends SliderBase { nativeViewProtected: OwnerSeekBar; public createNativeView() { - initializeModule(); - const nativeView = new SeekBar(this._context); - const listener = getListener(); - nativeView.setOnSeekBarChangeListener(listener); - return nativeView; + if (!SeekBar) { + SeekBar = android.widget.SeekBar; + } + return new SeekBar(this._context); } public initNativeView(): void { super.initNativeView(); - this.nativeViewProtected.owner = this; + const nativeView = this.nativeViewProtected; + initializeListenerClass(); + const listener = getListener(); + nativeView.setOnSeekBarChangeListener(listener); } public disposeNativeView() { diff --git a/tns-core-modules/ui/slider/slider.ios.ts b/tns-core-modules/ui/slider/slider.ios.ts index b738af4a99..5a4845b7e1 100644 --- a/tns-core-modules/ui/slider/slider.ios.ts +++ b/tns-core-modules/ui/slider/slider.ios.ts @@ -31,58 +31,65 @@ class SliderChangeHandlerImpl extends NSObject { } export class Slider extends SliderBase { - private _ios: UISlider; + nativeViewProtected: UISlider; private _changeHandler: NSObject; + + public createNativeView() { + return UISlider.new(); + } - constructor() { - super(); - this.nativeViewProtected = this._ios = UISlider.new(); - + public initNativeView(): void { + super.initNativeView(); + const nativeView = this.nativeViewProtected; // default values - this._ios.minimumValue = 0; - this._ios.maximumValue = this.maxValue; - + nativeView.minimumValue = 0; + nativeView.maximumValue = this.maxValue; this._changeHandler = SliderChangeHandlerImpl.initWithOwner(new WeakRef(this)); - this._ios.addTargetActionForControlEvents(this._changeHandler, "sliderValueChanged", UIControlEvents.ValueChanged); + nativeView.addTargetActionForControlEvents(this._changeHandler, "sliderValueChanged", UIControlEvents.ValueChanged); + } + + public disposeNativeView() { + this._changeHandler = null; + super.disposeNativeView(); } get ios(): UISlider { - return this._ios; + return this.nativeViewProtected; } [valueProperty.getDefault](): number { return 0; } [valueProperty.setNative](value: number) { - this._ios.value = value; + this.ios.value = value; } [minValueProperty.getDefault](): number { return 0; } [minValueProperty.setNative](value: number) { - this._ios.minimumValue = value; + this.ios.minimumValue = value; } [maxValueProperty.getDefault](): number { return 100; } [maxValueProperty.setNative](value: number) { - this._ios.maximumValue = value; + this.ios.maximumValue = value; } [colorProperty.getDefault](): UIColor { - return this._ios.thumbTintColor; + return this.ios.thumbTintColor; } [colorProperty.setNative](value: UIColor | Color) { let color = value instanceof Color ? value.ios : value; - this._ios.thumbTintColor = color; + this.ios.thumbTintColor = color; } [backgroundColorProperty.getDefault](): UIColor { - return this._ios.minimumTrackTintColor; + return this.ios.minimumTrackTintColor; } [backgroundColorProperty.setNative](value: UIColor | Color) { let color = value instanceof Color ? value.ios : value; - this._ios.minimumTrackTintColor = color; + this.ios.minimumTrackTintColor = color; } [backgroundInternalProperty.getDefault](): Background { diff --git a/tns-core-modules/ui/switch/switch.android.ts b/tns-core-modules/ui/switch/switch.android.ts index 03f529b4f2..46151d6e63 100644 --- a/tns-core-modules/ui/switch/switch.android.ts +++ b/tns-core-modules/ui/switch/switch.android.ts @@ -36,23 +36,22 @@ export class Switch extends SwitchBase { public checked: boolean; public createNativeView() { - initializeCheckedChangeListener(); - const nativeView = new android.widget.Switch(this._context); - const listener = new CheckedChangeListener(this); - nativeView.setOnCheckedChangeListener(listener); - (nativeView).listener = listener; - return nativeView; + return new android.widget.Switch(this._context); } public initNativeView(): void { super.initNativeView(); - const nativeView: any = this.nativeViewProtected; - nativeView.listener.owner = this; + const nativeView = this.nativeViewProtected; + initializeCheckedChangeListener(); + const listener = new CheckedChangeListener(this); + nativeView.setOnCheckedChangeListener(listener); + (nativeView).listener = listener; } public disposeNativeView() { const nativeView: any = this.nativeViewProtected; nativeView.listener.owner = null; + nativeView.listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/switch/switch.ios.ts b/tns-core-modules/ui/switch/switch.ios.ts index 957ba9d707..8acb707976 100644 --- a/tns-core-modules/ui/switch/switch.ios.ts +++ b/tns-core-modules/ui/switch/switch.ios.ts @@ -33,14 +33,26 @@ export class Switch extends SwitchBase { constructor() { super(); - const nativeView = UISwitch.new(); - this._handler = SwitchChangeHandlerImpl.initWithOwner(new WeakRef(this)); - nativeView.addTargetActionForControlEvents(this._handler, "valueChanged", UIControlEvents.ValueChanged); - this.nativeViewProtected = nativeView; this.width = 51; this.height = 31; } + public createNativeView() { + return UISwitch.new(); + } + + public initNativeView(): void { + super.initNativeView(); + const nativeView = this.nativeViewProtected; + this._handler = SwitchChangeHandlerImpl.initWithOwner(new WeakRef(this)); + nativeView.addTargetActionForControlEvents(this._handler, "valueChanged", UIControlEvents.ValueChanged); + } + + public disposeNativeView() { + this._handler = null; + super.disposeNativeView(); + } + get ios(): UISwitch { return this.nativeViewProtected; } diff --git a/tns-core-modules/ui/tab-view/tab-view.ios.ts b/tns-core-modules/ui/tab-view/tab-view.ios.ts index 92a12d043e..fd936231da 100644 --- a/tns-core-modules/ui/tab-view/tab-view.ios.ts +++ b/tns-core-modules/ui/tab-view/tab-view.ios.ts @@ -205,9 +205,18 @@ export class TabView extends TabViewBase { this.viewController = this._ios = UITabBarControllerImpl.initWithOwner(new WeakRef(this)); this.nativeViewProtected = this._ios.view; + } + + initNativeView() { + super.initNativeView(); this._delegate = UITabBarControllerDelegateImpl.initWithOwner(new WeakRef(this)); this._moreNavigationControllerDelegate = UINavigationControllerDelegateImpl.initWithOwner(new WeakRef(this)); - //This delegate is set on the last line of _addTabs method. + } + + disposeNativeView() { + this._delegate = null; + this._moreNavigationControllerDelegate = null; + super.disposeNativeView(); } @profile diff --git a/tns-core-modules/ui/text-base/text-base.android.ts b/tns-core-modules/ui/text-base/text-base.android.ts index e6ade7fb7e..61131348e3 100644 --- a/tns-core-modules/ui/text-base/text-base.android.ts +++ b/tns-core-modules/ui/text-base/text-base.android.ts @@ -58,6 +58,7 @@ export class TextBase extends TextBaseCommon { private _maxLines: number; public initNativeView(): void { + super.initNativeView(); initializeTextTransformation(); const nativeView = this.nativeTextViewProtected; this._defaultTransformationMethod = nativeView.getTransformationMethod(); @@ -65,7 +66,6 @@ export class TextBase extends TextBaseCommon { this._maxHeight = nativeView.getMaxHeight(); this._minLines = nativeView.getMinLines(); this._maxLines = nativeView.getMaxLines(); - super.initNativeView(); } public resetNativeView(): void { diff --git a/tns-core-modules/ui/text-field/text-field.ios.ts b/tns-core-modules/ui/text-field/text-field.ios.ts index b61bd3019c..c26cf960c9 100644 --- a/tns-core-modules/ui/text-field/text-field.ios.ts +++ b/tns-core-modules/ui/text-field/text-field.ios.ts @@ -141,31 +141,36 @@ class UITextFieldImpl extends UITextField { } export class TextField extends TextFieldBase { - private _ios: UITextField; - private _delegate: UITextFieldDelegateImpl; nativeViewProtected: UITextField; + private _delegate: UITextFieldDelegateImpl; createNativeView() { return UITextFieldImpl.initWithOwner(new WeakRef(this)); } - initNativeViewDelegates(view: UITextFieldImpl) { + initNativeView() { + super.initNativeView(); this._delegate = UITextFieldDelegateImpl.initWithOwner(new WeakRef(this)); } + disposeNativeView() { + this._delegate = null; + super.disposeNativeView(); + } + @profile public onLoaded() { super.onLoaded(); - this._ios.delegate = this._delegate; + this.ios.delegate = this._delegate; } public onUnloaded() { - this._ios.delegate = null; + this.ios.delegate = null; super.onUnloaded(); } get ios(): UITextField { - return this._ios; + return this.nativeViewProtected; } [hintProperty.getDefault](): string { diff --git a/tns-core-modules/ui/text-view/text-view.ios.ts b/tns-core-modules/ui/text-view/text-view.ios.ts index 2a3e4480f1..31dcb41765 100644 --- a/tns-core-modules/ui/text-view/text-view.ios.ts +++ b/tns-core-modules/ui/text-view/text-view.ios.ts @@ -97,38 +97,42 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate { @CSSType("TextView") export class TextView extends EditableTextBase implements TextViewDefinition { - private _ios: UITextView; + nativeViewProtected: UITextView; private _delegate: UITextViewDelegateImpl; private _isShowingHint: boolean; public _isEditing: boolean; createNativeView() { - if (this.nativeViewProtected) { - return this.nativeViewProtected; - } - const textView = this._ios = this.nativeViewProtected = UITextView.new(); + const textView = UITextView.new(); if (!textView.font) { textView.font = UIFont.systemFontOfSize(12); } return textView; } - initNativeViewDelegates(view: UITextView) { + + initNativeView() { + super.initNativeView(); this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this)); } + disposeNativeView() { + this._delegate = null; + super.disposeNativeView(); + } + @profile public onLoaded() { super.onLoaded(); - this._ios.delegate = this._delegate; + this.ios.delegate = this._delegate; } public onUnloaded() { - this._ios.delegate = null; + this.ios.delegate = null; super.onUnloaded(); } get ios(): UITextView { - return this._ios; + return this.nativeViewProtected; } public _refreshHintState(hint: string, text: string) { diff --git a/tns-core-modules/ui/time-picker/time-picker.android.ts b/tns-core-modules/ui/time-picker/time-picker.android.ts index fb5828897f..7a86a992ac 100644 --- a/tns-core-modules/ui/time-picker/time-picker.android.ts +++ b/tns-core-modules/ui/time-picker/time-picker.android.ts @@ -43,21 +43,18 @@ export class TimePicker extends TimePickerBase { updatingNativeValue: boolean; public createNativeView() { - initializeTimeChangedListener(); - const nativeView = new android.widget.TimePicker(this._context); - const listener = new TimeChangedListener(this); - nativeView.setOnTimeChangedListener(listener); - (nativeView).listener = listener; - (nativeView).calendar = java.util.Calendar.getInstance(); - return nativeView; + return new android.widget.TimePicker(this._context); } public initNativeView(): void { super.initNativeView(); - const nativeView: any = this.nativeViewProtected; - nativeView.listener.owner = this; + const nativeView = this.nativeViewProtected; + initializeTimeChangedListener(); + const listener = new TimeChangedListener(this); + nativeView.setOnTimeChangedListener(listener); + (nativeView).listener = listener; + const calendar = (nativeView).calendar = java.util.Calendar.getInstance(); - const calendar = (nativeView).calendar; const hour = hourProperty.isSet(this) ? this.hour : calendar.get(java.util.Calendar.HOUR_OF_DAY); const minute = minuteProperty.isSet(this) ? this.minute : calendar.get(java.util.Calendar.MINUTE); diff --git a/tns-core-modules/ui/time-picker/time-picker.ios.ts b/tns-core-modules/ui/time-picker/time-picker.ios.ts index cf60936a85..25688987f1 100644 --- a/tns-core-modules/ui/time-picker/time-picker.ios.ts +++ b/tns-core-modules/ui/time-picker/time-picker.ios.ts @@ -21,27 +21,35 @@ function getComponents(date: Date | NSDate): NSDateComponents { } export class TimePicker extends TimePickerBase { - private _ios: UIDatePicker; + nativeViewProtected: UIDatePicker; private _changeHandler: NSObject; - public nativeViewProtected: UIDatePicker; constructor() { super(); + let components = getComponents(NSDate.date()); + this.hour = components.hour; + this.minute = components.minute; + } - this._ios = UIDatePicker.new(); - this._ios.datePickerMode = UIDatePickerMode.Time; + createNativeView() { + const picker = UIDatePicker.new(); + picker.datePickerMode = UIDatePickerMode.Time; + return picker; + } + initNativeView() { + super.initNativeView(); this._changeHandler = UITimePickerChangeHandlerImpl.initWithOwner(new WeakRef(this)); - this._ios.addTargetActionForControlEvents(this._changeHandler, "valueChanged", UIControlEvents.ValueChanged); + this.nativeViewProtected.addTargetActionForControlEvents(this._changeHandler, "valueChanged", UIControlEvents.ValueChanged); + } - let components = getComponents(NSDate.date()); - this.hour = components.hour; - this.minute = components.minute; - this.nativeViewProtected = this._ios; + disposeNativeView() { + this._changeHandler = null; + super.initNativeView(); } get ios(): UIDatePicker { - return this._ios; + return this.nativeViewProtected; } [timeProperty.getDefault](): Date { diff --git a/tns-core-modules/ui/web-view/web-view.android.ts b/tns-core-modules/ui/web-view/web-view.android.ts index 2a6e6d8857..a7455b1865 100644 --- a/tns-core-modules/ui/web-view/web-view.android.ts +++ b/tns-core-modules/ui/web-view/web-view.android.ts @@ -93,20 +93,19 @@ export class WebView extends WebViewBase { nativeViewProtected: android.webkit.WebView; public createNativeView() { - initializeWebViewClient(); - const nativeView = new android.webkit.WebView(this._context); nativeView.getSettings().setJavaScriptEnabled(true); nativeView.getSettings().setBuiltInZoomControls(true); - const client = new WebViewClient(this); - nativeView.setWebViewClient(client); - (nativeView).client = client; return nativeView; } public initNativeView(): void { super.initNativeView(); - (this.nativeViewProtected).client.owner = this; + initializeWebViewClient(); + const nativeView = this.nativeViewProtected; + const client = new WebViewClient(this); + nativeView.setWebViewClient(client); + (nativeView).client = client; } public disposeNativeView() { @@ -116,6 +115,7 @@ export class WebView extends WebViewBase { } (nativeView).client.owner = null; + (nativeView).client = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/web-view/web-view.ios.ts b/tns-core-modules/ui/web-view/web-view.ios.ts index 403871ef6f..9d518d85eb 100644 --- a/tns-core-modules/ui/web-view/web-view.ios.ts +++ b/tns-core-modules/ui/web-view/web-view.ios.ts @@ -83,25 +83,33 @@ export class WebView extends WebViewBase { private _ios: WKWebView; private _delegate: any; - constructor() { - super(); - const configuration = WKWebViewConfiguration.new(); - this._delegate = WKNavigationDelegateImpl.initWithOwner(new WeakRef(this)); + createNativeView() { const jScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'initial-scale=1.0'); document.getElementsByTagName('head')[0].appendChild(meta);"; const wkUScript = WKUserScript.alloc().initWithSourceInjectionTimeForMainFrameOnly(jScript, WKUserScriptInjectionTime.AtDocumentEnd, true); const wkUController = WKUserContentController.new(); wkUController.addUserScript(wkUScript); + const configuration = WKWebViewConfiguration.new(); configuration.userContentController = wkUController; configuration.preferences.setValueForKey( true, "allowFileAccessFromFileURLs" ); - this.nativeViewProtected = this._ios = new WKWebView({ + return new WKWebView({ frame: CGRectZero, configuration: configuration }); } + initNativeView() { + super.initNativeView(); + this._delegate = WKNavigationDelegateImpl.initWithOwner(new WeakRef(this)); + } + + disposeNativeView() { + this._delegate = null; + super.disposeNativeView(); + } + @profile public onLoaded() { super.onLoaded(); From 5a5b1c640d41540d13889b77856da09e058361cf Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 21 Aug 2018 15:08:47 +0200 Subject: [PATCH 11/33] cleanup after comments --- tns-core-modules/ui/action-bar/action-bar.android.ts | 1 - tns-core-modules/ui/button/button.android.ts | 1 - tns-core-modules/ui/date-picker/date-picker.android.ts | 1 - .../ui/editable-text-base/editable-text-base.android.ts | 1 - tns-core-modules/ui/image/image.android.ts | 1 - tns-core-modules/ui/image/image.ios.ts | 2 -- tns-core-modules/ui/label/label.ios.ts | 4 ++-- tns-core-modules/ui/list-picker/list-picker.android.ts | 2 -- tns-core-modules/ui/list-view/list-view.android.ts | 2 -- tns-core-modules/ui/search-bar/search-bar.android.ts | 2 -- tns-core-modules/ui/switch/switch.android.ts | 1 - tns-core-modules/ui/web-view/web-view.android.ts | 1 - 12 files changed, 2 insertions(+), 17 deletions(-) diff --git a/tns-core-modules/ui/action-bar/action-bar.android.ts b/tns-core-modules/ui/action-bar/action-bar.android.ts index f4ea736ebd..42fddf9dba 100644 --- a/tns-core-modules/ui/action-bar/action-bar.android.ts +++ b/tns-core-modules/ui/action-bar/action-bar.android.ts @@ -145,7 +145,6 @@ export class ActionBar extends ActionBarBase { public disposeNativeView() { (this.nativeViewProtected).menuItemClickListener.owner = null; - (this.nativeViewProtected).menuItemClickListener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/button/button.android.ts b/tns-core-modules/ui/button/button.android.ts index 50417e0bbb..e2586a963e 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -64,7 +64,6 @@ export class Button extends ButtonBase { public disposeNativeView() { if (this.nativeViewProtected) { (this.nativeViewProtected).clickListener.owner = null; - (this.nativeViewProtected).clickListener = null; } super.disposeNativeView(); } diff --git a/tns-core-modules/ui/date-picker/date-picker.android.ts b/tns-core-modules/ui/date-picker/date-picker.android.ts index 802bd778d6..a4fdc54b47 100644 --- a/tns-core-modules/ui/date-picker/date-picker.android.ts +++ b/tns-core-modules/ui/date-picker/date-picker.android.ts @@ -70,7 +70,6 @@ export class DatePicker extends DatePickerBase { public disposeNativeView() { (this.nativeViewProtected).listener.owner = null; - (this.nativeViewProtected).listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts index f1996af386..5ac152b4e9 100644 --- a/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts +++ b/tns-core-modules/ui/editable-text-base/editable-text-base.android.ts @@ -174,7 +174,6 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { public disposeNativeView(): void { (this.nativeTextViewProtected).listener.owner = null; - (this.nativeTextViewProtected).listener = null; this._keyListenerCache = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/image/image.android.ts b/tns-core-modules/ui/image/image.android.ts index 759cbc8407..1ce6f67978 100644 --- a/tns-core-modules/ui/image/image.android.ts +++ b/tns-core-modules/ui/image/image.android.ts @@ -64,7 +64,6 @@ export class Image extends ImageBase { public disposeNativeView() { (this.nativeViewProtected).listener.owner = null; - (this.nativeViewProtected).listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/image/image.ios.ts b/tns-core-modules/ui/image/image.ios.ts index 1806185081..31c1119214 100644 --- a/tns-core-modules/ui/image/image.ios.ts +++ b/tns-core-modules/ui/image/image.ios.ts @@ -14,8 +14,6 @@ export class Image extends ImageBase { const imageView = UIImageView.new(); imageView.contentMode = UIViewContentMode.ScaleAspectFit; imageView.userInteractionEnabled = true; - this.nativeViewProtected = imageView; - this._setNativeClipToBounds(); return imageView; } diff --git a/tns-core-modules/ui/label/label.ios.ts b/tns-core-modules/ui/label/label.ios.ts index 4e0b2288fb..242bf1036f 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -24,7 +24,7 @@ export class Label extends TextBase implements LabelDefinition { private _fixedSize: FixedSize; public createNativeView() { - const view = this.nativeViewProtected = TNSLabel.new(); + const view = TNSLabel.new(); view.userInteractionEnabled = true; return view; } @@ -36,7 +36,7 @@ export class Label extends TextBase implements LabelDefinition { get textWrap(): boolean { return this.style.whiteSpace === "normal"; } - set textWrap(value: boolean) { + set textWrap(value: boolean) { if (typeof value === "string") { value = booleanConverter(value) } diff --git a/tns-core-modules/ui/list-picker/list-picker.android.ts b/tns-core-modules/ui/list-picker/list-picker.android.ts index 79db08e0db..da96caeb91 100644 --- a/tns-core-modules/ui/list-picker/list-picker.android.ts +++ b/tns-core-modules/ui/list-picker/list-picker.android.ts @@ -111,9 +111,7 @@ export class ListPicker extends ListPickerBase { public disposeNativeView() { const nativeView = this.nativeViewProtected; (nativeView).formatter.owner = null; - (nativeView).formatter = null; (nativeView).valueChangedListener.owner = null; - (nativeView).valueChangedListener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/list-view/list-view.android.ts b/tns-core-modules/ui/list-view/list-view.android.ts index 92cdeae042..2898272ef3 100644 --- a/tns-core-modules/ui/list-view/list-view.android.ts +++ b/tns-core-modules/ui/list-view/list-view.android.ts @@ -85,9 +85,7 @@ export class ListView extends ListViewBase { const nativeView = this.nativeViewProtected; nativeView.setAdapter(null); (nativeView).itemClickListener.owner = null; - (nativeView).itemClickListener = null; (nativeView).adapter.owner = null; - (nativeView).adapter = null; this.clearRealizedCells(); super.disposeNativeView(); } diff --git a/tns-core-modules/ui/search-bar/search-bar.android.ts b/tns-core-modules/ui/search-bar/search-bar.android.ts index d0960125f5..7552216fb5 100644 --- a/tns-core-modules/ui/search-bar/search-bar.android.ts +++ b/tns-core-modules/ui/search-bar/search-bar.android.ts @@ -116,9 +116,7 @@ export class SearchBar extends SearchBarBase { public disposeNativeView() { const nativeView: any = this.nativeViewProtected; nativeView.closeListener.owner = null; - nativeView.closeListener = null; nativeView.queryTextListener.owner = null; - nativeView.queryTextListener = null; this._searchPlate = null; this._searchTextView = null; super.disposeNativeView(); diff --git a/tns-core-modules/ui/switch/switch.android.ts b/tns-core-modules/ui/switch/switch.android.ts index 46151d6e63..0a3e26e36a 100644 --- a/tns-core-modules/ui/switch/switch.android.ts +++ b/tns-core-modules/ui/switch/switch.android.ts @@ -51,7 +51,6 @@ export class Switch extends SwitchBase { public disposeNativeView() { const nativeView: any = this.nativeViewProtected; nativeView.listener.owner = null; - nativeView.listener = null; super.disposeNativeView(); } diff --git a/tns-core-modules/ui/web-view/web-view.android.ts b/tns-core-modules/ui/web-view/web-view.android.ts index a7455b1865..e059ee998e 100644 --- a/tns-core-modules/ui/web-view/web-view.android.ts +++ b/tns-core-modules/ui/web-view/web-view.android.ts @@ -115,7 +115,6 @@ export class WebView extends WebViewBase { } (nativeView).client.owner = null; - (nativeView).client = null; super.disposeNativeView(); } From 39a57c1ed9ac7413c7d4d309dea467c4726da6c3 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 21 Aug 2018 15:55:38 +0200 Subject: [PATCH 12/33] fixed webview to use nativeviewprotected like other widgets --- tns-core-modules/ui/web-view/web-view.ios.ts | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tns-core-modules/ui/web-view/web-view.ios.ts b/tns-core-modules/ui/web-view/web-view.ios.ts index 9d518d85eb..67425f4758 100644 --- a/tns-core-modules/ui/web-view/web-view.ios.ts +++ b/tns-core-modules/ui/web-view/web-view.ios.ts @@ -80,7 +80,7 @@ class WKNavigationDelegateImpl extends NSObject } export class WebView extends WebViewBase { - private _ios: WKWebView; + nativeViewProtected: WKWebView; private _delegate: any; createNativeView() { @@ -113,51 +113,51 @@ export class WebView extends WebViewBase { @profile public onLoaded() { super.onLoaded(); - this._ios.navigationDelegate = this._delegate; + this.ios.navigationDelegate = this._delegate; } public onUnloaded() { - this._ios.navigationDelegate = null; + this.ios.navigationDelegate = null; super.onUnloaded(); } get ios(): WKWebView { - return this._ios; + return this.nativeViewProtected; } public stopLoading() { - this._ios.stopLoading(); + this.ios.stopLoading(); } public _loadUrl(src: string) { if (src.startsWith("file:///")) { - this._ios.loadFileURLAllowingReadAccessToURL(NSURL.URLWithString(src), NSURL.URLWithString(src)); + this.ios.loadFileURLAllowingReadAccessToURL(NSURL.URLWithString(src), NSURL.URLWithString(src)); } else { - this._ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src))); + this.ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src))); } } public _loadData(content: string) { - this._ios.loadHTMLStringBaseURL(content, NSURL.alloc().initWithString(`file:///${knownFolders.currentApp().path}/`)); + this.ios.loadHTMLStringBaseURL(content, NSURL.alloc().initWithString(`file:///${knownFolders.currentApp().path}/`)); } get canGoBack(): boolean { - return this._ios.canGoBack; + return this.ios.canGoBack; } get canGoForward(): boolean { - return this._ios.canGoForward; + return this.ios.canGoForward; } public goBack() { - this._ios.goBack(); + this.ios.goBack(); } public goForward() { - this._ios.goForward(); + this.ios.goForward(); } public reload() { - this._ios.reload(); + this.ios.reload(); } } \ No newline at end of file From 29dc093265855f695e15b2a9e189bcb5cf550b23 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 21 Aug 2018 15:56:14 +0200 Subject: [PATCH 13/33] cleanup after comment --- tns-core-modules/ui/segmented-bar/segmented-bar.android.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts b/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts index 06c2f6039b..11128a7c01 100644 --- a/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts +++ b/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts @@ -229,7 +229,6 @@ export class SegmentedBar extends SegmentedBarBase { public disposeNativeView() { const nativeView: any = this.nativeViewProtected; nativeView.listener.owner = null; - nativeView.listener = null; super.disposeNativeView(); } From 1295fa304f90f96940968b076ea08f7c222de095 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Tue, 21 Aug 2018 17:48:46 +0300 Subject: [PATCH 14/33] fix tslint errors from merge conflict --- tns-core-modules/ui/list-view/list-view.ios.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/list-view/list-view.ios.ts b/tns-core-modules/ui/list-view/list-view.ios.ts index 157a89d5ee..83c9697d65 100644 --- a/tns-core-modules/ui/list-view/list-view.ios.ts +++ b/tns-core-modules/ui/list-view/list-view.ios.ts @@ -280,7 +280,7 @@ export class ListView extends ListViewBase { } private _scrollToIndex(index: number, animated: boolean = true) { - if (!this._ios) { + if (!this.ios) { return; } @@ -293,7 +293,7 @@ export class ListView extends ListViewBase { index = itemsLength - 1; } - this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), + this.ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), UITableViewScrollPosition.Top, animated); } else if (trace.isEnabled()) { trace.write(`Cannot scroll listview to index ${index} when listview items not set`, trace.categories.Binding); From 7c17708ef529132c9ee76307b8a39e9308602acd Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 22 Aug 2018 10:52:52 +0200 Subject: [PATCH 15/33] test fixes --- tns-core-modules/ui/action-bar/action-bar.android.ts | 2 +- tns-core-modules/ui/button/button.android.ts | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tns-core-modules/ui/action-bar/action-bar.android.ts b/tns-core-modules/ui/action-bar/action-bar.android.ts index 42fddf9dba..c8e435c12c 100644 --- a/tns-core-modules/ui/action-bar/action-bar.android.ts +++ b/tns-core-modules/ui/action-bar/action-bar.android.ts @@ -140,7 +140,7 @@ export class ActionBar extends ActionBarBase { initializeMenuItemClickListener(); const menuItemClickListener = new MenuItemClickListener(this); nativeView.setOnMenuItemClickListener(menuItemClickListener); - (toolbar).menuItemClickListener = menuItemClickListener; + (nativeView).menuItemClickListener = menuItemClickListener; } public disposeNativeView() { diff --git a/tns-core-modules/ui/button/button.android.ts b/tns-core-modules/ui/button/button.android.ts index e2586a963e..ef9e8bbccc 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -37,18 +37,26 @@ function initializeClickListener(): void { } ClickListener = ClickListenerImpl; - APILEVEL = android.os.Build.VERSION.SDK_INT; - AndroidButton = android.widget.Button; } export class Button extends ButtonBase { nativeViewProtected: android.widget.Button; + constructor() { + super(); + if (!APILEVEL) { + APILEVEL = android.os.Build.VERSION.SDK_INT; + } + } + private _stateListAnimator: any; private _highlightedHandler: (args: TouchGestureEventData) => void; @profile public createNativeView() { + if (!AndroidButton) { + AndroidButton = android.widget.Button; + } return new AndroidButton(this._context); } From 5b08639b5239dfe36ee1c1af20d313eca83a0640 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Wed, 22 Aug 2018 17:15:34 +0300 Subject: [PATCH 16/33] fix android slider native view owner assignment --- tns-core-modules/ui/slider/slider.android.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/slider/slider.android.ts b/tns-core-modules/ui/slider/slider.android.ts index e7d4a9e2e3..66222ed7bf 100644 --- a/tns-core-modules/ui/slider/slider.android.ts +++ b/tns-core-modules/ui/slider/slider.android.ts @@ -25,7 +25,7 @@ function initializeListenerClass(): void { onProgressChanged(seekBar: OwnerSeekBar, progress: number, fromUser: boolean): void { const owner = seekBar.owner; - if (!owner._supressNativeValue) { + if (owner && !owner._supressNativeValue) { const newValue = progress + owner.minValue; valueProperty.nativeValueChange(owner, newValue); } @@ -62,6 +62,7 @@ export class Slider extends SliderBase { public initNativeView(): void { super.initNativeView(); const nativeView = this.nativeViewProtected; + nativeView.owner = this; initializeListenerClass(); const listener = getListener(); nativeView.setOnSeekBarChangeListener(listener); @@ -139,4 +140,4 @@ export class Slider extends SliderBase { [backgroundInternalProperty.setNative](value: Background) { // } -} \ No newline at end of file +} From 2038a10cfb1b4b95aab79488c9a422ba74c1ff80 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 22 Aug 2018 19:28:30 +0200 Subject: [PATCH 17/33] ensure nativeViewProtected is created --- tns-core-modules/ui/scroll-view/scroll-view.ios.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index d5de1e82e0..ab236582d6 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -71,15 +71,15 @@ export class ScrollView extends ScrollViewBase { } get horizontalOffset(): number { - return this.nativeViewProtected.contentOffset.x; + return this.nativeViewProtected ? this.nativeViewProtected.contentOffset.x : 0; } get verticalOffset(): number { - return this.nativeViewProtected.contentOffset.y; + return this.nativeViewProtected ? this.nativeViewProtected.contentOffset.y : 0; } get scrollableWidth(): number { - if (this.orientation !== "horizontal") { + if (!this.nativeViewProtected || this.orientation !== "horizontal") { return 0; } @@ -87,7 +87,7 @@ export class ScrollView extends ScrollViewBase { } get scrollableHeight(): number { - if (this.orientation !== "vertical") { + if (!this.nativeViewProtected || this.orientation !== "vertical") { return 0; } @@ -102,14 +102,14 @@ export class ScrollView extends ScrollViewBase { } public scrollToVerticalOffset(value: number, animated: boolean) { - if (this.orientation === "vertical") { + if (this.nativeViewProtected && this.orientation === "vertical") { const bounds = this.nativeViewProtected.bounds.size; this.nativeViewProtected.scrollRectToVisibleAnimated(CGRectMake(0, value, bounds.width, bounds.height), animated); } } public scrollToHorizontalOffset(value: number, animated: boolean) { - if (this.orientation === "horizontal") { + if (this.nativeViewProtected && this.orientation === "horizontal") { const bounds = this.nativeViewProtected.bounds.size; this.nativeViewProtected.scrollRectToVisibleAnimated(CGRectMake(value, 0, bounds.width, bounds.height), animated); } From 4fabdac79cb71e2312742f072793d1c96576f2c2 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 22 Aug 2018 19:34:14 +0200 Subject: [PATCH 18/33] fixed _map being created too late --- tns-core-modules/ui/list-view/list-view.ios.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/list-view/list-view.ios.ts b/tns-core-modules/ui/list-view/list-view.ios.ts index 83c9697d65..8ef9ad07e9 100644 --- a/tns-core-modules/ui/list-view/list-view.ios.ts +++ b/tns-core-modules/ui/list-view/list-view.ios.ts @@ -215,6 +215,12 @@ export class ListView extends ListViewBase { private _map: Map; widthMeasureSpec: number = 0; + constructor() { + super(); + this._map = new Map(); + this._heights = new Array(); + } + createNativeView() { return UITableView.new(); } @@ -227,8 +233,6 @@ export class ListView extends ListViewBase { nativeView.rowHeight = UITableViewAutomaticDimension; nativeView.dataSource = this._dataSource = DataSource.initWithOwner(new WeakRef(this)); this._delegate = UITableViewDelegateImpl.initWithOwner(new WeakRef(this)); - this._heights = new Array(); - this._map = new Map(); this._setNativeClipToBounds(); } From 9908b4b60a87d2241439cec1108aeaf54a9f861b Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Thu, 23 Aug 2018 09:44:03 +0200 Subject: [PATCH 19/33] call _addView first so that nativeViewProtected is created --- tns-core-modules/ui/list-view/list-view.ios.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/list-view/list-view.ios.ts b/tns-core-modules/ui/list-view/list-view.ios.ts index 8ef9ad07e9..ed637f2837 100644 --- a/tns-core-modules/ui/list-view/list-view.ios.ts +++ b/tns-core-modules/ui/list-view/list-view.ios.ts @@ -439,9 +439,9 @@ export class ListView extends ListViewBase { this._map.set(cell, view); // We expect that views returned from itemLoading are new (e.g. not reused). - if (view && !view.parent && view.nativeViewProtected) { - cell.contentView.addSubview(view.nativeViewProtected); + if (view && !view.parent) { this._addView(view); + cell.contentView.addSubview(view.nativeViewProtected); } cellHeight = this._layoutCell(view, indexPath); From e80f1cd97962e87f12fc8d97bb82b2caaf6cd8f3 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 10:29:07 +0200 Subject: [PATCH 20/33] =?UTF-8?q?make=20sure=20nativeViewProtected=20is=20?= =?UTF-8?q?never=20=E2=80=9Ccleared=E2=80=9D.=20That=20way=20it=20is=20set?= =?UTF-8?q?up=20correctly=20when=20needed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tns-core-modules/ui/page/page.ios.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index 6f57c2c170..62a9076919 100644 --- a/tns-core-modules/ui/page/page.ios.ts +++ b/tns-core-modules/ui/page/page.ios.ts @@ -231,8 +231,11 @@ export class Page extends PageBase { super(); const controller = UIViewControllerImpl.initWithOwner(new WeakRef(this)); this.viewController = this._ios = controller; - this.nativeViewProtected = controller.view; - this.nativeViewProtected.backgroundColor = whiteColor; + controller.view.backgroundColor = whiteColor; + } + + createNativeView() { + return this.viewController.view; } get ios(): UIViewController { From 516543285fe5e8686582a7fe8b3d81b42098fe3b Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 11:24:51 +0200 Subject: [PATCH 21/33] fixed tests for iOS now that we use createNativeView --- tests/app/ui/view/view-tests-common.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/app/ui/view/view-tests-common.ts b/tests/app/ui/view/view-tests-common.ts index 1ac2050117..14681a491a 100644 --- a/tests/app/ui/view/view-tests-common.ts +++ b/tests/app/ui/view/view-tests-common.ts @@ -345,19 +345,8 @@ class TestView extends LayoutBase { (this.style).customShortHand = value; } - private _nativeView; constructor(public name: string) { super(); - this._nativeView = this.nativeViewProtected; - this.nativeViewProtected = undefined; - } - - public createNativeView() { - if (isIOS) { - return this._nativeView; - } - - return super.createNativeView(); } public toString() { From 8f59cb82c2d5c7a217ddaa5011bdbabf511f04a0 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 11:25:15 +0200 Subject: [PATCH 22/33] now that we use createNativeView the order is important and setupUI must be called first --- tns-core-modules/application/application.ios.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tns-core-modules/application/application.ios.ts b/tns-core-modules/application/application.ios.ts index 87a8523585..9308aafce2 100644 --- a/tns-core-modules/application/application.ios.ts +++ b/tns-core-modules/application/application.ios.ts @@ -226,10 +226,8 @@ class IOSApplication implements IOSApplicationDefinition { // if we already have a root view, we reset it. this._rootView._onRootViewReset(); } - const rootView = createRootView(view); this._rootView = rootView; - const controller = getViewController(rootView); if (createRootFrame.value) { // Don't setup as styleScopeHost @@ -238,7 +236,7 @@ class IOSApplication implements IOSApplicationDefinition { // setup view as styleScopeHost rootView._setupAsRootView({}); } - + const controller = getViewController(rootView); const haveController = this._window.rootViewController !== null; this._window.rootViewController = controller; if (!haveController) { From dfbc3d191353056c10f05166fd79ac18861be35e Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 11:25:32 +0200 Subject: [PATCH 23/33] refactoring. Better that way? --- .../ui/core/view-base/view-base.ts | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tns-core-modules/ui/core/view-base/view-base.ts b/tns-core-modules/ui/core/view-base/view-base.ts index 2a5de38577..ead06819be 100644 --- a/tns-core-modules/ui/core/view-base/view-base.ts +++ b/tns-core-modules/ui/core/view-base/view-base.ts @@ -687,17 +687,22 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition } this._context = context; - let nativeView; - if (isAndroid) { - // const recycle = this.recycleNativeView; - // if (recycle === "always" || (recycle === "auto" && !this._disableNativeViewRecycling)) { - // nativeView = getNativeView(context, this.typeName); - // } - if (!nativeView) { - nativeView = this.createNativeView(); - } + // This will account for nativeView that is created in createNativeView, recycled + // or for backward compatability - set before _setupUI in iOS contructor. + let nativeView = this.nativeViewProtected; + // if (isAndroid) { + // const recycle = this.recycleNativeView; + // if (recycle === "always" || (recycle === "auto" && !this._disableNativeViewRecycling)) { + // nativeView = getNativeView(context, this.typeName); + // } + // } + if (!nativeView) { + nativeView = this.createNativeView(); + } + + if (isAndroid) { this._androidView = nativeView; if (nativeView) { if (this._isPaddingRelative === undefined) { @@ -730,13 +735,9 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition } } } else { - // TODO: Implement _createNativeView for iOS - nativeView = this.createNativeView() || this.nativeViewProtected; this._iosView = nativeView; } - // This will account for nativeView that is created in createNativeView, recycled - // or for backward compatability - set before _setupUI in iOS contructor. this.setNativeView(nativeView); if (this.parent) { From aef4b3099eb8c5b9d491b8203874c199dc87864c Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 11:25:51 +0200 Subject: [PATCH 24/33] isLayoutValid for iOS now that we use createNativeView --- tns-core-modules/ui/core/view/view-common.ts | 2 +- tns-core-modules/ui/core/view/view.ios.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tns-core-modules/ui/core/view/view-common.ts b/tns-core-modules/ui/core/view/view-common.ts index 0f9cb7c426..ea72eda5b3 100644 --- a/tns-core-modules/ui/core/view/view-common.ts +++ b/tns-core-modules/ui/core/view/view-common.ts @@ -74,7 +74,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { private _measuredWidth: number; private _measuredHeight: number; - private _isLayoutValid: boolean; + protected _isLayoutValid: boolean; private _cssType: string; private _localAnimations: Set; diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index 48dfccd8be..547bed25a9 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -169,6 +169,14 @@ export class View extends ViewCommon { } } + get isLayoutValid(): boolean { + if (this.nativeViewProtected) { + return this._isLayoutValid; + } + + return false; + } + public layoutNativeView(left: number, top: number, right: number, bottom: number): void { if (!this.nativeViewProtected) { return; From 439e8253bf805f25ff556275662e544d78aabf24 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 11:25:59 +0200 Subject: [PATCH 25/33] better that way --- tns-core-modules/ui/frame/frame.ios.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tns-core-modules/ui/frame/frame.ios.ts b/tns-core-modules/ui/frame/frame.ios.ts index 6ace89148c..9a42232649 100644 --- a/tns-core-modules/ui/frame/frame.ios.ts +++ b/tns-core-modules/ui/frame/frame.ios.ts @@ -30,7 +30,11 @@ export class Frame extends FrameBase { super(); this._ios = new iOSFrame(this); this.viewController = this._ios.controller; - this.nativeViewProtected = this._ios.controller.view; + this.nativeViewProtected = this.viewController.view; + } + + createNativeView() { + return this.viewController.view; } public get ios(): iOSFrame { From 81dded987d00fe2074b68402c7f92fea31fc7225 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Wed, 12 Sep 2018 11:26:07 +0200 Subject: [PATCH 26/33] updateScrollBarVisibility fix --- tns-core-modules/ui/scroll-view/scroll-view.ios.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index ab236582d6..75a3f5920a 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -40,7 +40,13 @@ export class ScrollView extends ScrollViewBase { private _delegate: UIScrollViewDelegateImpl; public createNativeView() { - return UIScrollView.new(); + const view = UIScrollView.new(); + if (this.orientation === "horizontal") { + view.showsHorizontalScrollIndicator = this.scrollBarIndicatorVisible; + } else { + view.showsVerticalScrollIndicator = this.scrollBarIndicatorVisible; + } + return view; } initNativeView() { @@ -63,6 +69,9 @@ export class ScrollView extends ScrollViewBase { } protected updateScrollBarVisibility(value) { + if (!this.nativeViewProtected) { + return; + } if (this.orientation === "horizontal") { this.nativeViewProtected.showsHorizontalScrollIndicator = value; } else { From 9dfafffb1560af69761cb7350190af1292fbcb49 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Thu, 20 Sep 2018 17:29:58 +0200 Subject: [PATCH 27/33] better to call this in initNativeView --- tns-core-modules/ui/scroll-view/scroll-view.ios.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index 75a3f5920a..45dd484416 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -41,16 +41,16 @@ export class ScrollView extends ScrollViewBase { public createNativeView() { const view = UIScrollView.new(); - if (this.orientation === "horizontal") { - view.showsHorizontalScrollIndicator = this.scrollBarIndicatorVisible; - } else { - view.showsVerticalScrollIndicator = this.scrollBarIndicatorVisible; - } return view; } initNativeView() { super.initNativeView(); + if (this.orientation === "horizontal") { + view.showsHorizontalScrollIndicator = this.scrollBarIndicatorVisible; + } else { + view.showsVerticalScrollIndicator = this.scrollBarIndicatorVisible; + } this._setNativeClipToBounds(); } @@ -208,4 +208,4 @@ function getTabBarHeight(scrollView: ScrollView): number { return 0; } -ScrollView.prototype.recycleNativeView = "auto"; \ No newline at end of file +ScrollView.prototype.recycleNativeView = "auto"; From 90488790c7b583033382ce1791fc355aa6ad264d Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Thu, 20 Sep 2018 17:47:05 +0200 Subject: [PATCH 28/33] oops! --- tns-core-modules/ui/scroll-view/scroll-view.ios.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index 45dd484416..783f556b29 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -47,9 +47,9 @@ export class ScrollView extends ScrollViewBase { initNativeView() { super.initNativeView(); if (this.orientation === "horizontal") { - view.showsHorizontalScrollIndicator = this.scrollBarIndicatorVisible; + this.nativeViewProtected.showsHorizontalScrollIndicator = this.scrollBarIndicatorVisible; } else { - view.showsVerticalScrollIndicator = this.scrollBarIndicatorVisible; + this.nativeViewProtected.showsVerticalScrollIndicator = this.scrollBarIndicatorVisible; } this._setNativeClipToBounds(); } From ce76f94a068eb16abc84489cd69c4d2933e2ab5d Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Fri, 21 Sep 2018 09:16:27 +0200 Subject: [PATCH 29/33] refactoring --- tns-core-modules/ui/scroll-view/scroll-view.ios.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index 783f556b29..737b0ecc3f 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -46,11 +46,7 @@ export class ScrollView extends ScrollViewBase { initNativeView() { super.initNativeView(); - if (this.orientation === "horizontal") { - this.nativeViewProtected.showsHorizontalScrollIndicator = this.scrollBarIndicatorVisible; - } else { - this.nativeViewProtected.showsVerticalScrollIndicator = this.scrollBarIndicatorVisible; - } + this.updateScrollBarVisibility(this.scrollBarIndicatorVisible); this._setNativeClipToBounds(); } From e5494853a84e6dd57d17262b3dbddf1ad172fb3a Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Fri, 21 Sep 2018 09:21:46 +0200 Subject: [PATCH 30/33] not needed as we have ```createNativeView``` --- tns-core-modules/ui/frame/frame.ios.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tns-core-modules/ui/frame/frame.ios.ts b/tns-core-modules/ui/frame/frame.ios.ts index 9a42232649..7e5d6ab7ca 100644 --- a/tns-core-modules/ui/frame/frame.ios.ts +++ b/tns-core-modules/ui/frame/frame.ios.ts @@ -30,7 +30,6 @@ export class Frame extends FrameBase { super(); this._ios = new iOSFrame(this); this.viewController = this._ios.controller; - this.nativeViewProtected = this.viewController.view; } createNativeView() { From b8113d8ac18c5b46d4a4250507eda442103585fa Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Tue, 25 Sep 2018 11:36:54 +0300 Subject: [PATCH 31/33] refactor: call setupUI on components created with constructor --- tns-core-modules/ui/dialogs/dialogs-common.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tns-core-modules/ui/dialogs/dialogs-common.ts b/tns-core-modules/ui/dialogs/dialogs-common.ts index 5c14ca9ad3..7cbeb7770b 100644 --- a/tns-core-modules/ui/dialogs/dialogs-common.ts +++ b/tns-core-modules/ui/dialogs/dialogs-common.ts @@ -67,6 +67,7 @@ export function getButtonColors(): { color: Color, backgroundColor: Color } { if (!button) { const Button = require("ui/button").Button; button = new Button; + button._setupUI({}); } let buttonColor: Color; @@ -82,6 +83,7 @@ export function getLabelColor(): Color { if (!label) { const Label = require("ui/label").Label; label = new Label; + label._setupUI({}); } let labelColor: Color; @@ -95,6 +97,7 @@ export function getTextFieldColor(): Color { if (!textField) { const TextField = require("ui/text-field").TextField; textField = new TextField(); + textField._setupUI({}); } let textFieldColor: Color; From af042abe416a85b73e6251e6214ec2cdea4f5490 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Tue, 25 Sep 2018 17:56:54 +0300 Subject: [PATCH 32/33] call setupUI on dialog components for iOS only --- tns-core-modules/ui/dialogs/dialogs-common.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tns-core-modules/ui/dialogs/dialogs-common.ts b/tns-core-modules/ui/dialogs/dialogs-common.ts index 7cbeb7770b..bade766b58 100644 --- a/tns-core-modules/ui/dialogs/dialogs-common.ts +++ b/tns-core-modules/ui/dialogs/dialogs-common.ts @@ -2,6 +2,7 @@ import { View } from "../core/view"; import { Color } from "../../color"; import { Page } from "../page"; +import { isIOS } from "../../platform"; import * as frameModule from "../frame"; export const STRING = "string"; @@ -67,7 +68,9 @@ export function getButtonColors(): { color: Color, backgroundColor: Color } { if (!button) { const Button = require("ui/button").Button; button = new Button; - button._setupUI({}); + if (isIOS) { + button._setupUI({}); + } } let buttonColor: Color; @@ -83,7 +86,9 @@ export function getLabelColor(): Color { if (!label) { const Label = require("ui/label").Label; label = new Label; - label._setupUI({}); + if (isIOS) { + label._setupUI({}); + } } let labelColor: Color; @@ -97,7 +102,9 @@ export function getTextFieldColor(): Color { if (!textField) { const TextField = require("ui/text-field").TextField; textField = new TextField(); - textField._setupUI({}); + if (isIOS) { + textField._setupUI({}); + } } let textFieldColor: Color; From 8d39e65479866f1cadf7c2b2b701407195f3fbfe Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Wed, 26 Sep 2018 11:26:09 +0300 Subject: [PATCH 33/33] move setupAsRootView before the modal is shown --- tns-core-modules/ui/core/view/view.ios.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index 5f5b845c1e..2da497b4af 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -331,6 +331,8 @@ export class View extends ViewCommon { return; } + this._setupAsRootView({}); + super._showNativeModalView(parentWithController, context, closeCallback, fullscreen, stretched); let controller = this.viewController; if (!controller) { @@ -344,8 +346,6 @@ export class View extends ViewCommon { this.viewController = controller; } - this._setupAsRootView({}); - if (fullscreen) { controller.modalPresentationStyle = UIModalPresentationStyle.FullScreen; } else {