iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 24
0
Software Development

利用Swift 4開發iOS App,Daily Work List系列 第 24

Daily Work List App - 24. Develop Photo Page Storyboard & View Controller 2

  • 分享至 

  • xImage
  •  

今天來完成PhotoPage剩下的部分,大部分東西都跟其他頁面類似,比較需要說道的是關於搜尋框,因此今天就來說明搜尋框的部分,文末會附上完成的PhotoViewController供參考喔

搜尋匡

這個頁面的是利用UISearchBar,因此Protocol要加入UISearchBarDelegate,另外再加入兩個陣列

// 儲存所有資料
var photoList: [Media] = [Media]()
// 顯示時使用的資料
var searchList: [Media] = [Media]()

在資料撈取的時候,兩個陣列都要加入喔!然後我們UITableView主要是看searchList,photoList是用來存取所有的資料,供當取消搜尋的時候,有資料還原的機會

@objc func reloadTableView() {
    photoList.removeAll()
    photoList.append(contentsOf: sqlManager.queryMediaByEventIdAndType(event_id: event_id, type: type))
    searchList.removeAll()
    searchList.append(contentsOf: self.photoList)
    
    self.photoTableView.reloadData()
    self.refreshControl.endRefreshing()
}

接著加入searchBar的對應功能,當搜尋匡有值的時候,我們要從photoList中查詢出相對應title名稱開頭相同的資料,加入serachList中,然後顯示出來,如果沒有值得話,就是所有的資料都要顯示,因此把photoList全部加入searchList中,就可以完全使用searchList的資料來操作TableView了

// 當搜尋匡內容文字異動時
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText == "" {
        // 當搜尋匡內容為空時,查詢全部
        self.searchList.append(contentsOf: self.photoList)
    } else {
        // 清空搜尋陣列
        self.searchList.removeAll()
        for photo in self.photoList {
            // 將title的名稱起始相同的資料加入
            if photo.title.hasPrefix(searchText) {
                self.searchList.append(photo)
            }
        }
    }
    // 刷新tableView 数据显示
    self.photoTableView.reloadData()
}
// when search bar button be clicked
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    // 當使用者點選搜尋匡時,開啟鍵盤
    searchBar.resignFirstResponder()
}
// when user click the cancel button
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    // 清空查詢匡文字
    searchBar.text = ""
    searchBar.endEditing(true)
    // 查詢陣列為全部
    self.searchList.removeAll()
    self.searchList.append(contentsOf: self.photoList)
    self.photoTableView.reloadData()
}

這樣就完成囉!圖片如下
https://ithelp.ithome.com.tw/upload/images/20181024/20111916ZTXNXcnmmA.png

https://ithelp.ithome.com.tw/upload/images/20181024/20111916fcqExYMC63.png https://ithelp.ithome.com.tw/upload/images/20181024/20111916hDcnZhOmph.png

PhotoViewController.swift的完整程式碼如下:

import Foundation
import UIKit

class PhotoViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UISearchBarDelegate, UITextFieldDelegate, UITextViewDelegate {
    
    let sqlManager = (UIApplication.shared.delegate as! AppDelegate).sqlManager
    
    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var photoTableView: UITableView!
    
    var photoList: [Media] = [Media]()
    var searchList: [Media] = [Media]()
    let cellIdentifier: String = "PhotoTableViewCell"
    var refreshControl: UIRefreshControl!
    var event_id: Int64!
    let type: Int = 0
    let path: String = "Photo/"
    let formatter = DateFormatter()
    let photoPiker = UIImagePickerController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        formatter.dateFormat = "yyyyMMddHHmmssSSSS"
        
        // Refresh Control
        refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: #selector(reloadTableView), for: UIControlEvents.valueChanged)
        photoTableView.addSubview(refreshControl)
        
