看板 KnucklesNote
作者 標題 [Xcode][Swift3] 新增文章編輯器
時間 2017-05-02 Tue. 16:25:51
使用 ScrollView 來建立一個文章編輯器
用來編輯多行文章的 Text View 要能夠隨螢幕大小調整
虛擬鍵盤跳出來時 Scroll View 要能縮小高度到可顯示的範圍
拉一個新的 Navigation Controller,將附帶的 Table View Controller 刪除
再拉一個新的 View Controller
![[圖]](http://i.imgur.com/KESIQZx.png)
加上 Segue 連結兩個 Controller
按著 Ctrl 將 Navigation Controller 拉到 View Controller
跳出的選單選擇「root view controller」
![[圖]](http://i.imgur.com/Nlduavq.png)
在文章列表頁的右上方加上發表文章的按鈕
按著 Ctrl 將按鈕拉至新的 Navigation Controller
跳出的選單選擇「Present Modally」
![[圖]](http://i.imgur.com/s4Gq7PT.png)
因為使用了新 Navigation Controller
開啟這頁後,左上角不會自動出現「回上頁」的按鈕
要自己加上去,拉一個 Bar Button Item 到左上角
Title 輸入「取消」
![[圖]](http://i.imgur.com/iuQnpEx.png)
新增一個類別檔案 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
![[圖]](http://i.imgur.com/oSoOpN0.png)
在 Scroll View 中再拉一個 View
調整成與 Scroll View 的大小,加上四個方向皆為 0 的 Constraints
![[圖]](http://i.imgur.com/eCixySr.png)
然後將這個 View 改名為 Content View
在 Scroll View 中的 View,必需要有六個 Constraints 才行
還缺長跟寬的,但長跟寬不是固定的數值,必需要與顯示範圍一樣大
先取消勾選 Navigation Bar 的 Translucent 屬性
避免顯示範圍覆蓋到 Navigation Bar 的位置
![[圖]](http://i.imgur.com/YnFIqXY.png)
在左邊的 Document Outline
按著 Ctrl 將 Scroll View 裡面的 View 拉到 Scroll View
選擇「Equal Widths」,然後再拉一次選擇「Equal Heights」
![[圖]](http://i.imgur.com/bYmXmMk.png)
這樣 Scroll View 裡的 View 就會保持和 Scroll View 一樣大
在 Scroll View 裡的 View 加上想要的 Label 與 輸入框
其中 Text View 要加上四個方向為 0 的 Constraints
![[圖]](http://i.imgur.com/7AxnHbZ.png)
執行看看,在 Text View 中輸入很多行的文字後
發現跳出來的虛擬鍵盤會蓋住後面的文字內容
必需要在虛擬鍵盤出現時,將 Scroll View 的高度縮小才行
找出 Scroll View 與下方邊界的 Constraint
![[圖]](http://i.imgur.com/pV4BB34.png)
使用 Assistant Editor 將這個 Constraint
在 EditorViewController.swift 中加上一個 @IBLayout
名稱輸入「scrollViewBottomConstraint」
要使用程式將這個 Constraint 的值設為鍵盤的高度
找出 Content View 高度的 Constraint
![[圖]](http://i.imgur.com/Ta3tFAS.png)
一樣使用 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
![[圖]](http://i.imgur.com/7ia8WSl.png)
編輯 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)
}
將「看板:」與「標題:」隱藏在上方
執行結果
![[圖]](http://i.imgur.com/bv1v8dx.png)
要從文章列表傳值到編輯器時
例如要傳看板名稱 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
![[圖]](http://i.imgur.com/X6I7ujy.png)
使用 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
回列表(←)
分享