35、打造iOS小费计算器应用:从项目创建到UI设计与优化

打造iOS小费计算器应用:从项目创建到UI设计与优化

1. 应用启动流程与类型桥接

在应用启动时,会经历一系列重要步骤:
1. 加载主故事板。
2. 创建UI组件。
3. 实例化应用初始视图控制器类的对象。
4. 利用故事板中存储的信息,将视图控制器的 @IBOutlets @IBActions 连接到相应的UI组件。

由于此应用只有一个场景,所以仅有一个视图控制器。故事板对象创建完成后,iOS会调用视图控制器的 viewDidLoad 方法。在这个方法里,可以执行一些特定于视图的任务,这些任务只有在场景的UI组件存在之后才能执行。例如,在这个应用中,可以调用 UITextField becomeFirstResponder 方法,使它成为活动组件,就好像用户触摸了它一样。同时,配置 UITextField ,当它成为活动组件时,在屏幕下半部分显示数字键盘。从 viewDidLoad 调用 becomeFirstResponder 会使iOS在视图加载后立即显示键盘(如果设备连接了蓝牙键盘,则不会显示键盘)。调用此方法还表明 UITextField 是第一响应者,即事件发生时第一个接收通知的组件。iOS的响应者链定义了组件接收事件通知的顺序,更多详细信息可访问: http://bit.ly/iOSResponderChain

在开发过程中,经常会将Swift对象传递给用Objective - C编写的类的方法,比如Cocoa Touch类中的方法。Swift的数字类型、 String Array Dictionary 类型都可以在需要其Objective - C等效类型的上下文中使用。同样,当Objective - C的等效类型(如 NSString NSArray NSMutableArray NSDictionary NSMutableDictionary )返回到Swift代码中时,会自动被视为其Swift对应类型。例如,在这个应用中,使用 NSNumberFormatter 类创建特定于区域设置的货币和百分比字符串,这些字符串从 NSNumberFormatter 的方法中返回时是 NSString 对象,但Swift会自动将其视为 String 类型的对象,这种机制被称为桥接,对开发者来说是透明的。

2. 构建应用的UI
2.1 创建项目

首先,创建一个新的单视图iOS应用项目,在“选择新项目选项”页面中指定以下设置:
- 产品名称: TipCalculator
- 组织名称:可以使用 Deitel and Associates, Inc. ,也可以使用自己的组织名称。
- 公司标识符:可以使用 com.deitel ,也可以使用自己的公司标识符或 edu.self
- 语言:Swift。
- 设备:iPhone。该应用是为iPhone和iPod touch设计的,虽然可以在iPad上运行,但会填充大部分屏幕并居中显示。

指定完设置后,点击“下一步”,选择项目保存位置,然后点击“创建”来创建项目。

为了避免数字键盘在横向模式下遮挡小费计算器的部分UI,此应用仅支持纵向模式。在Xcode编辑器区域显示的项目设置的“常规”选项卡中,滚动到“部署信息”部分,确保“设备方向”中仅选择“纵向”。大多数iPhone应用应支持纵向、左横向和右横向模式,大多数iPad应用还应支持倒置模式,更多关于苹果人机界面指南的信息可访问: http://bit.ly/HumanInterfaceGuidelines

2.2 配置尺寸类以设计纵向模式的iPhone应用

在之前的设计中,使用默认的尺寸类“Any”来支持任何iOS设备的纵向和横向模式。而在这个应用中,需要为纵向模式的高窄设备(如iPhone或iPod touch)配置设计区域。选择 Main.storyboard 以显示设计区域(也称为画布),在画布底部点击“尺寸类”控件以显示尺寸类工具,然后点击左下角指定尺寸类为“紧凑宽度和常规高度”。

2.3 添加UI组件

