iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 7
1
Software Development

iOS 三十天上架記帳 APP系列 第 7

Money Mom - 實作標籤輸入 Part 3

前言

在 Part 2 的時候,我們已經實作了大部分的功能了,接下來我們需要調整標籤輸入框的顯示方式,來呈現最好的使用者體驗。

Part 2 的介面如下:

最後紅色區塊的標籤輸入框,一直呈現相同大小,也導致即使標籤後面還有空位,紅色區塊卻依然我行我素的換行,所以我們這篇要來給他一點教訓。

監控標籤輸入框文字改變

為了在每次使用者輸入文字後,動態改變標籤輸入框的寬度,我們需要在每次使用者輸入字後,請 UICollectionView 重新計算寬度。

首先,我們要先修改之前加入的 TagTextFieldDelegate,新增一個方法:didChange(text:),這個方法會在標籤輸入框文字有更動時被呼叫,如下:

protocol TagTextFieldDelegate {
    func didAdd(tag: String)
    func didChange(text: String) // <---
}

然後在初始化 UITextField 時,就開始監控文字改變,如下:

class TagTextFieldCollectionViewCell: UICollectionViewCell {
    lazy var textField: UITextField = {
        var textField = UITextField()
        textField.delegate = self
        textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged) // <---
        return textField
    }()

    // ...略
}
extension TagTextFieldCollectionViewCell: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // ...略

        textField.text = ""
        delegate?.didChange(text: "") // <---

        return true
    }

    @objc func textFieldDidChange() {
        delegate?.didChange(text: textField.text ?? "") // <---
    }
}

如此一來,每次標籤輸入框的文字有改變,就會呼叫 Delegate 的 didChange(text:) 方法。

文字改變時,動態調整標籤輸入框寬度

首先我們先在 QuickCreateViewController 底下實作 TagTextFieldDelegate 的地方,加入 didChange(text:) 的方法實作,如下:

class QuickCreateViewController: UIViewController {
    // ...略

    var tags: [String] = []
    var tagTextFieldText = "" // <---

    // ...略
}
extension QuickCreateViewController: TagTextFieldDelegate {
    // ...略

    func didChange(text: String) {
        tagTextFieldText = text // <---
        tagCollectionView.collectionViewLayout.invalidateLayout() // <---
    }
}

一旦標籤輸入框文字改變,我們就先將改變後的文字記起來(方便後面計算寬度使用),然後再請 UICollectionView 重新計算寬度,如下:

extension QuickCreateViewController: UICollectionViewDelegateFlowLayout {
    // ...略

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if indexPath.row == tags.count {
            let cell = TagTextFieldCollectionViewCell() // <---
            cell.textField.text = tagTextFieldText // <---
            cell.textField.sizeToFit() // <---

            return CGSize(width: min(cell.textField.frame.width + cell.layoutMargins.left + cell.layoutMargins.right, tagCollectionView.frame.width / 2), height: 50) // <---
        } else {
            // ...略
        }
    }
}

跟標籤一樣,標籤輸入框的大小最寬只允許螢幕寬的一半,也就是 UICollectionView 的一半寬。

至此,我們就完成了超酷炫標籤輸入的大部分邏輯了,如下:

程式碼:GitHub

下一篇再把一些界面調整一下,就可以結束標籤輸入的系列啦!


上一篇
Money Mom - 實作標籤輸入 Part 2
下一篇
Money Mom - 實作標籤輸入 Part ∞
系列文
iOS 三十天上架記帳 APP30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言