当键盘出现 swift 4.2 时 UICollectionViewCell 改变高度

Posted

技术标签:

【中文标题】当键盘出现 swift 4.2 时 UICollectionViewCell 改变高度【英文标题】:UICollectionViewCell changes height when keyboard appears swift 4.2 【发布时间】:2019-03-14 19:48:52 【问题描述】:

我一直在开发一个具有 UICollectionView 的应用程序,该应用程序的工作方式类似于主屏幕,而 UICollectionViewCells 充当不同的页面(水平滚动)。我在每个单元格上添加了一个文本字段进行编辑,但是当我单击文本字段时,当键盘出现时,单元格的高度会扩展。当键盘隐藏时,单元格高度保持扩展。我一直在寻找这个问题的答案,但我还没有找到有效的解决方案。

我尝试过使布局无效,将 translatesAutoresizingMaskIntoConstraints 设置为 false,并直接将内容偏移设置为零。这些选项都没有解决问题。

下面是我的代码:

private let reuseIdentifier = ["Cell1", "Cell2", "Cell3", "Cell4", "Cell5"]

let navi_btn_array: [UIButton] = [navi_home_btn, navi_gavel_btn, navi_orders_btn, navi_profile_btn, navi_lightning_btn]
var collectionView: UICollectionView = 
    var layout = UICollectionViewFlowLayout();
    layout.sectionInset = UIEdgeInsets.zero
    var cv = UICollectionView(frame: .zero, collectionViewLayout: layout);
    cv.autoresizesSubviews = false
    cv.contentInset = UIEdgeInsets.zero
    cv.translatesAutoresizingMaskIntoConstraints = false;
    return cv;
();

class MainCVC: UICollectionViewController,UICollectionViewDelegateFlowLayout, CLLocationManagerDelegate, UITextFieldDelegate 
    override func viewDidLoad() 
        super.viewDidLoad()



        collectionView?.register(SimpleDispensaryPage_Cell.self, forCellWithReuseIdentifier: reuseIdentifier[0])
        collectionView?.delegate = self
        collectionView?.dataSource = self
        collectionView?.isPagingEnabled = true

        let nc:NotificationCenter = NotificationCenter.default
        nc.addObserver(self, selector: #selector(keyboardDidShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
        nc.addObserver(self, selector: #selector(keyboardDidHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
    

    @objc func keyboardDidShow(notification: Notification)

        collectionViewLayout.invalidateLayout()
        collectionView?.contentOffset.y = 0


    
    @objc func keyboardDidHide(notification: Notification)

        collectionViewLayout.invalidateLayout()
        collectionView?.contentOffset.y = 0

    



    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 5

    
    override func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1

    

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 


            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier[0], for: indexPath)
            cell.backgroundColor = Custom_Colors.color_pine.withAlphaComponent(0.5)
            var txt_fld = UITextField()
            txt_fld.frame = CGRect(x: 0, y: 50, width: 100, height: 50)
            cell_label.text = "Placeholder #"+String(indexPath.item)
            cell_label.textAlignment = .center
            cell.addSubview(cell_label)
            return cell
        
    


运行时我也收到此错误:

2019-03-14 11:41:20.770799-0700 app[57379:5390785] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
2019-03-14 11:41:20.771043-0700 app[57379:5390785] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7fda15c13f40>, and it is attached to <UICollectionView: 0x7fda1706f000; frame = (0 0; 375 730.8); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x600000447bc0>; layer = <CALayer: 0x600000437720>; contentOffset: 8, -38.333333333333336; contentSize: 1891, 579; adjustedContentInset: 0, 0, 151.79999999999995, 0> collection view layout: <UICollectionViewFlowLayout: 0x7fda15c13f40>.
2019-03-14 11:41:20.771245-0700 app[57379:5390785] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.

【问题讨论】:

在keyboardDidShow和keyboardDidHide方法中改变y的偏移值。 我在上面的代码中是否设置错误?这也有助于保持原来的高度吗? 【参考方案1】:

这里有一些奇怪的设置。我建议进行一些更改:

1 - 永远不要在 collectionView(_, cellForItemAt ...) 中添加子视图。这将导致每次重复使用单元格时都会进行多次添加。子视图应由单元格添加(最好在创建时添加)。

2 - 删除 cv.autoresizesSubviews = falsecv.translatesAutoresizingMaskIntoConstraints = false

3 - 如果您想为单元格设置固定大小,您可以设置 layout.delegate = self 并实现以下方法:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
  return CGSize(width: screenWidth, height: screenHeight)

4 - 如果你真的只想要几个页面,为什么不使用 UIPageViewController?

【讨论】:

我确实想出了如何更正尺寸,但这实际上是一种更简洁的方法。谢谢!

以上是关于当键盘出现 swift 4.2 时 UICollectionViewCell 改变高度的主要内容,如果未能解决你的问题,请参考以下文章

当键盘出现Swift时,使用文本字段和按钮向上移动视图

Swift:当键盘出现时如何让视图控制器滚动到文本字段

当键盘出现在swift中时滚动UITextView

当键盘出现在 Swift 中时 UITextField 向上移动

UITextField 的键盘不会出现在 Swift 中的第一次点击时

当我在 swift 中单击单元格中的文本字段时,键盘没有出现