前言
“一次構(gòu)建忘渔,多處運(yùn)行”高帖,跨平臺APP帶著這股風(fēng)潮把火燒到了前端,為開發(fā)者帶來無盡的遐想∑枇福現(xiàn)有的流行跨平臺框架有以下:
- 基于單WebView的開發(fā)框架散址。開發(fā)者可以使用現(xiàn)有的最新web技術(shù),開發(fā)出單頁面web應(yīng)用宣赔。同時利用JSBridge预麸,又能獲取原生的API,從而使web應(yīng)用具有了原生應(yīng)用的功能儒将。Cordova+IONIC可以說是這個潮流的代表吏祸,也是跨平臺APP的先鋒。然而這類跨平臺應(yīng)用的缺點(diǎn)是不流暢钩蚊,在安卓手機(jī)上體驗(yàn)較差贡翘。
- Hybrid方向。也就是原生應(yīng)用配合HTML5技術(shù)砰逻,讓APP具有了部分跨平臺的功能鸣驱。Hybrid也是現(xiàn)在各大互聯(lián)網(wǎng)企業(yè)采用較多的跨平臺開發(fā)方式。這類APP在體驗(yàn)上優(yōu)于單WebView的APP蝠咆,并且能夠極大提高開發(fā)效率踊东。然而這種方式離“一次構(gòu)建,多處運(yùn)行”的設(shè)想還是有很大距離刚操,畢竟依然需要針對不同的移動平臺進(jìn)行原生開發(fā)递胧。
- 使用Javascript開發(fā)純原生應(yīng)用。既然單WebView性能有缺憾赡茸,Hybrid技術(shù)棧又比較高,那么Javascript開發(fā)純原生應(yīng)用就孕育而生祝闻。這個方向的代表有ReactNative, Weex和我們今天的主角--Nativescript占卧。
和ReactNative相比,Nativescript最大的特點(diǎn)是可以獲得100%的原生API联喘。也就是說华蜒,開發(fā)者可以通過Javascript獲取和原生開發(fā)語言同樣多的原生接口。下面豁遭,我們通過實(shí)現(xiàn)一個簡單的計算器叭喜,來體會一下Nativescript的開發(fā)思想。同時蓖谢,我們能體會到“獲取所有原生API”帶來的巨大好處捂蕴。
你可以先在這里看到最終的結(jié)果譬涡。 注意輸入的數(shù)字的字體會隨著文本長度逐漸變小,想想這個功能怎么實(shí)現(xiàn)啥辨。
Why Nativescript?
大家定會好奇涡匀,ReactNative這么火姨谷,大家都在談?wù)撍藁梗笥幸唤y(tǒng)天下的感覺蛇损,為什么還要討論Nativescript呢柜蜈?這是因?yàn)镽eactNative依然不能真正統(tǒng)一編程語言倦逐。ReactNative基于平臺抽象倘感,不可能暴露100%的原生API牲证,因此需要使用原生編程語言進(jìn)行擴(kuò)展军洼,提高了技術(shù)棧玫荣。所以甚淡,一個ReactNative的開發(fā)團(tuán)隊(duì)里面必須同時具備Javascript,Java還有ObjectiveC開發(fā)技術(shù)崇决。
相比之下材诽,Nativescript的技術(shù)棧則要簡單的多,開發(fā)者只需要使用Javascript就能進(jìn)行開發(fā)恒傻。這里列出了幾個Nativescript的核心功能:
- 使用Javascript直接訪問所有原生API
- 系統(tǒng)新功能0延時支持
- 第三方原生庫全部支持
準(zhǔn)備
首先需要搭建開發(fā)環(huán)境脸侥,請參考官方的文檔。你可以使用下面的命令來檢測Nativescript是否安轉(zhuǎn)完成:
tns doctor
Nativescript支持純Javascript盈厘,同時也支持Angular2睁枕。我們選擇Angular2和Typescript進(jìn)行開發(fā),體會一下Angular2帶來的開發(fā)便利沸手。
創(chuàng)建我們的項(xiàng)目
tns create NSCalculator --ng
這個命令會在當(dāng)前目錄下新建NSCalculator文件夾外遇,同時安裝好所需的第三方依賴。其實(shí)這個命令還給你新建一個Demo契吉,運(yùn)行下面的命令跳仿,你就會看到你的第一個Nativescript應(yīng)用
tns platform add ios
tns run ios --emulator
拆分
使用Visual Studio Code打開文件,有如下的文件夾結(jié)構(gòu)
我們的代碼將會組織在app目錄下捐晶,所以只需考慮這個文件夾菲语。main.ts是整個應(yīng)用的啟動文件,我們現(xiàn)在不需要更改它惑灵。我們看到main.ts里面引入了app.component模塊山上,app.component將會被改造成我們的計算器組件。在改造app.component.ts前英支,我們先考慮一下如何將計算器拆分成一個個組件佩憾。
首先從功能上對計算器進(jìn)行拆分。計算器由Displayer和Keyboard兩個部分,Keyboard由Button組成妄帘±慊疲基于此,我們在app目錄下新增三個文件夾:Displayer寄摆,Keyboard谅辣,NSButton。
布局
組件化開發(fā)有兩種常用方式婶恼,一種是由大到小開發(fā)桑阶,也就是Calculator -> Displayer -> Keyboard -> Button,一種是由小到大開發(fā)勾邦,也就是 Button -> Keyboard -> Displayer -> Calculator蚣录。當(dāng)然你也可以混合開發(fā)。本例采用由大到小的開發(fā)方式眷篇。
刪除app.component.ts里面的內(nèi)容萎河,用以下代替:
// app.component.ts
import {
Component,
} from "@angular/core";
@Component({
selector: "calculator",
template: `
<GridLayout rows="auto,*" columns="*">
<StackLayout row="0" style="font-size:60;color:#fff;height:120;background-color:rgba(0,0,0,0.8);text-align:right;vertical-align:bottom;">
<Label text="99" ></Label>
</StackLayout>
<GridLayout row="1" style="background-color:#fff;text-align:center;">
<Label text="keyboards" ></Label>
</GridLayout>
</GridLayout>
`,
})
export class AppComponent {
public counter: string = '';
}
運(yùn)行以下命令,你就能看到效果
tns livesync ios --emulator --watch
和 tns run ios
命令不同蕉饼,這個命令會監(jiān)視你的文件變化并自動構(gòu)建部署新的應(yīng)用虐杯。
Nativescript的布局方式和安卓原生的布局方式非常類似。對于計算器昧港,我們的Displayer需要一個固定的高度擎椰,Keyboard需要占據(jù)全部剩余的空間。因此创肥,Calculator的第一級布局使用了GridLayout达舒。rows="auto,*" 表示Gridlayout為兩行,第一行高度由內(nèi)容(auto)決定叹侄,第二行高度占據(jù)全部剩余空間(*)巩搏。columns="*"表示Gridlayout分為一列布局,這一列的寬度占據(jù)全部空間趾代。
我們?yōu)镈isplayer選擇了StackLayout布局贯底,這是因?yàn)槲覀冃枰袻abel靠右下角對齊。我們?yōu)镵eyboard選擇了GridLayout布局撒强,這很好理解丈甸,因?yàn)槲覀冃枰粋€5x4的格子用來放置計算器的按鈕。
熟悉ReactNative的同學(xué)可能知道尿褪,ReactNative使用Flex布局,非常便于web開發(fā)者掌握得湘。Nativescript則使用和原生開發(fā)非常相似的布局方式杖玲,然而這種布局方式其實(shí)也很容易掌握。
注意我們還使用了行內(nèi)CSS來裝飾Nativescript的組件淘正。Nativescript支持的CSS屬性是web CSS屬性的一個子集摆马。你可以在這里看到Nativescript支持的CSS種類臼闻,總的來說,有限但是夠用囤采。
組件
目前為止我們的APP只有一個組件AppComponent述呐,這非常不利于項(xiàng)目的擴(kuò)展。幸運(yùn)的是Nativescript支持Angular2.0的全部功能蕉毯,我們可以使用Angular來實(shí)現(xiàn)Displayer和Keyboard組件乓搬。
在app目錄下新建Keyboard文件夾,在Keyboard文件里新增keyboard.component.ts代虾,keyboard.html进肯,以及keyboard.css文件。內(nèi)容如下:
//keyboard.component.ts
import {
Component,
} from '@angular/core';
@Component({
selector:'keyboard',
templateUrl:'Keyboard/keyboard.html',
styleUrls:['Keyboard/keyboard.css']
})
export class Keyboard{
}
<!--keyboard.html-->
<GridLayout row="1" columns="1*,1*,1*,1*"
rows="1*,1*,1*,1*,1*">
<!--第一行-->
<StackLayout row="0" col="0">
<Label class="keyboard-item gray" text="C"></Label>
</StackLayout>
<StackLayout row="0" col="1">
<Label class="keyboard-item gray" text="+/-"></Label>
</StackLayout>
<StackLayout row="0" col="2">
<Label class="keyboard-item gray" text="%"></Label>
</StackLayout>
<StackLayout row="0" col="3">
<Label class="keyboard-item yellow" text="÷"></Label>
</StackLayout>
<!--第二行-->
<StackLayout row="1" col="0">
<Label class="keyboard-item gray" text="7"></Label>
</StackLayout>
<StackLayout row="1" col="1">
<Label class="keyboard-item gray" text="8"></Label>
</StackLayout>
<StackLayout row="1" col="2">
<Label class="keyboard-item gray" text="9"></Label>
</StackLayout>
<StackLayout row="1" col="3">
<Label class="keyboard-item yellow" text="x"></Label>
</StackLayout>
<!--第三行-->
<StackLayout row="2" col="0">
<Label class="keyboard-item gray" text="4"></Label>
</StackLayout>
<StackLayout row="2" col="1">
<Label class="keyboard-item gray" text="5"></Label>
</StackLayout>
<StackLayout row="2" col="2">
<Label class="keyboard-item gray" text="6"></Label>
</StackLayout>
<StackLayout row="2" col="3">
<Label class="keyboard-item yellow" text="-"></Label>
</StackLayout>
<!--第四行-->
<StackLayout row="3" col="0">
<Label class="keyboard-item gray" text="1"></Label>
</StackLayout>
<StackLayout row="3" col="1">
<Label class="keyboard-item gray" text="2"></Label>
</StackLayout>
<StackLayout row="3" col="2">
<Label class="keyboard-item gray" text="3"></Label>
</StackLayout>
<StackLayout row="3" col="3">
<Label class="keyboard-item yellow" text="+"></Label>
</StackLayout>
<!--第五行-->
<StackLayout row="4" col="0" colSpan="2">
<Label class="keyboard-item gray" text="0"></Label>
</StackLayout>
<StackLayout row="4" col="2">
<Label class="keyboard-item gray" text="."></Label>
</StackLayout>
<StackLayout row="4" col="3">
<Label class="keyboard-item yellow" text="="></Label>
</StackLayout>
</GridLayout>
// keyboard.css
.keyboard-item {
border-width: 0.5;
border-color: rgb(123,123,123);
font-family: monospace;
width:100%;
height: 100%;
text-align: center;
}
.gray {
background-color: rgb(205,205,205);
color:rgb(22,22,22);
font-size: 25;
}
.yellow {
background-color:rgb(242,127,38);
color:#fff;
font-size: 30;
}
在Keyboard組件里棉磨,我們把HTML模板和CSS都拆分到了獨(dú)立文件里面江掩,又回到了那個干干凈凈的web世界。而這兩者ReactNative都不能支持乘瓤!所以在組件復(fù)用性和易用性上环形,Nativescript其實(shí)技高一籌。
然而現(xiàn)在應(yīng)用界面并沒有任何變化衙傀,我們還需要在app.component.ts中引入Keyboard組件抬吟。修改后的app.component.ts文件如下
//app.component.ts
import {
Component,
} from "@angular/core";
//引入外部組件
import {
Keyboard
} from './Keyboard/keyboard.component';
@Component({
selector: "calculator",
template: `
<GridLayout rows="auto,*" columns="*">
<!--Dispalyer-->
<StackLayout row="0" style="font-size:60;color:#fff;height:120;background-color:rgba(0,0,0,0.8);text-align:right;vertical-align:bottom;">
<Label text="99" ></Label>
</StackLayout>
<!--引入Keyboard組件-->
<keyboard row="1"></keyboard>
</GridLayout>
`,
directives:[Keyboard] //聲明對Keyboard組件的依賴
})
export class AppComponent {
public counter: string = '';
}
現(xiàn)在我們的計算器有點(diǎn)樣子了:
似乎有點(diǎn)簡單。但是請注意差油,這個界面是完全的原生界面拗军,完全由原生組件構(gòu)成。然而蓄喇,由于Nativescript的支持发侵,我們確可以像開發(fā)web應(yīng)用一般輕松的開發(fā)原生應(yīng)用了。
但是現(xiàn)在的Keyboard還不能提供任何功能妆偏,Keyboard不能響應(yīng)點(diǎn)擊事件刃鳄,也不能把數(shù)據(jù)傳遞給Displayer。接下來我們就要為Keyboard加上這些功能钱骂。
交互
Nativescript提供了原生的手勢事件叔锐,你可以在應(yīng)用中直接使用。由于touch事件會返回手指的狀態(tài):向下见秽,移動愉烙,向上等,滿足鍵盤交互的需求解取,因此我們監(jiān)聽touch事件步责。
要監(jiān)聽Keyboard的點(diǎn)擊事件,最直觀的答案就是為每個按鈕設(shè)置touch事件監(jiān)聽器,在這個計算器應(yīng)用中我們需要設(shè)置19次蔓肯!而且我們的監(jiān)聽邏輯不能復(fù)用遂鹊,雖然他們的功能很相似!這是不可接受的蔗包。所以秉扑,我們應(yīng)該把按鈕也做成一個Angular組件,因?yàn)榻M件是可以復(fù)用的调限。
那么這個按鈕組件需要哪些功能呢舟陆? 當(dāng)點(diǎn)擊按鈕時,按鈕的背景色需要改變旧噪,并且需要把這個點(diǎn)擊事件告知其他組件吨娜。
在app目錄下新建NSButton文件夾,同時在NSButton文件夾里新增一下文件: nsbutton.component.ts, nsbutton.css淘钟。
//nsbutton.component.ts
import {
Component,
ElementRef,
ViewChild,
AfterViewInit,
Input,
OnInit
} from '@angular/core';
import {
Label
} from 'ui/label';
import {
GestureTypes,
TouchGestureEventData
} from 'ui/gestures';
import {
Color
} from 'color';
@Component({
selector: 'nsbutton',
template: `<Label class="keyboard-item" #nsbutton [text]="text" (touch)="onTouch($event)"> </Label>`,
styleUrls:['NSButton/nsbutton.css']
})
export class NSButton implements AfterViewInit{
@ViewChild('nsbutton') nsBtnRef : ElementRef;
@Input('text') text: string;
@Input('normalBg') normalBg:string;
@Input('activeBg') activeBg:string;
private nsBtnView : Label;
ngAfterViewInit() {
this.nsBtnView = <Label> this.nsBtnRef.nativeElement;
this.changeBg(this.nsBtnView,this.normalBg || '#D0D0D0');
}
changeBg(component:Label,bgColor:string) {
component.backgroundColor = new Color(bgColor);
}
onTouch(event) {
this.onTouchEvent(event.action);
}
onTouchEvent(type:string) {
switch(type) {
case 'down':
case 'move':
this.changeBg(this.nsBtnView,this.activeBg || '#A3A3A3');
break;
default:
this.changeBg(this.nsBtnView,this.normalBg || '#D0D0D0');
break;
}
}
}
請注意宦赠,這里我們沒有使用ngStyle的方式來改變按鈕的背景,而是用了更底層一級的API米母。主要是為了像你展示在Nativescript中使用原生API是多么輕松的一件事勾扭。
//nsbutton.css
.keyboard-item {
border-width: 0.5;
border-color: rgb(123,123,123);
font-family: monospace;
width:100%;
height: 100%;
text-align: center;
font-size: 25;
}
然后,需要在Keyboard組件里引入NSButton铁瞒。修改keyboard.component.ts和keyboard.html文件如下:
//keyboard.component.ts
import {
Component,
} from '@angular/core';
import {
NSButton
} from '../NSButton/nsbutton.component';
@Component({
selector:'keyboard',
templateUrl:'Keyboard/keyboard.html',
styleUrls:['Keyboard/keyboard.css'],
directives:[NSButton],
})
export class Keyboard{
}
//keyboard.html
<GridLayout row="1" columns="1*,1*,1*,1*"
rows="1*,1*,1*,1*,1*">
<!--第一行-->
<GridLayout row="0" col="0">
<nsbutton text="C"></nsbutton>
</GridLayout>
<GridLayout row="0" col="1">
<nsbutton text="+/-"></nsbutton>
</GridLayout>
<GridLayout row="0" col="2">
<nsbutton text="%"></nsbutton>
</GridLayout>
<GridLayout row="0" col="3" style="color:#fff;">
<nsbutton text="÷" normalBg="#F27F26" activeBg="#B65F1C"></nsbutton>
</GridLayout>
<!--第二行-->
<GridLayout row="1" col="0">
<nsbutton text="7"></nsbutton>
</GridLayout>
<GridLayout row="1" col="1">
<nsbutton text="8"></nsbutton>
</GridLayout>
<GridLayout row="1" col="2">
<nsbutton text="9"></nsbutton>
</GridLayout>
<GridLayout row="1" col="3" style="color:#fff;">
<nsbutton text="x" normalBg="#F27F26" activeBg="#B65F1C"></nsbutton>
</GridLayout>
<!--第三行-->
<GridLayout row="2" col="0">
<nsbutton text="4"></nsbutton>
</GridLayout>
<GridLayout row="2" col="1">
<nsbutton text="5"></nsbutton>
</GridLayout>
<GridLayout row="2" col="2">
<nsbutton text="6"></nsbutton>
</GridLayout>
<GridLayout row="2" col="3" style="color:#fff;">
<nsbutton text="-" normalBg="#F27F26" activeBg="#B65F1C"></nsbutton>
</GridLayout>
<!--第四行-->
<GridLayout row="3" col="0">
<nsbutton text="1"></nsbutton>
</GridLayout>
<GridLayout row="3" col="1">
<nsbutton text="2"></nsbutton>
</GridLayout>
<GridLayout row="3" col="2">
<nsbutton text="3"></nsbutton>
</GridLayout>
<GridLayout row="3" col="3" style="color:#fff;">
<nsbutton text="+" normalBg="#F27F26" activeBg="#B65F1C"></nsbutton>
</GridLayout>
<!--第五行-->
<GridLayout row="4" col="0" colSpan="2">
<nsbutton text="0"></nsbutton>
</GridLayout>
<GridLayout row="4" col="2">
<nsbutton text="."></nsbutton>
</GridLayout>
<GridLayout row="4" col="3" style="color:#fff;">
<nsbutton text="=" normalBg="#F27F26" activeBg="#B65F1C"></nsbutton>
</GridLayout>
</GridLayout>
現(xiàn)在妙色,我們的按鈕組件就有了一個漂亮的點(diǎn)擊動畫。
不過Keyboard的點(diǎn)擊事件還不能通知給Displayer慧耍,我們接著來增加這個功能身辨,修改nsbuttom.component.ts, keyboard.component.ts, app.component.ts如下:
//nsbuttom.component.ts
import {
Component,
ElementRef,
ViewChild,
AfterViewInit,
Input,
OnInit
} from '@angular/core';
import {
Label
} from 'ui/label';
import {
GestureTypes,
TouchGestureEventData
} from 'ui/gestures';
import {
Color
} from 'color';
@Component({
selector: 'nsbutton',
template: `<Label class="keyboard-item" #nsbutton [text]="text" (touch)="onTouch($event)"> </Label>`,
styleUrls:['NSButton/nsbutton.css']
})
export class NSButton implements AfterViewInit{
@ViewChild('nsbutton') nsBtnRef : ElementRef;
@Input('text') text: string;
@Input('normalBg') normalBg:string;
@Input('activeBg') activeBg:string;
@Input('onBtnClicked') onBtnClicked: Function;
private nsBtnView : Label;
ngAfterViewInit() {
this.nsBtnView = <Label> this.nsBtnRef.nativeElement;
this.changeBg(this.nsBtnView,this.normalBg || '#D0D0D0');
}
changeBg(component:Label,bgColor:string) {
component.backgroundColor = new Color(bgColor);
}
onTouch(event) {
this.onTouchEvent(event.action);
}
onKeyUp() {
if(this.onBtnClicked) {
this.onBtnClicked && this.onBtnClicked(this.text);
}
}
onTouchEvent(type:string) {
switch(type) {
case 'down':
case 'move':
this.changeBg(this.nsBtnView,this.activeBg || '#A3A3A3');
break;
case 'up':
this.onKeyUp();
default:
this.changeBg(this.nsBtnView,this.normalBg || '#D0D0D0');
break;
}
}
}
//keyboard.component.ts
import {
Component,
Input,
OnInit
} from '@angular/core';
import {
NSButton
} from '../NSButton/nsbutton.component';
@Component({
selector:'keyboard',
templateUrl:'Keyboard/keyboard.html',
styleUrls:['Keyboard/keyboard.css'],
directives:[NSButton],
})
export class Keyboard implements OnInit{
@Input('onKeyBoardClicked') onKeyBoardClicked: Function;
ngOnInit() {
this.onBtnClicked = this.onBtnClicked.bind(this);
}
public onBtnClicked(text:string):void {
this.onKeyBoardClicked && this.onKeyBoardClicked(text);
}
}
//app.component.ts
import {
Component,
OnInit,
ElementRef,
ViewChild,
AfterViewInit,
} from "@angular/core";
import {
Label
} from 'ui/label';
import {
Keyboard
} from './Keyboard/keyboard.component';
import {
device,
platformNames
} from 'platform';
@Component({
selector: "calculator",
template: `
<GridLayout rows="auto,*" columns="*">
<!--Dispalyer-->
<StackLayout row="0" style="font-size:60;color:#fff;height:120;background-color:rgba(0,0,0,0.8);text-align:right;vertical-align:bottom;">
<Label [text]="counter" #displayer></Label>
</StackLayout>
<!--Keyboard-->
<keyboard row="1" [onKeyBoardClicked]="onKeyBoardClicked"></keyboard>
</GridLayout>
`,
directives:[Keyboard]
})
export class AppComponent implements OnInit{
public counter: string = '';
@ViewChild('displayer') displayerRef: ElementRef;
private displayerView : Label;
ngOnInit() {
this.onKeyBoardClicked = this.onKeyBoardClicked.bind(this);
}
public onKeyBoardClicked(text:string):void {
this.counter += text;
}
}
這樣我們的Keyboard點(diǎn)擊就能實(shí)時顯示在Disapler上面了。
這個交互我們完全依賴于Angular2為我們提供的單向綁定芍碧。再強(qiáng)調(diào)一次煌珊,Nativesript支持所有的Angular2功能,這真的會簡化我們的開發(fā)泌豆。
原生API
對比我們的計算器和ios原生計算器定庵,我們發(fā)現(xiàn)原生計算器的Displayer會自動調(diào)整字體大小,以保證顯示的數(shù)字完全展示踪危。得益于Nativescript蔬浙,我們也能通過Javascript調(diào)用這套API,實(shí)現(xiàn)相同的效果贞远。修改app.comonent.ts如下:
//app.component.ts
import {
Component,
OnInit,
ElementRef,
ViewChild,
AfterViewInit,
} from "@angular/core";
import {
Label
} from 'ui/label';
import {
Keyboard
} from './Keyboard/keyboard.component';
import {
device,
platformNames
} from 'platform';
@Component({
selector: "calculator",
template: `
<GridLayout rows="auto,*" columns="*">
<!--Dispalyer-->
<StackLayout row="0" style="font-size:60;color:#fff;height:120;background-color:rgba(0,0,0,0.8);text-align:right;vertical-align:bottom;">
<Label [text]="counter" #displayer></Label>
</StackLayout>
<!--Keyboard-->
<keyboard row="1" [onKeyBoardClicked]="onKeyBoardClicked"></keyboard>
</GridLayout>
`,
directives:[Keyboard]
})
export class AppComponent implements OnInit, AfterViewInit{
public counter: string = '';
@ViewChild('displayer') displayerRef: ElementRef;
private displayerView : Label;
ngAfterViewInit() {
this.displayerView = <Label> this.displayerRef.nativeElement;
this.setIOSLabelAutoFont(this.displayerView);
}
private setIOSLabelAutoFont(elem: Label) {
if(device.os === platformNames.ios){
elem.ios.numberOfLines = 1;
elem.ios.minimumFontSize = 20;
elem.ios.adjustsFontSizeToFitWidth = true;
}
}
ngOnInit() {
this.onKeyBoardClicked = this.onKeyBoardClicked.bind(this);
}
public onKeyBoardClicked(text:string):void {
this.counter += text;
}
}
elem.ios.numberOfLines = 1
, elem.ios.minimumFontSize = 20
, elem.ios.adjustsFontSizeToFitWidth = true
是三個IOS的UILabel原生的api畴博。在Nativescript中,我們可以使用Javascript直接調(diào)用他們蓝仲,Nativescript會幫我們處理好Javascript到原生的映射绎晃,包括數(shù)據(jù)類型的轉(zhuǎn)換蜜唾,不需要寫任我的ObjectiveC代碼。
如此庶艾,我們就實(shí)現(xiàn)了在文章最開始展示的交互。** 這個交互擎勘,在ReactNative中咱揍,是無法直接實(shí)現(xiàn)的! **這也是Nativescript相比于ReactNative的強(qiáng)大之處
總結(jié)
得益于Nativescript可以訪問100%的原生API, 我們不需要寫任何原生代碼棚饵,就能獲得和原生代碼一樣的能力煤裙。這可以說是Nativescript相比于其他平臺,比如React Native, 最大的優(yōu)勢噪漾。在現(xiàn)階段硼砰,Nativescript應(yīng)該是最成熟的,性能最好的跨平臺APP構(gòu)建方案欣硼。
github代碼在這里:https://github.com/eeandrew/NSCalculator