看板 KnucklesNote
作者 標題 [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.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 加上通知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
)
在鍵盤出現前執行 self.keyboardWillShow(_:)
在鍵盤關閉前執行 self.keyboardWillHide(_:)
加上成員函數 viewWillDisappear()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
在編輯器關閉時停止通知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 與下方的距離設為鍵盤的高度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
}
將 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 往下捲動let bottomOffset = CGPoint(x: 0, y: self.scrollView.contentSize.height - self.scrollView.bounds.size.height)
self.scrollView.setContentOffset(bottomOffset, animated: true)
}
將「看板:」與「標題:」隱藏在上方
執行結果
要從文章列表傳值到編輯器時
例如要傳看板名稱 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
}
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 累積人氣: 405
回列表(←)
分享