        reloadTableView()
    }
    
    @objc func reloadTableView() {
        photoList.removeAll()
        photoList.append(contentsOf: sqlManager.queryMediaByEventIdAndType(event_id: event_id, type: type))
        searchList.removeAll()
        searchList.append(contentsOf: self.photoList)
        
        self.photoTableView.reloadData()
        self.refreshControl.endRefreshing()
    }
    
    // get the count of elements you are going to display in your tableView
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.searchList.count
    }
    
    // assign the values in your array variable to a cell
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! PhotoTableViewCell
        cell.id = self.searchList[indexPath.row].id
        cell.title.text = self.searchList[indexPath.row].title
        cell.title.tag = Int(self.searchList[indexPath.row].id)
        cell.detail.text = self.searchList[indexPath.row].detail
        cell.detail.tag = Int(self.searchList[indexPath.row].id)
        
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let filePath = documentsURL.appendingPathComponent(self.searchList[indexPath.row].path).path
        if FileManager.default.fileExists(atPath: filePath) {
            cell.photo.image = UIImage(contentsOfFile: filePath)
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, editActionsForRowAt: IndexPath) -> [UITableViewRowAction]? {
        let delete = UITableViewRowAction(style: .normal, title: "Delete") { action, indexPath in
            do {
                let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                let filePath = documentsURL.appendingPathComponent(self.searchList[indexPath.row].path).path
                try FileManager.default.removeItem(atPath: filePath)
                self.sqlManager.deleteMediaById(id: self.searchList[indexPath.row].id)
                self.reloadTableView()
            } catch {
                // TODO
                print("\(error)")
            }
        }
        delete.backgroundColor = UIColor.red
        
        return [delete]
    }
    
    @IBAction func cancel(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        do {
            let documentsDirectory = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
            let dataPath = documentsDirectory.appendingPathComponent(path)!
            try FileManager.default.createDirectory(atPath: dataPath.path, withIntermediateDirectories: true)
            
            let fileName = "\(formatter.string(from: Date())).jpg"
            let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let fileURL = documentsURL.appendingPathComponent(path + fileName)
            print(fileURL)
            
            // 取得編輯後的圖片(原圖用UIImagePickerControllerOriginalImage)
            let image: UIImage = info[UIImagePickerControllerEditedImage] as! UIImage
            let imageData: Data = UIImageJPEGRepresentation(image, 1)!
            try imageData.write(to: fileURL, options: .atomic)
            
            sqlManager.insertMedia(event_id: event_id, type: type, title: fileName, detail: nil, path: path + fileName)
        } catch {
            // TODO
            print("\(error)")
        }
        
        // update the button label text
        self.reloadTableView()
        
        photoPiker.dismiss(animated: true, completion: nil)
    }
    
    @IBAction func add(_ sender: UIBarButtonItem) {
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
            photoPiker.sourceType = .photoLibrary
            photoPiker.delegate = self
            photoPiker.allowsEditing = true
            self.present(photoPiker, animated: true, completion: nil)
        }
    }
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText == "" {
            // 當搜尋匡內容為空時,查詢全部
            self.searchList.append(contentsOf: self.photoList)
        } else {
            // 清空搜尋陣列
            self.searchList.removeAll()
            for photo in self.photoList {
                // 將title的名稱起始相同的資料加入
                if photo.title.hasPrefix(searchText) {
                    self.searchList.append(photo)
                }
            }
        }
        // 刷新tableView 数据显示
        self.photoTableView.reloadData()
    }
    
    // when search bar button be clicked
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
    }
    
    // when user click the cancel button
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        // 清空查詢匡文字
        searchBar.text = ""
        searchBar.endEditing(true)
        // 查詢陣列為全部
        self.searchList.removeAll()
        self.searchList.append(contentsOf: self.photoList)
        self.photoTableView.reloadData()
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if textField.text! == "" {
            confirmAlert("title cannot be null!")
            return false
        } else {
            self.view.endEditing(true)
            sqlManager.updateMediaTitleById(id: Int64(textField.tag), title: textField.text!)
            return true
        }
    }
    
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if text == "\n" {
            sqlManager.updateMediaDetailById(id: Int64(textView.tag), detail: textView.text)
            textView.resignFirstResponder()
            return false
        }
        return true
    }
    
    @objc func confirmAlert(_ message: String) {
        let alertViewController = UIAlertController(title: "Warn!", message: message, preferredStyle: .alert)
        alertViewController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Default action"), style: .default, handler: { _ in
        }))
        self.present(alertViewController, animated: true, completion: nil)
    }
}

上一篇
Daily Work List App - 23. Develop Photo Page Storyboard & View Controller
下一篇
Daily Work List App - 25. Develop Video Page Storyboard & View Controller
系列文
利用Swift 4開發iOS App,Daily Work List31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言