下面详细介绍添加UI组件的步骤:
1. 添加“账单金额”标签
- 从对象库中拖动一个标签到场景的左上角,使用蓝色引导线将标签定位到距离场景顶部和左侧的推荐距离。
- 双击标签,输入“Bill Amount”,然后按回车键更改其文本属性。
2. 添加显示格式化用户输入的标签
- 在“账单金额”标签下方拖动另一个标签,使放置引导线如图所示,这里将显示用户输入。
- 拖动新标签右侧的中间调整手柄,直到场景右侧出现蓝色引导线。
- 在属性检查器中,滚动到“视图”部分,找到标签的“背景”属性,点击该属性的值,选择“其他…”以显示颜色对话框。使用对话框底部第二行的“Crayons”选项卡,选择“Sky(蓝色)”蜡笔颜色,并将不透明度设置为50%,使场景的白色背景与标签颜色混合,得到更浅的蓝色。
- 标签的默认高度为21点,为了使文本在彩色背景下更易读,拖动底部中心调整手柄将标签高度增加到30点。
- 选中标签,在属性检查器中删除其“文本”属性的值,使标签为空。
3. 添加“自定义小费百分比:”标签和显示当前自定义小费百分比的标签
- 在蓝色标签下方拖动另一个标签,双击并将其文本设置为“Custom Tip Percentage:”。
- 在“自定义小费百分比:”标签右侧拖动另一个标签,将其文本设置为“18%”,这是应用中选择的初始自定义小费百分比,当用户移动滑块时,应用会更新该值。
4. 创建自定义小费百分比滑块
- 从对象库中拖动一个滑块到场景中,使其与“自定义小费百分比:”标签保持推荐距离,然后调整其大小和位置。
- 使用属性检查器将滑块的最小值设置为0(默认值),最大值设置为30,当前值设置为18。
5. 添加“15%”和“18%”标签
- 拖动另一个标签到场景中,使用蓝色引导线将其定位到滑块下方的推荐距离,将其文本设置为“15%”,并将对齐方式设置为居中。
- 按住“Option”键并拖动“15%”标签到右侧进行复制,也可以选中该标签并按“+ D”复制,然后将新标签的文本更改为“18%”。
6. 创建显示小费和总计的标签
- 拖动一个标签到UI上,直到出现蓝色引导线。
- 拖动标签的底部中心调整手柄将高度设置为30,拖动左侧中心调整手柄将宽度设置为156。
- 使用属性检查器清除“文本”属性,将对齐方式设置为居中,背景颜色设置为“Banana”(位于颜色对话框的“Crayons”选项卡中倒数第二行)。
- 将“自动收缩”属性设置为“最小字体比例”,并将值更改为0.75,如果文本太宽无法适应标签,文本将缩小到原始字体大小的75%以容纳更多文本。
- 按住“Option”键并拖动黄色标签到左侧复制,创建另一个位于“15%”标签下方的标签。
- 按住“Shift”键并点击每个黄色标签以选中它们,按住“Option”键并拖动其中一个选中的标签向下,直到出现蓝色引导线。
- 拖动“Tip”标签,使蓝色引导线如图所示,将“15%”和“18%”标签居中于它们对应的列上方。
7. 创建“Tip”和“Total”标签
- 拖动一个标签到场景中,将其文本更改为“Total”,将对齐方式设置为右对齐,并将其定位到第二行黄色标签的左侧。
- 按住“Option”键并拖动“Total”标签向上,直到出现蓝色引导线,将新标签的文本更改为“Tip”,然后将其向右拖动,使“Tip”和“Total”标签的右边缘对齐。
8. 创建用于接收用户输入的文本字段
- 从对象库中拖动一个文本字段到场景的底部边缘,使用属性检查器将其“键盘类型”属性设置为“数字键盘”,“外观”设置为“深色”。这个文本字段在应用首次加载时将隐藏在数字键盘后面,通过它接收用户输入,然后将输入格式化并显示在场景顶部的蓝色标签中。

下面是添加UI组件的流程图:

