iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
Mobile Development

ios 的小小實驗室 !系列 第 15

DAY 15 『 Realm 新增、修改、刪除 』Part3

昨天分享如何新增、修改、刪除、印出 Realm 資料庫的資料,以及讀取 Realm 資料庫的資料去更新 TableView

今天會介紹:

  1. Table View Cell
  2. UITableViewDelegate、UITableViewDataSource、UITextFieldDelegate

在專案底下 New Group / New File / 選 Cocoa Touch Class

在 MyTableViewCell 檔裡,分別加入各個物件的 @outlet
串連 Storyboard Cell 以及 MyTableViewCell

import UIKit

class MyTableViewCell: UITableViewCell {
    
    @IBOutlet weak var showName: UILabel!
    @IBOutlet weak var showAge: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }
}

extension ViewController: UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate{
    //tableView要顯示幾列
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return users.count
    }
    
    //cell裏面要顯示什麼
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
        // Cell contents setting
        cell.showName.text = users[indexPath.row].setuserName
        cell.showAge.text = users[indexPath.row].setuserAge
        tableView.deleteRows(at: [indexPath], with:.fade)
        return cell
    }
    // view 詢問有多少 section 要顯示
    func numberOfSections(in tableView: UITableView) -> Int { return 1 }
    
    //textField的限制
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
       var result = false
       if let text = textField.text, let range = Range(range, in: text) {
           let newText = text.replacingCharacters(in: range, with: string)
           // 最多輸入 10 個數值
           if newText.count < 11 {
            result = true
           }
       }
       return result
    }
}

由於 UITableViewDelegate、UITableViewDataSource、UITextFieldDelegate 是用 extension 的方式宣告
因此在 override func viewDidLoad() 底下需加上

tableView.delegate = self
tableView.dataSource = self

在 Storyboard 將 CollectionView 拉線到 View Controller,選擇 delegate & dataSource

拉完後就會呈現這樣

附上完整程式碼

//  Datas.swift

import UIKit
import Foundation
import RealmSwift
class Datas: Object {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    override static func primaryKey() -> String? {
        return "id"
    }
}
//  MyTableViewCell.swift

import UIKit
class MyTableViewCell: UITableViewCell {
    
    @IBOutlet weak var showName: UILabel!
    @IBOutlet weak var showAge: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}
//  ViewController.swift

import RealmSwift
import UIKit
struct SetUser {
    var setuserName : String?
    var setuserAge : String?
    init(setuserName: String, setuserAge:String){
        self.setuserName = setuserName
        self.setuserAge = setuserAge
    }
}
class ViewController: UIViewController {
    let realm = try! Realm()
    var users = [SetUser]()
    
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var ageTextField: UITextField!
    @IBOutlet weak var inputButton: UIButton!
    @IBOutlet weak var deleteTextField: UITextField!
    @IBOutlet weak var deleteButton: UIButton!
    @IBOutlet weak var fixTextField: UITextField!
    @IBOutlet weak var fixButton: UIButton!
    @IBOutlet weak var findTextField: UITextField!
    @IBOutlet weak var findButton: UIButton!
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        reloadData()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        print("fileURL: \(realm.configuration.fileURL!)")
        
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyBoard))
        self.view.addGestureRecognizer(tap)
    }

    @IBAction func inputData(_ sender: UIButton) {
        let input: Datas = Datas()
        if Int(ageTextField.text!) ?? 0 > 0 && (nameTextField.text != nil){
        input.name = nameTextField.text ?? ""
        input.age = Int(ageTextField.text!) ?? 0
        try! realm.write {realm.add(input)}
        }
        else{ alertTrigger();print("輸入的資料有誤!") }
        reloadData()
    }

    @IBAction func deleteData(_ sender: UIButton) {
        let delete = realm.objects(Datas.self)
        if Int(deleteTextField.text!) ?? 0 > 0 && Int(deleteTextField.text!)! < delete.count+1 {
            try! realm.write { realm.delete(delete[Int(deleteTextField.text!)!-1]) }
        }
        else{ alertTrigger();print("輸入值有誤!") }
        reloadData()
    }

    @IBAction func fixData(_ sender: UIButton) {
        let fixid = realm.objects(Datas.self)
        if (fixTextField.text != nil) && (fixid.count > 0){
            let fix: Datas = Datas()
            fix.id = "\(fixid[0].id)"
            fix.name = fixTextField.text!
            fix.age = fixid[0].age
            try! realm.write {realm.add(fix, update: .all)}
        }
        else{ alertTrigger();print("目前沒資料!") }
        reloadData()
    }

    @IBAction func findData(_ sender: UIButton) {
        let show = realm.objects(Datas.self)
        if Int(findTextField.text!) ?? 0 > 0 && Int(findTextField.text!)! < show.count+1 && show.count > 0{
            print("name:\(show[ Int(findTextField.text!)!-1].name),age:\(show[Int(findTextField.text!)!-1].age)")
        }
        else{ alertTrigger();print("輸入值有誤") }
    }

    func reloadData(){
        users = []
        let alluser = realm.objects(Datas.self)
        guard alluser.count > 0 else { tableView.reloadData(); print("nil"); return }
        for i in 1...alluser.count{
            users.append(SetUser(setuserName: alluser[i-1].name, setuserAge: String(alluser[i-1].age)))
        }
        tableView.reloadData()
    }

    func alertTrigger(){
        let alertController = UIAlertController(title: "提示", message: "請確認輸入的資料,按確認關閉!", preferredStyle: .alert)
        let confirmAction = UIAlertAction(title: "確認", style: .default, handler: nil)
        alertController.addAction(confirmAction)
        self.present(alertController, animated: true, completion: nil)
    }
    
    @objc func dismissKeyBoard() { self.view.endEditing(true) }
}

extension ViewController: UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate{
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return users.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
        cell.showName.text = users[indexPath.row].setuserName
        cell.showAge.text = users[indexPath.row].setuserAge
        tableView.deleteRows(at: [indexPath], with:.fade)
        return cell
    }
    func numberOfSections(in tableView: UITableView) -> Int { return 1 }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
       var result = false
       if let text = textField.text, let range = Range(range, in: text) {
           let newText = text.replacingCharacters(in: range, with: string)
           if newText.count < 11 {
            result = true
           }
       }
       return result
    }
}

這樣就完成啦!明天會有新的實作分享,敬請期待!


上一篇
DAY 14 『 Realm 新增、修改、刪除 』Part2
下一篇
DAY 16 『 改用 xib 進行界面創作 』
系列文
ios 的小小實驗室 !30

尚未有邦友留言

立即登入留言