Tìm hiểu Swift thông qua việc làm 1 ứng dụng tính toán tiền Tip đơn giản trên iOS

Việc đầu tiên chúng ta cần làm là tạo 1 Project mới trong Xcode bằng File/New/Project rồi chọn Single View Application cho ứng dụng iOS. Các bạn đặt tên, chọn thiết bị (device) là iPhone rồi chọn nơi để Save project.

Tạo model

Việc đầu tiên chúng ta cần làm là tạo model cho ứng dụng. Để làm điều này, các bạn vào File/New/File rồi chọn iOS/Source/Swift File. Đặt tên file là TipCalculatorModel.swift and click Create

Nội dung của file model này sẽ có dạng như sau:

//
//  TipCalculatorModel.swift
//  TipCalculator
//
//  Created by Justin Vu on 3/29/15.
//  Copyright (c) 2015 Justin Vu. All rights reserved.
//

import Foundation

class TipCalculatorModel {
    var total: Double
    var taxPct: Double
    var subtotal: Double {
        get {
            return total / (taxPct + 1)
        }
    }

    init(total: Double, taxPct: Double) {
        self.total = total
        self.taxPct = taxPct
    }

    func calcTipWithTipPct(tipPct: Double) -> Double {
        return subtotal * tipPct
    }

    func returnPossibleTips() -> [Int: Double] {
        let possibleTipsInferred = [0.15, 0.18, 0.22]
        let possibleTipsExplicit: [Double] = [0.15, 0.18, 0.22]

        var retval = [Int: Double]()
        for possibleTip in possibleTipsExplicit {
            let intPct = Int(possibleTip*100)
            retval[intPct] = calcTipWithTipPct(possibleTip)
        }
        return retval
    }
}

Vậy là model của ứng dụng đã sẵn sàng, tiếp theo chúng ta sẽ xây dựng phần View của ứng dụng

Xây dựng View

Nhìn lại 1 chút class TipCalculatorModel có 2 inputs là total và tax. Ứng dụng của chúng ta sẽ tốt hơn nếu user có thể nhập total bằng bàn phím số nên chúng ta sẽ sử dụng text field cho nó. Còn đối với tax, thông thường nó là 1 con số trong khoảng nhỏ nên chúng ta sẽ sử dụng slider cho nó.

Bên cạnh text field và slider, chúng ta cần thêm 1 label cho mỗi thứ và 1 navigation bar để show tên app. Kèm theo đó là 1 button để thực hiện việc tính tip và 1 text field để show kết quả.

  1. Navigation bar. Thay vì việc thêm trực tiếp navigation bar trực tiếp, bạn có thể chọn view controller. Sau đó nhìn lên phía trên Menu, chọn Editor/Embed in/Navigation Controller. Việc này sẽ thêm Navigation Bar vào view controller của chúng ta. Double Click lên Navigation Bar ở trong view controller của chúng ta và đặt tên ;à Tip Calculator
  2. Labels. Từ Object Library, kéo Label vào trong view controller. Double Click lên label rồi set text thành Bill Total (Post-Tax). Chọn label, ở phía bên phải, chọn Size Inspector, điền X=33Y=81. Thực hiện việc này tương tự đối với label khác và set text là Tax Percentage (0%), X=20, Y=120
  3. Text Field. Từ Object Library, kéo 1 Text Field vào trong view controller. Ở phần Attributes Inspector, chọn Keyboard Type = Decimal Pad. Ở trong Size Inspector, set X=192, Y=77Width=392
  4. Silder. Từ Object Library, kéo 1 Slider vào view controller. Ở Attribute Inspector set Minimum Value=0, Maximum Value=10Current Value=6. Ở phần Size Inspector, set X=190, Y=116, Width=396
  5. Button. Thêm 1 button vào và đặt tên là Calculate và set X=268, Y=154
  6. Text View. Thêm 1 Text View vào View Controller. Kích đúp vào Text view và xoá toàn bộ phần placeholder text. Ở phần Attributes Inspector, bỏ check EditableSelectable. Ở Size Inspector, set ** X=16, Y=192, Width=568, Height=400**
  7. Tap Gesture Recognizer. Từ Objeect Library, kéo 1 Tap Gesture Recognizer vào main View. (Sử dụng Document Outline để chắc chắn rằng bạn thêm vào main View chứ không phải sub view nào). Gesture này đướcuwr dụng để dismiss keyboard khi user muốn bằng cách chạm vào view
  8. Auto Layout. Chọn main View ở Document Outline, sau đó click button thứ 3 ở phía dưới bên phải và chọn Add Missing Constraints