graph LR
    A[开始] --> B[添加“账单金额”标签]
    B --> C[添加显示格式化用户输入的标签]
    C --> D[添加“自定义小费百分比:”标签和显示当前自定义百分比的标签]
    D --> E[创建自定义小费百分比滑块]
    E --> F[添加“15%”和“18%”标签]
    F --> G[创建显示小费和总计的标签]
    G --> H[创建“Tip”和“Total”标签]
    H --> I[创建用于接收用户输入的文本字段]
    I --> J[结束]
3. 添加自动布局约束

虽然已经完成了小费计算器应用的UI设计,但还没有添加任何自动布局约束。如果在模拟器或设备上运行应用,会发现根据使用的模拟器不同,一些UI组件可能会超出屏幕边缘。下面介绍添加自动布局约束的步骤:
1. 添加缺失的自动布局约束
- 点击设计区域的白色背景或在文档大纲窗口中选择“视图”。
- 在画布底部,点击“解决自动布局问题”按钮,在“视图控制器中的所有视图”下选择“添加缺失的约束”。
- Interface Builder会分析设计中的UI组件,根据它们的大小、位置和对齐方式为你创建一组自动布局约束。在某些情况下,这些约束可能足够满足设计需求,但通常还需要进行一些调整。添加缺失约束后,所有UI组件都完全可见,但有些组件的大小和位置可能不正确,特别是黄色标签应该具有相同的宽度。
2. 设置黄色标签具有相同的宽度
- 按住“Shift”键并点击每个黄色标签以选中它们。
- 在画布底部的自动布局工具中,点击“Pin工具”图标,确保“Equal Widths”被选中,然后点击“添加3个约束”按钮。由于三个标签将被设置为与第四个标签具有相同的宽度,所以只添加了三个约束。但设置黄色标签宽度相等后,右侧列上方的“18%”标签可能会消失,“Tip”和“Total”标签可能会变得太窄而无法显示。
3. 调试缺失的“18%”标签
- 选中画布中的“18%”标签,在实用工具区域选择“大小检查器”,可以看到该标签的完整约束集。“18%”标签的水平定位有两个约束:“Trailing Space to: Superview”约束指定该标签应距离场景的后边缘60点;“Align Center X to: Label”约束指定该标签应在指定标签上水平居中。这两个约束相互冲突,根据黄色标签的宽度,“18%”标签可能会出现在距离场景后边缘不同的位置。通过在大小检查器中点击“Trailing Space to: Superview”约束并按删除键,可以消除冲突。测试应用在不同模拟器中的显示效果,确保UI正常工作。

下面是添加自动布局约束的步骤表格:
|步骤|操作|
|----|----|
|1|点击设计区域白色背景或选择“视图”,点击“解决自动布局问题”按钮,选择“添加缺失的约束”|
|2|选中所有黄色标签,点击“Pin工具”图标,选中“Equal Widths”,点击“添加3个约束”按钮|
|3|选中“18%”标签,在“大小检查器”中删除“Trailing Space to: Superview”约束|

4. 使用Interface Builder创建输出口

接下来,使用Interface Builder为应用以编程方式交互的UI组件创建输出口。常见的命名约定是在输出口属性名称的末尾使用不包含“UI”类前缀的UI组件类名,例如 billAmountLabel 而不是 billAmountUILabel 。Interface Builder通过从组件控制拖动到源代码中,使创建UI组件的输出口变得容易,这里需要利用Xcode助理编辑器。
1. 打开助理编辑器
- 确保在项目导航器中选择场景的故事板,然后点击Xcode工具栏上的“助理编辑器”按钮(或选择“视图 > 助理编辑器 > 显示助理编辑器”)。Xcode的编辑器区域会分割,右侧将显示 ViewController.swift 文件。默认情况下,查看故事板时,助理编辑器会显示相应视图控制器的源代码。但通过点击助理编辑器顶部跳转栏中的“自动”,可以选择不同设备尺寸和方向的UI预览选项、本地化版本的UI预览或与当前编辑器中显示的内容并排查看其他文件。Xcode自动生成的第1 - 7行注释可以删除,并用自己的注释替换。同时,删除第18 - 21行的 didReceiveMemoryWarning 方法,因为在这个应用中不会使用它。
2. 创建输出口
- 为显示用户输入的蓝色标签创建输出口,需要这个输出口以编程方式更改标签的文本,以货币格式显示输入。输出口被声明为视图控制器类的属性。控制从蓝色标签拖动到 ViewController.swift 的第11行下方并释放,会显示一个用于配置输出口的弹出窗口。
- 在弹出窗口中,确保“连接类型”选择“输出口”,指定输出口名称为 billAmountLabel ,然后点击“连接”。Xcode会在 ViewController 类中插入以下属性声明:

