diff --git a/tests/app/ui/view/view-tests-common.ts b/tests/app/ui/view/view-tests-common.ts index 5ab435ebf..b521f4325 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() { diff --git a/tns-core-modules/application/application.ios.ts b/tns-core-modules/application/application.ios.ts index 87a852358..9308aafce 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) { 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 036d739ad..c8e435c12 100644 --- a/tns-core-modules/ui/action-bar/action-bar.android.ts +++ b/tns-core-modules/ui/action-bar/action-bar.android.ts @@ -131,17 +131,16 @@ 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); + (nativeView).menuItemClickListener = menuItemClickListener; } public 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 97773f531..ba4417297 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 091cdbd11..ef9e8bbcc 100644 --- a/tns-core-modules/ui/button/button.android.ts +++ b/tns-core-modules/ui/button/button.android.ts @@ -37,34 +37,42 @@ 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() { - initializeClickListener(); - const button = new AndroidButton(this._context); - const clickListener = new ClickListener(this); - button.setOnClickListener(clickListener); - (button).clickListener = clickListener; - return button; + if (!AndroidButton) { + AndroidButton = android.widget.Button; + } + return new AndroidButton(this._context); } 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() { - (this.nativeViewProtected).clickListener.owner = null; + if (this.nativeViewProtected) { + (this.nativeViewProtected).clickListener.owner = null; + } super.disposeNativeView(); } diff --git a/tns-core-modules/ui/button/button.ios.ts b/tns-core-modules/ui/button/button.ios.ts index f66a7b84c..a994e8180 100644 --- a/tns-core-modules/ui/button/button.ios.ts +++ b/tns-core-modules/ui/button/button.ios.ts @@ -14,12 +14,20 @@ export class Button extends ButtonBase { private _tapHandler: NSObject; private _stateChangedHandler: ControlStateChangeListener; - constructor() { - super(); - this.nativeViewProtected = UIButton.buttonWithType(UIButtonType.System); + createNativeView() { + return UIButton.buttonWithType(UIButtonType.System); + } + public initNativeView(): void { + super.initNativeView(); + const nativeView = this.nativeViewProtected; this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this)); - this.nativeViewProtected.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.ts b/tns-core-modules/ui/core/view-base/view-base.ts index 6fe0a1bc8..a09464c4a 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; + + // 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) { - // const recycle = this.recycleNativeView; - // if (recycle === "always" || (recycle === "auto" && !this._disableNativeViewRecycling)) { - // nativeView = getNativeView(context, this.typeName); - // } - - if (!nativeView) { - nativeView = this.createNativeView(); - } - this._androidView = nativeView; if (nativeView) { if (this._isPaddingRelative === undefined) { @@ -730,14 +735,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition } } } else { - // TODO: Implement _createNativeView for iOS - nativeView = this.createNativeView(); - this._iosView = nativeView || 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 || this.nativeViewProtected); + this.setNativeView(nativeView); if (this.parent) { const nativeIndex = this.parent._childIndexToNativeChildIndex(atIndex); diff --git a/tns-core-modules/ui/core/view/view-common.ts b/tns-core-modules/ui/core/view/view-common.ts index 952944cf0..45727dea4 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 097a2cfe2..17ec8014b 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -186,6 +186,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; @@ -368,6 +376,8 @@ export class View extends ViewCommon { return; } + this._setupAsRootView({}); + super._showNativeModalView(parentWithController, context, closeCallback, fullscreen, stretched); let controller = this.viewController; if (!controller) { @@ -381,8 +391,6 @@ export class View extends ViewCommon { this.viewController = controller; } - this._setupAsRootView({}); - if (fullscreen) { controller.modalPresentationStyle = UIModalPresentationStyle.FullScreen; } else { @@ -608,9 +616,8 @@ export class CustomLayoutView extends ContainerView { 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 f52954a86..a4fdc54b4 100644 --- a/tns-core-modules/ui/date-picker/date-picker.android.ts +++ b/tns-core-modules/ui/date-picker/date-picker.android.ts @@ -54,19 +54,18 @@ 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() { 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 64a0049c3..3d2533ef0 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/dialogs/dialogs-common.ts b/tns-core-modules/ui/dialogs/dialogs-common.ts index 5c14ca9ad..bade766b5 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,6 +68,9 @@ export function getButtonColors(): { color: Color, backgroundColor: Color } { if (!button) { const Button = require("ui/button").Button; button = new Button; + if (isIOS) { + button._setupUI({}); + } } let buttonColor: Color; @@ -82,6 +86,9 @@ export function getLabelColor(): Color { if (!label) { const Label = require("ui/label").Label; label = new Label; + if (isIOS) { + label._setupUI({}); + } } let labelColor: Color; @@ -95,6 +102,9 @@ export function getTextFieldColor(): Color { if (!textField) { const TextField = require("ui/text-field").TextField; textField = new TextField(); + if (isIOS) { + textField._setupUI({}); + } } let textFieldColor: Color; 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 cc7ecad6b..31d898372 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,34 +156,31 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public createNativeView() { - initializeEditTextListeners(); - const editText = new android.widget.EditText(this._context); - this._configureEditText(editText); + return new android.widget.EditText(this._context); + } + 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(); + this._inputType = editText.getInputType(); } public disposeNativeView(): void { - super.disposeNativeView(); - (this.nativeViewProtected).listener.owner = null; + (this.nativeTextViewProtected).listener.owner = null; this._keyListenerCache = null; + super.disposeNativeView(); } public resetNativeView(): void { super.resetNativeView(); - this.nativeViewProtected.setInputType(this._inputType); + this.nativeTextViewProtected.setInputType(this._inputType); } public onUnloaded() { @@ -192,7 +189,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public dismissSoftInput() { - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; if (!nativeView) { return; } @@ -201,21 +198,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 +245,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 +279,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 +328,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 +344,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 +356,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 +387,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 +395,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 +416,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 +437,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 +452,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 1cd401f93..189e796aa 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/frame/frame.ios.ts b/tns-core-modules/ui/frame/frame.ios.ts index 6ace89148..7e5d6ab7c 100644 --- a/tns-core-modules/ui/frame/frame.ios.ts +++ b/tns-core-modules/ui/frame/frame.ios.ts @@ -30,7 +30,10 @@ export class Frame extends FrameBase { super(); this._ios = new iOSFrame(this); this.viewController = this._ios.controller; - this.nativeViewProtected = this._ios.controller.view; + } + + createNativeView() { + return this.viewController.view; } public get ios(): iOSFrame { 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 d46087701..1be43ea75 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 0b28d34d8..1ce6f6797 100644 --- a/tns-core-modules/ui/image/image.android.ts +++ b/tns-core-modules/ui/image/image.android.ts @@ -49,19 +49,17 @@ 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() { diff --git a/tns-core-modules/ui/image/image.ios.ts b/tns-core-modules/ui/image/image.ios.ts index 19839148f..31c111921 100644 --- a/tns-core-modules/ui/image/image.ios.ts +++ b/tns-core-modules/ui/image/image.ios.ts @@ -10,14 +10,15 @@ 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; + return imageView; + } + + public initNativeView(): void { + super.initNativeView(); this._setNativeClipToBounds(); } diff --git a/tns-core-modules/ui/label/label.android.ts b/tns-core-modules/ui/label/label.android.ts index 96fca113d..4052bb125 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 555e29a8b..382b9444f 100644 --- a/tns-core-modules/ui/label/label.ios.ts +++ b/tns-core-modules/ui/label/label.ios.ts @@ -23,21 +23,20 @@ export class Label extends TextBase implements LabelDefinition { nativeViewProtected: TNSLabel; private _fixedSize: FixedSize; - 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.nativeViewProtected; + return this.nativeTextViewProtected; } get textWrap(): boolean { return this.style.whiteSpace === "normal"; } - set textWrap(value: boolean) { + set textWrap(value: boolean) { if (typeof value === "string") { value = booleanConverter(value) } @@ -57,7 +56,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); @@ -104,7 +103,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( @@ -120,7 +119,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; @@ -138,7 +137,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); } @@ -146,7 +145,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), @@ -157,7 +156,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, @@ -168,7 +167,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, @@ -179,7 +178,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, @@ -190,7 +189,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), @@ -201,7 +200,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, @@ -212,7 +211,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, @@ -223,7 +222,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/list-picker/list-picker.android.ts b/tns-core-modules/ui/list-picker/list-picker.android.ts index faed19a5d..da96caeb9 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([]); 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 77d65800a..935b2d084 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 46023cf5a..2898272ef 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(); } 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 6858d3d6d..896e076fd 100644 --- a/tns-core-modules/ui/list-view/list-view.ios.ts +++ b/tns-core-modules/ui/list-view/list-view.ios.ts @@ -208,7 +208,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; @@ -219,20 +219,34 @@ export class ListView extends ListViewBase { 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)); - this._delegate = UITableViewDelegateImpl.initWithOwner(new WeakRef(this)); - this._heights = new Array(); this._map = new Map(); + this._heights = new Array(); + } + + 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._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 @@ -241,16 +255,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 { @@ -272,7 +286,7 @@ export class ListView extends ListViewBase { } private _scrollToIndex(index: number, animated: boolean = true) { - if (!this._ios) { + if (!this.ios) { return; } @@ -285,7 +299,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); @@ -301,7 +315,7 @@ export class ListView extends ListViewBase { }); if (this.isLoaded) { - this._ios.reloadData(); + this.ios.reloadData(); this.requestLayout(); this._isDataDirty = false; } else { @@ -310,7 +324,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); } @@ -324,7 +338,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; @@ -355,7 +369,7 @@ export class ListView extends ListViewBase { var changed = this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec); super.measure(widthMeasureSpec, heightMeasureSpec); if (changed) { - this._ios.reloadData(); + this.ios.reloadData(); } } @@ -390,7 +404,7 @@ export class ListView extends ListViewBase { return height; } - return this._ios.estimatedRowHeight; + return this.ios.estimatedRowHeight; } public _prepareCell(cell: ListViewCell, indexPath: NSIndexPath): number { @@ -427,9 +441,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); @@ -456,10 +470,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[] { @@ -469,7 +483,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); } @@ -481,7 +495,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/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index c5c380eea..d17c66514 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 { diff --git a/tns-core-modules/ui/progress/progress.ios.ts b/tns-core-modules/ui/progress/progress.ios.ts index e5c0f4d6f..680152090 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 85a5553a6..f2f33e0e7 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 c56a72e24..717e5851f 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,15 @@ export class ScrollView extends ScrollViewBase { private _contentMeasuredWidth: number = 0; private _contentMeasuredHeight: number = 0; private _delegate: UIScrollViewDelegateImpl; + + public createNativeView() { + const view = UIScrollView.new(); + return view; + } - constructor() { - super(); - this.nativeViewProtected = UIScrollView.new(); + initNativeView() { + super.initNativeView(); + this.updateScrollBarVisibility(this.scrollBarIndicatorVisible); this._setNativeClipToBounds(); } @@ -60,6 +65,9 @@ export class ScrollView extends ScrollViewBase { } protected updateScrollBarVisibility(value) { + if (!this.nativeViewProtected) { + return; + } if (this.orientation === "horizontal") { this.nativeViewProtected.showsHorizontalScrollIndicator = value; } else { @@ -68,15 +76,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; } @@ -84,7 +92,7 @@ export class ScrollView extends ScrollViewBase { } get scrollableHeight(): number { - if (this.orientation !== "vertical") { + if (!this.nativeViewProtected || this.orientation !== "vertical") { return 0; } @@ -99,14 +107,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); } @@ -192,4 +200,4 @@ function getTabBarHeight(scrollView: ScrollView): number { return 0; } -ScrollView.prototype.recycleNativeView = "auto"; \ No newline at end of file +ScrollView.prototype.recycleNativeView = "auto"; 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 01d2764fe..cb95c547c 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,15 +111,6 @@ 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() { 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 d7d2f7350..2b85cb710 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 bef19e7b6..5e52b6238 100644 --- a/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts +++ b/tns-core-modules/ui/segmented-bar/segmented-bar.android.ts @@ -213,18 +213,16 @@ 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); } 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 c7a7ec16a..aa7e87c75 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 4a4edbb34..66222ed7b 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 { @@ -28,7 +25,7 @@ function initializeModule(): 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); } @@ -56,16 +53,19 @@ 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; + nativeView.owner = this; + initializeListenerClass(); + const listener = getListener(); + nativeView.setOnSeekBarChangeListener(listener); } public disposeNativeView() { @@ -140,4 +140,4 @@ export class Slider extends SliderBase { [backgroundInternalProperty.setNative](value: Background) { // } -} \ No newline at end of file +} diff --git a/tns-core-modules/ui/slider/slider.ios.ts b/tns-core-modules/ui/slider/slider.ios.ts index b738af4a9..5a4845b7e 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 03f529b4f..0a3e26e36 100644 --- a/tns-core-modules/ui/switch/switch.android.ts +++ b/tns-core-modules/ui/switch/switch.android.ts @@ -36,18 +36,16 @@ 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() { diff --git a/tns-core-modules/ui/switch/switch.ios.ts b/tns-core-modules/ui/switch/switch.ios.ts index 957ba9d70..8acb70797 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 92a12d043..fd936231d 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-common.ts b/tns-core-modules/ui/text-base/text-base-common.ts index ee7482beb..4826bd095 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 07a8d8a07..61131348e 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; @@ -57,19 +58,19 @@ export class TextBase extends TextBaseCommon { private _maxLines: number; public initNativeView(): void { + super.initNativeView(); initializeTextTransformation(); - const nativeView = this.nativeViewProtected; + const nativeView = this.nativeTextViewProtected; this._defaultTransformationMethod = nativeView.getTransformationMethod(); this._minHeight = nativeView.getMinHeight(); this._maxHeight = nativeView.getMaxHeight(); this._minLines = nativeView.getMinLines(); this._maxLines = nativeView.getMaxLines(); - super.initNativeView(); } 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 002e078dd..3918cf213 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,13 @@ export * from "../core/view"; 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-base/text-base.ios.ts b/tns-core-modules/ui/text-base/text-base.ios.ts index 5e109800a..49d14afb1 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 59a02d888..c26cf960c 100644 --- a/tns-core-modules/ui/text-field/text-field.ios.ts +++ b/tns-core-modules/ui/text-field/text-field.ios.ts @@ -141,61 +141,66 @@ class UITextFieldImpl extends UITextField { } export class TextField extends TextFieldBase { - private _ios: UITextField; - private _delegate: UITextFieldDelegateImpl; nativeViewProtected: UITextField; + private _delegate: UITextFieldDelegateImpl; - constructor() { - super(); - let weakRef = new WeakRef(this); - this._ios = UITextFieldImpl.initWithOwner(weakRef); - this._delegate = UITextFieldDelegateImpl.initWithOwner(weakRef); - this.nativeViewProtected = this._ios; + createNativeView() { + return UITextFieldImpl.initWithOwner(new WeakRef(this)); + } + + 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 { - 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 +228,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 dafc30802..8c316d619 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 9486945ce..31dcb4176 100644 --- a/tns-core-modules/ui/text-view/text-view.ios.ts +++ b/tns-core-modules/ui/text-view/text-view.ios.ts @@ -97,34 +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; - constructor() { - super(); - - const textView = this.nativeViewProtected = this._ios = UITextView.new(); + createNativeView() { + const textView = UITextView.new(); if (!textView.font) { textView.font = UIFont.systemFontOfSize(12); } + return textView; + } + + 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) { @@ -138,7 +146,7 @@ export class TextView extends EditableTextBase implements TextViewDefinition { this.showHint(hint); } else { this._isShowingHint = false; - this.nativeViewProtected.text = ""; + this.nativeTextViewProtected.text = ""; } } @@ -148,28 +156,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 +208,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 +223,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 }; } } 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 fb5828897..7a86a992a 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 cf60936a8..25688987f 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(); - - this._ios = UIDatePicker.new(); - this._ios.datePickerMode = UIDatePickerMode.Time; - - this._changeHandler = UITimePickerChangeHandlerImpl.initWithOwner(new WeakRef(this)); - this._ios.addTargetActionForControlEvents(this._changeHandler, "valueChanged", UIControlEvents.ValueChanged); - let components = getComponents(NSDate.date()); this.hour = components.hour; this.minute = components.minute; - this.nativeViewProtected = this._ios; + } + + createNativeView() { + const picker = UIDatePicker.new(); + picker.datePickerMode = UIDatePickerMode.Time; + return picker; + } + + initNativeView() { + super.initNativeView(); + this._changeHandler = UITimePickerChangeHandlerImpl.initWithOwner(new WeakRef(this)); + this.nativeViewProtected.addTargetActionForControlEvents(this._changeHandler, "valueChanged", UIControlEvents.ValueChanged); + } + + 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 2a6e6d885..e059ee998 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() { 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 403871ef6..67425f475 100644 --- a/tns-core-modules/ui/web-view/web-view.ios.ts +++ b/tns-core-modules/ui/web-view/web-view.ios.ts @@ -80,76 +80,84 @@ class WKNavigationDelegateImpl extends NSObject } export class WebView extends WebViewBase { - private _ios: WKWebView; + nativeViewProtected: 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(); - 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