Build và chạy thử ứng dụng của chúng ta để chắc chắn rằng user interface đã sẵn sàng hoạt động

interface.png

Xử lý View Controller

Mở file ViewController.swift và add những properties sau vào ngay trước method viewDidLoad

    @IBOutlet var totalTextField : UITextField!
    @IBOutlet var taxPctSlider : UISlider!
    @IBOutlet var taxPctLabel : UILabel!
    @IBOutlet var resultsTextView : UITextView!

Sau đó mở file Main.storyboard ra, ở phía bên phải ngoài cùng, tìm tới phần Connections Inspector, bạn sẽ thấy các properties vừa mới được thêm vào list ở trong phần Outlets. Bạn thấy một hình tròn nhỏ phía bên phải của resultsTextView chứ, bạn giữ Control và kéo chuột từ hình tròn đó vào trong chỗ của Text View mà mình đã add vào View Controlelr trước đó. Bạn làm tương tự với 3 thuộc tính còn lại.

Tiếp theo chúng ta cần kết nối các sự kiện từ view đến các method trong view controller. Vẫn ở trong file ViewController.swift, chúng ta thêm 3 methods sau vào bất kỳ chỗ nào trong class:

    @IBAction func calculateTapped(sender : AnyObject) {

    }

    @IBAction func taxPercentageChanged(sender : AnyObject) {

    }

    @IBAction func viewTapped(sender : AnyObject) {

    }

Mở lại file Main.storyboard và chắc chắn rằng bạn đang chọn View Controller (Tip Calculator) ở trong Document Outline. Nhìn sang Connections Inspector, bạn sẽ thấy các methods mới được list ở trong phần Rêcived Actions. Bạn kéo chuột từ hình tròn bên phải calculateTapped vào button Calculate. 1 popup sẽ hiện ra, bạn chọn Touch Up Inside. Tiếp theo bạn thực hiện tương tự với 2 methods còn lại. taxPercentageChanged ứng với Value ChangedviewTapped ứng với Tap Gesture Recognizer ở trong Document Outline

Kết nối View Controller và Model

Mở file ViewController.swift và thêm 1 property cho model vào class và 1 method để cập nhật các UI

    let tipCalc = TipCalculatorModel(total: 33.25, taxPct: 0.06)

    func refreshUI() {
        totalTextField.text = String(format: "%0.2f", tipCalc.total)
        taxPctSlider.value = Float(tipCalc.taxPct) * 100.0
        taxPctLabel.text = "Tax Percentage (\(Int(taxPctSlider.value))%)"
        resultsTextView.text = ""
    }

Tiếp theo bạn gọi method refreshUI ở cuôi bên trong method viewDidLoad. Chúng ta cũng cần xây dựng taxPercentageChangedviewTapped như bên dưới

    @IBAction func taxPercentageChanged(sender : AnyObject) {
        tipCalc.taxPct = Double(taxPctSlider.value) / 100.0
        refreshUI()
    }

    @IBAction func viewTapped(sender : AnyObject) {
        totalTextField.resignFirstResponder()
    }

Chỉ còn lại method calculateTapped

    @IBAction func calculateTapped(sender : AnyObject) {
        tipCalc.total = Double((totalTextField.text as NSString).doubleValue)
        let possibleTips = tipCalc.returnPossibleTips()
        var results = ""
        for (tipPct, tipValue) in possibleTips {
            results += "\(tipPct)%: \(tipValue)\n"
        }
        resultsTextView.text = results
    }

Đến đây các bạn có thể build và xem thành quả của mình rồi. Hi vọng các bạn có thể hiểu thêm về Swift qua ví dụ thực tế này. Các bạn có thể down source đầy đủ ở đây để tham khảo: Source Code TipCalculator


All Rights Reserved