@IBOutlet weak var billAmountLabel: UILabel!
- 重复上述步骤为其他标记的UI组件创建输出口。每个输出口属性左侧的灰色边距中有一个小靶心符号,表示输出口已连接到UI组件。将鼠标悬停在该符号上,会在场景中突出显示连接的UI组件,可用于确认每个输出口是否正确连接。

通过以上步骤,完成了小费计算器应用的项目创建、UI设计、自动布局约束添加和输出口创建等工作,为后续的功能实现奠定了基础。

5. 代码实现与功能完善

在完成了UI设计和输出口创建后,接下来要在 ViewController.swift 文件中添加代码,实现小费计算器的核心功能。

5.1 导入必要的库

ViewController.swift 文件的开头,导入必要的库:

import UIKit

class ViewController: UIViewController {

    // 之前创建的输出口
    @IBOutlet weak var billAmountLabel: UILabel!
    @IBOutlet weak var customTipPercentageLabel: UILabel!
    @IBOutlet weak var tip15Label: UILabel!
    @IBOutlet weak var total15Label: UILabel!
    @IBOutlet weak var tipCustomLabel: UILabel!
    @IBOutlet weak var totalCustomLabel: UILabel!
    @IBOutlet weak var customTipSlider: UISlider!
    @IBOutlet weak var billAmountTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 使文本字段成为第一响应者,显示键盘
        billAmountTextField.becomeFirstResponder()
        // 设置滑块的初始值
        customTipSlider.value = 18
        // 更新自定义小费百分比标签
        updateCustomTipPercentageLabel()
        // 计算并更新小费和总计
        calculateTips()
    }

    // 更新自定义小费百分比标签
    func updateCustomTipPercentageLabel() {
        let customTipPercentage = Int(customTipSlider.value)
        customTipPercentageLabel.text = "\(customTipPercentage)%"
    }

    // 计算小费和总计
    func calculateTips() {
        // 获取账单金额
        let billAmount = Double(billAmountTextField.text!) ?? 0
        // 计算15%的小费和总计
        let tip15 = billAmount * 0.15
        let total15 = billAmount + tip15
        // 计算自定义小费和总计
        let customTipPercentage = Double(customTipSlider.value) / 100
        let tipCustom = billAmount * customTipPercentage
        let totalCustom = billAmount + tipCustom

        // 创建数字格式化器
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle =.currency

        // 格式化并更新标签文本
        if let formattedTip15 = numberFormatter.string(from: NSNumber(value: tip15)),
           let formattedTotal15 = numberFormatter.string(from: NSNumber(value: total15)),
           let formattedTipCustom = numberFormatter.string(from: NSNumber(value: tipCustom)),
           let formattedTotalCustom = numberFormatter.string(from: NSNumber(value: totalCustom)) {
            tip15Label.text = formattedTip15
            total15Label.text = formattedTotal15
            tipCustomLabel.text = formattedTipCustom
            totalCustomLabel.text = formattedTotalCustom
        }
    }

    // 滑块值改变时的响应方法
    @IBAction func customTipSliderValueChanged(_ sender: UISlider) {
        updateCustomTipPercentageLabel()
        calculateTips()
    }

    // 文本字段编辑结束时的响应方法
    @IBAction func billAmountTextFieldEditingDidEnd(_ sender: UITextField) {
        calculateTips()
    }
}
5.2 代码解释
  • 导入库 :导入 UIKit 库,这是iOS应用开发的基础库。
  • 输出口声明 :之前通过Interface Builder创建的输出口,用于与UI组件进行交互。
  • viewDidLoad 方法 :在视图加载完成后调用,使文本字段成为第一响应者显示键盘,设置滑块的初始值,更新自定义小费百分比标签,并计算初始的小费和总计。
  • updateCustomTipPercentageLabel 方法 :根据滑块的值更新自定义小费百分比标签的文本。
  • calculateTips 方法 :获取账单金额,计算15%的小费和总计,以及自定义百分比的小费和总计。使用 NumberFormatter 将计算结果格式化为货币字符串,并更新相应的标签文本。
  • customTipSliderValueChanged 方法 :当滑块的值改变时,更新自定义小费百分比标签,并重新计算小费和总计。
  • billAmountTextFieldEditingDidEnd 方法 :当文本字段编辑结束时,重新计算小费和总计。

