这将从 GitHub 将代码下载到名为git clone https://github.com/alexziskind1/nativescript-calculator-demoapp.git
nativescript-calculator-demoapp的目录中。在您的终端中导航到该目录,以便您可以执行 NativeScript 命令
将 iOS 平台添加到项目中,为在模拟器或设备上运行做好准备cd
nativescript-calculator-demoapp
现在您已准备好运行该应用程序。如果您想在 iOS 模拟器中运行该应用程序,请执行 emulate 命令tns platform add ios
您也可以直接在 iPhone 上运行它,只需将手机通过 USB 连接到 Mac 并执行 run 命令tns emulate ios
计算器应该在您的模拟器或设备中打开,并将如下所示tns run ios
iOS 计算器应用程序在右侧的操作条中有一个轻微的渐变,从 West Side 到 Ecstacy。或者正如我所说的,从浅橙色到深橙色。.label-back {
background-color
:
#202020
;
padding-top
:
50
;
}
GridLayout
构建的,在 GridLayout
加载时,背景图像在 JavaScript 代码中设置。这将从捆绑包中加载图像,并将网格的背景设置为使用该图像。有几种技术可以设置布局的背景,这些技术在我的 关于该主题的文章中进行了详细说明。function
actionsGridLoaded(args) {
var
theView = args.object._view;
if
(args.object.ios) {
theView.layer.contents = UIImage.imageNamed(
"app/res/calc-back-orange.png"
).CGImage;
}
}
exports.actionsGridLoaded = actionsGridLoaded;
自然,布局应该能够嵌套,NativeScript 提供了大量选项来找到合适的组合。计算器应用程序演示了三种布局类型的使用:DockLayout
、StackLayout
和 GridLayout
,以及多级嵌套。
<
DockLayout
stretchLastChild
=
"true"
>
<
StackLayout
dock
=
"top"
>
…
</
StackLayout
>
<
GridLayout
rows
=
"*, *, *, *, *"
columns
=
"*, *, *, *"
dock
=
"bottom"
>
…
<
GridLayout
rowSpan
=
"5"
col
=
"3"
rows
=
"*, *, *, *, *"
columns
=
"*"
>
…
</
GridLayout
>
</
GridLayout
>
</
DockLayout
>
虽然 NativeScript 支持开箱即用的许多常见本机功能,但有时您可能想要更进一步,对这些控件进行额外的操作。它的美妙之处在于您绝对可以做到这一点,因为 NativeScript 允许您在需要时深入到本机级别。
iOS 计算器数字显示的工作方式就是一个这样的需求。字体的大小保持不变,直到输入一定数量的数字。一旦数字的数量超过显示的宽度,字体就会自动开始减小尺寸。这是一个很好的效果,并且在 iOS 中通过在标签上设置属性来支持。
我们可以通过扩展 NativeScript 自带的标签来利用这种能力。以下代码展示了如何通过设置名为 adjustsFontSizeToFitWidth
的本机底层 iOS 标签属性来扩展 Label
元素。
__extends
的函数。您可以在文章末尾看到它的定义。这段代码创建了一个名为var
ScalingLabel = (
function
(_super) {
__extends(ScalingLabel, _super);
function
ScalingLabel () {
_super.call(
this
);
this
.mylabel = UILabel.alloc().init();
this
._ios.adjustsFontSizeToFitWidth =
true
;
this
.ios.font = UIFont.fontWithNameSize(
"HelveticaNeue-UltraLight"
, 80);
this
.ios.addSubview(
this
.mylabel );
}
return
ScalingLabel;
})(label.Label);
exports.ScalingLabel = ScalingLabel;
ScalingLabel
的新标签类型,它将根据计算器显示中显示的数字数量自动调整其字体大小。计算器应用程序在 components 文件夹中的 calccomponents.ios.js 文件中具有 ScalingLabel
等额外组件。Page
元素提供了另一个属性,该属性指向定义 ScalingLabel
的代码文件的位置。<
Page
xmlns:cc
=
"components/calccomponents"
xmlns
=
"http://schemas.nativescript.org/tns.xsd"
loaded
=
"pageLoaded"
>
...
</
Page
>
ScalingLabel
放置到我们的页面中<
cc:ScalingLabel
text
=
"{{ mainLabelText }}"
cssClass
=
"display"
/>
AVAudioPlayer
类,该类是 AVFoundation 框架的一部分,这正是我们将在这里使用的。为了使按钮发出点击声,我们在 NativeScript 项目中创建了一个新模块。这里只显示 iOS 版本,但 Android 版本也可以轻松创建。
名为 clicker.ios.js 的文件包含该模块,该模块将维护对音频播放器的活动引用。该模块将创建AVAudioPlayer
的一个新实例,并公开一个名为 click
的函数,该函数将在每次点击按钮时触发。在视图模型中,我们维护对 clicker 类的引用,并在需要时调用它。var
Clicker =
function
(resource) {
var
soundPath = NSBundle.mainBundle().pathForResourceOfType(
"app/"
+resource,
"mp3"
);
var
soundUrl = NSURL.fileURLWithPath(soundPath);
var
player = AVAudioPlayer.alloc().initWithContentsOfURLError(soundUrl,
null
);
player.prepareToPlay();
this
.click =
function
() {
player.currentTime = 0.0;
player.play();
};
};
module.exports.Clicker = Clicker;
当 UI 中的按钮被点击时,var
Calc = (
function
(_super) {
__extends(Calc, _super);
function
Calc() {
_super.call(
this
);
var
self =
this
;
this
.clicker =
new
clicker.Clicker(
"res/click_short"
);
…
}
}
click
函数被调用,播放器播放点击声。…
Calc.prototype.btnTapEq =
function
() {
this
.playSound();
this
.equalsPressed();
};
Calc.prototype.playSound =
function
() {
this
.clicker.click();
};
…
我们的计算器应用程序使用两种类型的 UI 元素,需要更新它们的字体
查看我的 关于字体的文章 ,以了解有关 NativeScript 字体技术的更多详细信息,以及使用自定义字体。var
button = require(
"ui/button/button"
);
var
FontButton = (
function
(_super) {
__extends(FontButton, _super);
function
FontButton() {
_super.call(
this
);
this
.mybutton = UIButton.alloc().init();
this
.ios.font = UIFont.fontWithNameSize(
"HelveticaNeue-Thin"
, 80);
this
.ios.addSubview(
this
.mybutton );
}
return
FontButton;
})(button.Button);
exports.FontButton = FontButton;
如果您已经使用过 NativeScript 一段时间,您一定已经注意到 XML 中 Page
元素上的 loaded
属性。实际上,Page
元素并不是唯一触发 loaded
事件的 UI 元素。您可以为布局、按钮、标签等添加加载处理程序。您只需在 XML 中的元素上添加 loaded
属性,并指定 JavaScript 代码中公开的处理程序即可。
loaded
处理程序的 GridLayout
来构建的<
GridLayout
loaded
=
"actionsGridLoaded"
rowSpan
=
"5"
col
=
"3"
rows
=
"*, *, *, *, *"
columns
=
"*"
>
…
</
GridLayout
>
loaded 事件处理程序接收对底层视图对象的引用,我们可以操作该对象并将背景图像设置为视图的 layer 属性。function
actionsGridLoaded(args) {
var
theView = args.object._view;
if
(args.object.ios) {
theView.layer.contents = UIImage.imageNamed(
"app/res/calc-back-orange.png"
).CGImage;
}
}
exports.actionsGridLoaded = actionsGridLoaded;
如果您还没有,请从 GitHub 获取计算器代码,运行它,看看所有部分是如何相互作用的。使用本文帮助您了解文档中可能尚未涵盖的某些概念。然后开始构建您自己的应用程序!
__extends
函数 - 此函数通过将所有父属性复制到子类来模拟继承。var
__extends =
this
.__extends ||
function
(d, b) {
for
(
var
p
in
b)
if
(b.hasOwnProperty(p)) d[p] = b[p];
function
__() {
this
.constructor = d; }
__.prototype = b.prototype;
d.prototype =
new
__();
};