前提・実現したいこと
Twitterの投稿画面のようなものを作っています。
キーボードが表示されたときにはキーボードの上に投稿ボタンなどを配置したいと考えています。
画面遷移時にTextViewにフォーカスを当てるようにしているのですが、TextViewを2回タップするとボタンなどを配置しているViewのレイアウトが変わってしまうのでそれを防ぎたいです。
発生している問題
《ボタンなどを配置しているViewについて》 キーボードの上に表示させる投稿ボタンなどのUIパーツを配置するためのView(keyboardBackView)を画面底辺に設置しています。 画面遷移のタイミングでキーボードが表示されるので(常時)、keyboardBackViewの高さにキーボードの高さを加えて、キーボード上に表示されるように調整しています。 このときにTextViewにフォーカスがあたっている状態なので、TextViewを2回タップするとkeyboardBackViewの高さが変わってしまいます。(上に高さが加わる) タップしてもさらに高さを加えないようにしたいです。
該当のソースコード
swift
1import UIKit 2 3class PostViewController: UIViewController, UIScrollViewDelegate { 4 5 @IBOutlet weak var textView: UITextView! 6 @IBOutlet weak var wordCountLabel: UILabel! 7 fileprivate let placeholder: String = "テキストを入力" // プレースホルダ 8 fileprivate var maxWordCount: Int = 100 // 最大文字数 9 @IBOutlet weak var keyboardBackViewConstraint: NSLayoutConstraint! 10 @IBOutlet weak var keyboardBackView: UIView! 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 self.textView.delegate = self 16 17 if textView.text.isEmpty { 18 textView.textColor = .darkGray 19 textView.text = placeholder 20 self.wordCountLabel.text = "300/300" 21 } 22 23 NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) 24 25 // 遷移時にtextViewにフォーカスをあてる 26 self.textView.becomeFirstResponder() 27 } 28 29 override func viewDidLayoutSubviews() { 30 self.keyboardBackView.addBorder(width: 0.5, color: UIColor.black, position: .top) 31 } 32 33 @objc func keyboardWillShow(notification: NSNotification) { 34 if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { 35 36 let suggestionHeight = self.keyboardBackViewConstraint.constant + keyboardSize.height 37 self.keyboardBackViewConstraint.constant = suggestionHeight 38 } 39 } 40 41 42 @IBAction func cancelButtonTapped(_ sender: Any) { 43 self.dismiss(animated: true, completion: nil) 44 45 } 46 47} 48 49extension PostViewController: UITextViewDelegate { 50 51 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { 52 let existingLines = textView.text.components(separatedBy: .newlines) 53 let newLines = text.components(separatedBy: .newlines) 54 let linesAfterChange = existingLines.count + newLines.count - 1 55 return linesAfterChange <= 300 && textView.text.count + (text.count - range.length) <= maxWordCount 56 } 57 58 func textViewDidChange(_ textView: UITextView) { 59 let existingLines = textView.text.components(separatedBy: .newlines) 60 if existingLines.count <= 300 { 61 self.wordCountLabel.text = "(maxWordCount - textView.text.count)/300" 62 } 63 } 64 65 func textViewDidBeginEditing(_ textView: UITextView) { 66 if textView.text == placeholder { 67 textView.text = nil 68 textView.textColor = .darkText 69 } 70 } 71 72 func textViewDidEndEditing(_ textView: UITextView) { 73 if textView.text.isEmpty { 74 textView.textColor = .darkGray 75 textView.text = placeholder 76 } 77 } 78} 79 80enum BorderPosition { 81 case top 82 case left 83 case right 84 case bottom 85} 86 87extension UIView { 88 /// 特定の場所にborderをつける 89 /// 90 /// - Parameters: 91 /// - width: 線の幅 92 /// - color: 線の色 93 /// - position: 上下左右どこにborderをつけるか 94 func addBorder(width: CGFloat, color: UIColor, position: BorderPosition) { 95 96 let border = CALayer() 97 98 switch position { 99 case .top: 100 border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: width) 101 border.backgroundColor = color.cgColor 102 self.layer.addSublayer(border) 103 case .left: 104 border.frame = CGRect(x: 0, y: 0, width: width, height: self.frame.height) 105 border.backgroundColor = color.cgColor 106 self.layer.addSublayer(border) 107 case .right: 108 print(self.frame.width) 109 110 border.frame = CGRect(x: self.frame.width - width, y: 0, width: width, height: self.frame.height) 111 border.backgroundColor = color.cgColor 112 self.layer.addSublayer(border) 113 case .bottom: 114 border.frame = CGRect(x: 0, y: self.frame.height - width, width: self.frame.width, height: width) 115 border.backgroundColor = color.cgColor 116 self.layer.addSublayer(border) 117 } 118 } 119}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/15 14:54 編集
2021/02/18 05:31