下面是代码执行流程的流程图:

graph LR
    A[视图加载] --> B[使文本字段成为第一响应者]
    B --> C[设置滑块初始值]
    C --> D[更新自定义小费百分比标签]
    D --> E[计算初始小费和总计]
    F[滑块值改变] --> G[更新自定义小费百分比标签]
    G --> E
    H[文本字段编辑结束] --> E
6. 测试与优化

在完成代码编写后,需要对应用进行测试,确保其功能正常。

6.1 测试步骤
  1. 在Xcode中,选择模拟器或连接的设备。
  2. 点击运行按钮,启动应用。
  3. 在文本字段中输入账单金额,观察蓝色标签是否以货币格式显示输入。
  4. 拖动滑块,观察自定义小费百分比标签和计算结果是否更新。
  5. 改变设备的方向(虽然应用仅支持纵向,但可测试布局是否稳定),确保UI组件显示正常。
6.2 优化建议
  • 输入验证 :目前代码没有对用户输入进行验证,当用户输入非数字字符时,可能会导致计算错误。可以在 calculateTips 方法中添加输入验证逻辑,确保输入为有效的数字。
  • 用户体验优化 :可以添加一些动画效果,如键盘的显示和隐藏动画,或者计算结果更新时的淡入淡出效果,提升用户体验。
  • 本地化支持 :当前应用的货币格式是根据系统默认设置的,可以根据用户的地区设置动态调整货币符号和格式。
7. 总结

通过以上步骤,我们完成了一个简单的iOS小费计算器应用的开发。从项目创建、UI设计、自动布局约束添加、输出口创建到代码实现和功能测试,涵盖了iOS应用开发的基本流程。在开发过程中,要注意以下几点:
- UI设计 :合理使用尺寸类和自动布局约束,确保应用在不同设备上都能正常显示。
- 代码结构 :遵循良好的代码结构和命名规范,使代码易于维护和扩展。
- 用户体验 :注重用户体验,如输入验证、动画效果和本地化支持等。

希望这篇文章能帮助你了解iOS应用开发的基本流程,通过实践不断提升自己的开发技能。

下面是开发流程的总结表格:
|阶段|操作|
|----|----|
|项目创建|指定产品名称、组织名称、公司标识符、语言和设备类型,选择保存位置创建项目,配置设备方向为纵向|
|UI设计|配置尺寸类,添加UI组件,添加自动布局约束|
|输出口创建|使用Interface Builder创建UI组件的输出口|
|代码实现|在 ViewController.swift 中编写代码,实现小费计算功能|
|测试优化|测试应用功能,进行输入验证、用户体验优化和本地化支持等优化|

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值