键盘在UICollectionViewController中断布局
我有一个水平的UICollectionViewController,其中每个单元格包含单元格底部的UITextView。 当我在UITextView里面点击时,键盘出现时,CollectionView的高度减少了260点(我注意到它是键盘的高度),然后增加了130点,因此最终的高度比预期的要低130点。
你有什么想法为什么框架以这种方式改变?
我在下面列出了最相关的部分,或者您可以在这里找到测试项目:https://github.com/johntiror/testAutomaticPush/tree/master
UIViewController(简单地启动CollectionViewController):
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let layout = UICollectionViewFlowLayout()
layout.itemSize = view.bounds.size
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
let fsPicVC = CollectionViewController(collectionViewLayout: layout)
self.present(fsPicVC, animated: true) { }
}
}
CollectionViewController:
class CollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView!.register(CollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
return cell
}
}
非常感谢
首先,我必须给我的两分钱,故事板很棒:)
您可能不想为此用例使用CollectionViewController。 如果你决定使用它,我也发布了另一个答案。 这是将CollectionView移动到ViewController的最快捷方式。 这解决了您的问题,但不考虑自动布局。
1)在ViewController中替换这些行:
let fsPicVC = CollectionViewController(collectionViewLayout: layout)
self.present(fsPicVC, animated: true) { }
同
let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.dataSource = self
view.addSubview(collectionView)
2)将其添加到ViewController的底部(在ViewController类之外):
extension ViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
// Configure the cell
return cell
}
}
最后,您可以删除CollectionViewController,因为它现在已被替换。
PS您也可能想要1)扩展ViewController以符合UICollectionViewDelegateFlowLayout和2)使collectionView全局。
如果你想使用CollectionViewController,这里有一个可能的解决方案(如果你想切换到一个通用的ViewController,请参阅我的其他答案)。
将以下内容添加到您的CollectionViewController类中:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Try commenting out this line to see the animation. It's included so the user doesn't see the fade effect
collectionView?.backgroundColor = UIColor.orange
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
func keyboardWillChangeFrame(notification: NSNotification) {
guard let info = notification.userInfo else {return}
guard let keyboardFrameEndValue = info[UIKeyboardFrameEndUserInfoKey] as? NSValue else {return}
let keyboardFrameEnd = keyboardFrameEndValue.cgRectValue
var itemSize = view.bounds.size
itemSize.height = keyboardFrameEnd.origin.y
guard let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout else {return}
layout.itemSize = itemSize
collectionView?.setCollectionViewLayout(layout, animated: true)
}
演示链接:https://github.com/harshilkotecha/UIScrollViewWhenKeyboardAppearInSwift3
当你有多个textview时,如此最好的解决方案非常困难 - >
第1步:授权给UITextFieldDelegate
class ScrollViewController: UIViewController,UITextFieldDelegate {
第2步:创建新的IBOutlet,但不要与故事板中的任何文本字段连接。
// get current text box when user Begin editing
@IBOutlet weak var activeTextField: UITextField?
第3步:当用户关注文本字段对象传递引用并存储在activeTextField中时,编写这两种方法。
// get current text field
func textFieldDidBeginEditing(_ textField: UITextField)
{
activeTextField=textField;
}
func textFieldDidEndEditing(_ textField: UITextField)
{
activeTextField=nil;
}
第4步:在viewdidload() setNotificationKeyboard中设置通知
override func viewWillAppear(_ animated: Bool) {
// call method for keyboard notification
self.setNotificationKeyboard()
}
// Notification when keyboard show
func setNotificationKeyboard () {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: .UIKeyboardWillHide, object: nil)
}
第5步:两种键盘出现和消失的方法。
func keyboardWasShown(notification: NSNotification)
{
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height+10, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.activeTextField
{
if (!aRect.contains(activeField.frame.origin))
{
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
}
// when keyboard hide reduce height of scroll view
func keyboardWillBeHidden(notification: NSNotification){
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0,0.0, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
}
链接地址: http://www.djcxy.com/p/96231.html