refactor(core-modules): implement createNativeView and initNativeView for all components

refactor(core-modules): implement createNativeView and initNativeView for all components
This commit is contained in:
Martin Guillon
2018-09-26 12:59:12 +02:00
committed by Martin Yankov
parent 71107533bb
commit 46705ee332
48 changed files with 632 additions and 521 deletions

View File

@ -345,19 +345,8 @@ class TestView extends LayoutBase {
(<any>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() {

View File

@ -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) {

View File

@ -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);
(<any>toolbar).menuItemClickListener = menuItemClickListener;
return toolbar;
return new android.support.v7.widget.Toolbar(this._context);
}
public initNativeView(): void {
super.initNativeView();
(<any>this.nativeViewProtected).menuItemClickListener.owner = this;
const nativeView = this.nativeViewProtected;
initializeMenuItemClickListener();
const menuItemClickListener = new MenuItemClickListener(this);
nativeView.setOnMenuItemClickListener(menuItemClickListener);
(<any>nativeView).menuItemClickListener = menuItemClickListener;
}
public disposeNativeView() {

View File

@ -5,10 +5,10 @@ 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 {

View File

@ -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);
(<any>button).clickListener = clickListener;
return button;
if (!AndroidButton) {
AndroidButton = android.widget.Button;
}
return new AndroidButton(this._context);
}
public initNativeView(): void {
const nativeView = this.nativeViewProtected;
(<any>nativeView).clickListener.owner = this;
super.initNativeView();
const nativeView = this.nativeViewProtected;
initializeClickListener();
const clickListener = new ClickListener(this);
nativeView.setOnClickListener(clickListener);
(<any>nativeView).clickListener = clickListener;
}
public disposeNativeView() {
if (this.nativeViewProtected) {
(<any>this.nativeViewProtected).clickListener.owner = null;
}
super.disposeNativeView();
}

View File

@ -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() {

View File

@ -687,17 +687,22 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
}
this._context = context;
let nativeView;
if (isAndroid) {
// 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 = <android.view.View>getNativeView(context, this.typeName);
// }
// }
if (!nativeView) {
nativeView = this.createNativeView();
}
if (isAndroid) {
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);

View File

@ -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<am.Animation>;

View File

@ -169,6 +169,14 @@ export class View extends ViewCommon {
}
}
get isLayoutValid(): boolean {
if (this.nativeViewProtected) {
return this._isLayoutValid;
}
return false;
}
public layoutNativeView(left: number, top: number, right: number, bottom: number): void {
if (!this.nativeViewProtected) {
return;
@ -323,6 +331,8 @@ export class View extends ViewCommon {
return;
}
this._setupAsRootView({});
super._showNativeModalView(parentWithController, context, closeCallback, fullscreen, stretched);
let controller = this.viewController;
if (!controller) {
@ -336,8 +346,6 @@ export class View extends ViewCommon {
this.viewController = controller;
}
this._setupAsRootView({});
if (fullscreen) {
controller.modalPresentationStyle = UIModalPresentationStyle.FullScreen;
} else {
@ -536,9 +544,8 @@ export class CustomLayoutView extends View {
nativeViewProtected: UIView;
constructor() {
super();
this.nativeViewProtected = UIView.alloc().initWithFrame(iosUtils.getter(UIScreen, UIScreen.mainScreen).bounds);
createNativeView() {
return UIView.alloc().initWithFrame(iosUtils.getter(UIScreen, UIScreen.mainScreen).bounds);
}
get ios(): UIView {

View File

@ -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);
(<any>picker).listener = listener;
return picker;
}
public initNativeView(): void {
super.initNativeView();
(<any>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);
(<any>nativeView).listener = listener;
}
public disposeNativeView() {

View File

@ -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 {

View File

@ -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;

View File

@ -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);
(<any>editText).listener = listeners;
return editText;
}
public initNativeView(): void {
super.initNativeView();
const nativeView = this.nativeViewProtected;
(<any>nativeView).listener.owner = this;
this._inputType = nativeView.getInputType();
this._inputType = editText.getInputType();
}
public disposeNativeView(): void {
super.disposeNativeView();
(<any>this.nativeViewProtected).listener.owner = null;
(<any>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(<any>color);
this.nativeTextViewProtected.setHintTextColor(<any>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);
}
}
}

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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);
(<any>imageView).listener = listener;
return imageView;
return new AndroidImageView(this._context);
}
public initNativeView(): void {
super.initNativeView();
(<any>this.nativeViewProtected).listener.owner = this;
initializeImageLoadedListener();
const nativeView = this.nativeViewProtected;
const listener = new ImageLoadedListener(this);
nativeView.setImageLoadedListener(listener);
(<any>nativeView).listener = listener;
}
public disposeNativeView() {

View File

@ -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();
}

View File

@ -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);
}

View File

@ -23,15 +23,14 @@ 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 {
@ -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 = <UILabel>this.nativeViewProtected;
const view = <UILabel>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,

View File

@ -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);
(<any>picker).formatter = formatter;
const valueChangedListener = new ValueChangeListener(this);
picker.setOnValueChangedListener(valueChangedListener);
(<any>picker).valueChangedListener = valueChangedListener;
const editText = getEditText(picker);
if (editText) {
(<any>picker).editText = editText;
}
picker.setWrapSelectorWheel(false);
return picker;
}
public initNativeView(): void {
super.initNativeView();
initializeNativeClasses();
const nativeView = this.nativeViewProtected;
this._selectorWheelPaint = getSelectorWheelPaint(nativeView);
(<any>nativeView).formatter.owner = this;
(<any>nativeView).valueChangedListener.owner = this;
const editText = (<any>nativeView).editText;
const formatter = new Formatter(this);
nativeView.setFormatter(formatter);
(<any>nativeView).formatter = formatter;
const valueChangedListener = new ValueChangeListener(this);
nativeView.setOnValueChangedListener(valueChangedListener);
(<any>nativeView).valueChangedListener = valueChangedListener;
const editText = getEditText(nativeView);
if (editText) {
(<any>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([]);

View File

@ -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;
constructor() {
super();
createNativeView() {
return UIPickerView.new();
}
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;
}
}

View File

@ -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);
(<any>listView).adapter = adapter;
const itemClickListener = new ItemClickListener(this);
listView.setOnItemClickListener(itemClickListener);
(<any>listView).itemClickListener = itemClickListener;
return listView;
}
@ -75,11 +64,17 @@ export class ListView extends ListViewBase {
super.initNativeView();
this.updateEffectiveRowHeight();
const nativeView: any = this.nativeViewProtected;
(<any>nativeView).itemClickListener.owner = this;
const adapter = (<any>nativeView).adapter;
adapter.owner = this;
const nativeView = this.nativeViewProtected;
initializeItemClickListener();
ensureListViewAdapterClass();
const adapter = new ListViewAdapterClass(this);
nativeView.setAdapter(adapter);
(<any>nativeView).adapter = adapter;
const itemClickListener = new ItemClickListener(this);
nativeView.setOnItemClickListener(itemClickListener);
(<any>nativeView).itemClickListener = itemClickListener;
if (this._androidViewId < 0) {
this._androidViewId = android.view.View.generateViewId();
}

View File

@ -206,7 +206,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<number>;
@ -217,20 +217,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<number>();
this._map = new Map<ListViewCell, ItemView>();
this._heights = new Array<number>();
}
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
@ -239,16 +253,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 {
@ -270,7 +284,7 @@ export class ListView extends ListViewBase {
}
private _scrollToIndex(index: number, animated: boolean = true) {
if (!this._ios) {
if (!this.ios) {
return;
}
@ -283,7 +297,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);
@ -299,7 +313,7 @@ export class ListView extends ListViewBase {
});
if (this.isLoaded) {
this._ios.reloadData();
this.ios.reloadData();
this.requestLayout();
this._isDataDirty = false;
} else {
@ -308,7 +322,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);
}
@ -322,7 +336,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;
@ -353,7 +367,7 @@ export class ListView extends ListViewBase {
var changed = this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec);
super.measure(widthMeasureSpec, heightMeasureSpec);
if (changed) {
this._ios.reloadData();
this.ios.reloadData();
}
}
@ -388,7 +402,7 @@ export class ListView extends ListViewBase {
return height;
}
return this._ios.estimatedRowHeight;
return this.ios.estimatedRowHeight;
}
public _prepareCell(cell: ListViewCell, indexPath: NSIndexPath): number {
@ -425,9 +439,9 @@ export class ListView extends ListViewBase {
this._map.set(cell, view);
// We expect that views returned from itemLoading are new (e.g. not reused).
if (view && !view.parent && view.nativeViewProtected) {
cell.contentView.addSubview(view.nativeViewProtected);
if (view && !view.parent) {
this._addView(view);
cell.contentView.addSubview(view.nativeViewProtected);
}
cellHeight = this._layoutCell(view, indexPath);
@ -454,10 +468,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[] {
@ -467,7 +481,7 @@ export class ListView extends ListViewBase {
this._itemTemplatesInternal = new Array<KeyedTemplate>(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);
}
@ -479,7 +493,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;
}

View File

@ -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 {

View File

@ -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 {

View File

@ -86,6 +86,7 @@ export class ScrollView extends ScrollViewBase {
}
public initNativeView(): void {
super.initNativeView();
if (this._androidViewId < 0) {
this._androidViewId = android.view.View.generateViewId();
}

View File

@ -39,9 +39,14 @@ export class ScrollView extends ScrollViewBase {
private _contentMeasuredHeight: number = 0;
private _delegate: UIScrollViewDelegateImpl;
constructor() {
super();
this.nativeViewProtected = UIScrollView.new();
public createNativeView() {
const view = UIScrollView.new();
return view;
}
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);
}

View File

@ -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);
(<any>nativeView).queryTextListener = queryTextListener;
@ -106,15 +111,6 @@ export class SearchBar extends SearchBarBase {
const closeListener = new CloseListener(this);
nativeView.setOnCloseListener(closeListener);
(<any>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() {

View File

@ -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 {

View File

@ -213,18 +213,16 @@ export class SegmentedBar extends SegmentedBarBase {
tabHostLayout.addView(frame);
nativeView.addView(tabHostLayout);
const listener = new TabChangeListener(this);
nativeView.setOnTabChangedListener(listener);
(<any>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);
(<any>nativeView).listener = listener;
nativeView.setup();
this._tabContentFactory = this._tabContentFactory || new TabContentFactory(this);
}

View File

@ -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);

View File

@ -13,10 +13,7 @@ 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])
@ -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() {

View File

@ -31,58 +31,65 @@ class SliderChangeHandlerImpl extends NSObject {
}
export class Slider extends SliderBase {
private _ios: UISlider;
nativeViewProtected: UISlider;
private _changeHandler: NSObject;
constructor() {
super();
this.nativeViewProtected = this._ios = UISlider.new();
public createNativeView() {
return 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 {

View File

@ -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);
(<any>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);
(<any>nativeView).listener = listener;
}
public disposeNativeView() {

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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(<any>transformedText);
this.nativeTextViewProtected.setText(<any>transformedText);
}
}

View File

@ -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.
*/

View File

@ -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 = <UITextField | UITextView | UILabel>this.nativeViewProtected;
const nativeView = <UITextField | UITextView | UILabel>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 = (<UITextField | UITextView | UILabel>this.nativeViewProtected).textAlignment;
if (this.nativeViewProtected instanceof UILabel) {
paragraphStyle.alignment = (<UITextField | UITextView | UILabel>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 = (<UITextField | UITextView | UILabel>this.nativeViewProtected).textAlignment;
if (this.nativeViewProtected instanceof UILabel) {
paragraphStyle.alignment = (<UITextField | UITextView | UILabel>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(<any>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);

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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 };
}
}

View File

@ -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);
(<any>nativeView).listener = listener;
(<any>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);
(<any>nativeView).listener = listener;
const calendar = (<any>nativeView).calendar = java.util.Calendar.getInstance();
const calendar = (<any>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);

View File

@ -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 {

View File

@ -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);
(<any>nativeView).client = client;
return nativeView;
}
public initNativeView(): void {
super.initNativeView();
(<any>this.nativeViewProtected).client.owner = this;
initializeWebViewClient();
const nativeView = this.nativeViewProtected;
const client = new WebViewClient(this);
nativeView.setWebViewClient(client);
(<any>nativeView).client = client;
}
public disposeNativeView() {

View File

@ -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();
}
}