顯示廣告
隱藏 ✕
看板 KnucklesNote
作者 Knuckles (站長 那克斯)
標題 [Xcode][Swift3] 新增文章編輯器
時間 2017-05-02 Tue. 16:25:51


使用 ScrollView 來建立一個文章編輯器
用來編輯多行文章的 Text View 要能夠隨螢幕大小調整
虛擬鍵盤跳出來時 Scroll View 要能縮小高度到可顯示的範圍

拉一個新的 Navigation Controller,將附帶的 Table View Controller 刪除
再拉一個新的 View Controller
[圖]


加上 Segue 連結兩個 Controller
按著 Ctrl 將 Navigation Controller 拉到 View Controller
跳出的選單選擇「root view controller」
[圖]


在文章列表頁的右上方加上發表文章的按鈕
按著 Ctrl 將按鈕拉至新的 Navigation Controller
跳出的選單選擇「Present Modally」
[圖]



因為使用了新 Navigation Controller
開啟這頁後,左上角不會自動出現「回上頁」的按鈕
要自己加上去,拉一個 Bar Button Item 到左上角
Title 輸入「取消」
[圖]



新增一個類別檔案 EditorViewController.swift
Subclass of: ViewController
設定新的 ViewController 的自訂類別為 EditorViewController

使用 AssisantEditor 拉一個 @IBAction 到 EditorViewController.swift
名稱輸入「cancel」,將產生的 @IBAction 改為
    @IBAction func cancel(_ sender: Any) {
        // 先關掉虛擬鍵盤
        self.view.endEditing(true)

        let alert = UIAlertController(title: "取消編輯", message: "確定要不存檔離開嗎?", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil))
        alert.addAction(UIAlertAction(title: "確定", style: .default, handler: { action in
            self.dismiss(animated: true, completion: nil)
        }))
        self.present(alert, animated: true, completion: nil)
    }
點了取消按鈕後,會跳出確認對話框,點了確定後,
執行 self.dismiss(animated:completion:) 即可關閉目前這一頁
回到之前的頁面


在新的 View Controller 中拉一個 Scroll View
調整成顯示範圍的大小,加上四個方向皆為 0 的 Constraints
[圖]


在 Scroll View 中再拉一個 View
調整成與 Scroll View 的大小,加上四個方向皆為 0 的 Constraints
[圖]

然後將這個 View 改名為 Content View

在 Scroll View 中的 View,必需要有六個 Constraints 才行
還缺長跟寬的,但長跟寬不是固定的數值,必需要與顯示範圍一樣大

先取消勾選 Navigation Bar 的 Translucent 屬性
避免顯示範圍覆蓋到 Navigation Bar 的位置
[圖]


在左邊的 Document Outline
按著 Ctrl 將 Scroll View 裡面的 View 拉到 Scroll View
選擇「Equal Widths」,然後再拉一次選擇「Equal Heights」
[圖]

這樣 Scroll View 裡的 View 就會保持和 Scroll View 一樣大

在 Scroll View 裡的 View 加上想要的 Label 與 輸入框
其中 Text View 要加上四個方向為 0 的 Constraints
[圖]



執行看看,在 Text View 中輸入很多行的文字後
發現跳出來的虛擬鍵盤會蓋住後面的文字內容
必需要在虛擬鍵盤出現時,將 Scroll View 的高度縮小才行

找出 Scroll View 與下方邊界的 Constraint
[圖]


使用 Assistant Editor 將這個 Constraint
在 EditorViewController.swift 中加上一個 @IBLayout
名稱輸入「scrollViewBottomConstraint」
要使用程式將這個 Constraint 的值設為鍵盤的高度

找出 Content View 高度的 Constraint
[圖]


一樣使用 Assistant Editor 拉至 EditorViewController.swift 中
建立 @IBLayout,名稱輸入「contentViewHeight」
要在鍵盤出現時,將 Content View 的高度設定為比 Scroll View 多 60
也就是上面「看板:」與「標題:」的高度
這樣就可以往下捲動,將「看板:」與「標題:」隱藏了


編輯 EditorViewController.swift

加上成員函數 viewWillAppear()
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: #selector(self.keyboardWillShow(_:)),
            name: UIKeyboardWillShowNotification,
            object: nil
        )
        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: #selector(self.keyboardWillHide(_:)),
            name: UIKeyboardWillHideNotification,
            object: nil
        )
使用 NSNotificationCenter 加上通知
在鍵盤出現前執行 self.keyboardWillShow(_:)
在鍵盤關閉前執行 self.keyboardWillHide(_:)

加上成員函數 viewWillDisappear()
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
在編輯器關閉時停止通知

加上兩個成員函數
    // MARK: - Keyboard Action

    func keyboardWillShow(_ notification: NSNotification) {
        guard let value = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue else { return }
        let keyboardHeight = value.cgRectValue.height

        self.scrollViewBottomConstraint.constant = keyboardHeight
        self.contentViewHeight.constant = 60

        self.view.layoutIfNeeded()
    }

    func keyboardWillHide(_ notification: NSNotification) {
        self.scrollViewBottomConstraint.constant = 0
        self.contentViewHeight.constant = 0
    }
當鍵盤顯示時,將 Scroll View 與下方的距離設為鍵盤的高度
將 Content View 的高度設為比 Scroll View 多 60

當鍵盤隱藏時,再將設定改回來


如果想要在點擊 Text View 時,Scroll View 自動往下捲動,
將「看板:」與「標題:」隱藏在上方的話

使用 Assistant Editor 將 Scroll View 拉至 EditorViewController.swift 中
建立 @IBLayout,名稱輸入「scrollView」

按著 Ctrl 將 Text View 拉至 View Controller
選擇 delegate
[圖]



編輯 EditorViewController.swift

將類別加上繼承 UITextViewDelegate
class EditorViewController: UIViewController, UITextViewDelegate {

加上 delegate 函數 textViewDidBeginEditing()
    func textViewDidBeginEditing(_ textView: UITextView) {
        let bottomOffset = CGPoint(x: 0, y: self.scrollView.contentSize.height - self.scrollView.bounds.size.height)
        self.scrollView.setContentOffset(bottomOffset, animated: true)
    }
在點擊了 Text View 後,Scroll View 往下捲動
將「看板:」與「標題:」隱藏在上方

執行結果
[圖]



要從文章列表傳值到編輯器時

例如要傳看板名稱 boardName 過去

在 EditorViewController 新增成員變數 boardName

點選文章列表連至 EditorViewController 的 Segue
設定 Identifier 為「Post」

修改文章列表的成員函數 prepare(for:sender:) 加上
        if segue.identifier == "Post" {
            let navigationController = segue.destination as! UINavigationController
            let editorViewController = navigationController.topViewController as! EditorViewController

            editorViewController.boardName = self.boardName
        }


點擊非輸入區的時候隱藏鍵盤

拉一個 Tap Gesture Recognizer 到 root View
[圖]


使用 Assistant Editor 將 Tap Gesture Recognizer 建立一個 @IBAction
名稱輸入「hideKeyboard」

在建立的 @IBAction 函數 hideKeyboard() 裡加上
        self.view.endEditing(true)

執行看看,先點一下輸入框讓虛擬鍵盤跳出來
再點一下上方的「看板:」或「標題:」,虛擬鍵盤就會關閉了


--
※ 作者: Knuckles 時間: 2017-05-02 16:25:51
※ 編輯: Knuckles 時間: 2017-05-06 23:41:46
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 398 
分享網址: 複製 已複製
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