gpt4 book ai didi

ios - UICollectionViewController 页脚在结束编辑后未正确重新定位自身

转载 作者:行者123 更新时间:2023-11-28 05:45:36 27 4
gpt4 key购买 nike

我有一个简单的 UICollectionViewController,它是一个带有固定到可见边界的页眉和页脚的部分。当我单击页脚中的 textField 时,页脚会自动在键盘上方设置动画,并且 collectionView 会滚动以显示单元格,否则这些单元格会像您预期的那样被键盘隐藏。但是,当我在键盘外单击一个,并通过调用 self.view.endEditing(true) 关闭它时,页脚和 collectionView 不会使用react,除非 collectionView 滚动到底部附近。如果 collectionView 滚动到底部附近,则页脚和 collectionView 会按预期进行动画处理。

如何强制页脚和 collectionView 每次都正确地设置动画?

在下图中,页眉为橙色,页脚为绿色,并且有 10 个红蓝交替的单元格。

实际行为(当键盘关闭时您没有滚动到 collectionView 底部附近时发生) actual behavior

Desired Behavior(当您在 collectionView 的底部或附近滚动时键盘消失时发生) desired behavior

我知道有一些方法可以在键盘出现和消失时使用通知来实现这一点,但我更愿意尽可能使用默认的 UICollectionViewController 行为。是否缺少某些配置或设置?

代码:新的单 View 应用程序。删除 StoryBoard 和 ViewController.swift。从信息 plist 文件中删除主要 Storyboard条目。

AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = CollectionViewController.init()

return true
}
}

CollectionViewController.swift

import UIKit

private let reuseIdentifier = "Cell"
private let collectionViewHeaderFooterReuseIdentifier = "MyHeaderFooterClass"

class CollectionViewController: UICollectionViewController {

init() {
let collectionViewFlowLayout = UICollectionViewFlowLayout.init()
collectionViewFlowLayout.sectionHeadersPinToVisibleBounds = true
collectionViewFlowLayout.sectionFootersPinToVisibleBounds = true
super.init(collectionViewLayout: collectionViewFlowLayout)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}

override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
self.collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
self.collectionView?.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)
self.collectionView?.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)

self.collectionView?.backgroundColor = UIColor.white

self.collectionView?.dataSource = self
self.collectionView?.delegate = self
}
}

// MARK: UICollectionViewDelegate
extension CollectionViewController {
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
DispatchQueue.main.async {
self.view.endEditing(true)
self.collectionViewLayout.invalidateLayout()
self.collectionView?.layoutIfNeeded()
}
}
}

// MARK: - UICollectionViewDataSource
extension CollectionViewController {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 10
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)

switch indexPath.row % 2 {
case 0:
cell.backgroundColor = UIColor.red
case 1:
cell.backgroundColor = UIColor.blue
default:
cell.backgroundColor = UIColor.gray
}

return cell
}

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier, for: indexPath)

if kind == UICollectionView.elementKindSectionHeader {
view.backgroundColor = UIColor.orange
}
else { //footer
view.backgroundColor = UIColor.green
}

return view
}
}

// MARK: - Collection View Flow Layout Delegate
extension CollectionViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 100)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 100)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 100)
}
}

我的页眉页脚类

import UIKit

class MyHeaderFooterClass: UICollectionReusableView {
let textField: UITextField = {
let view = UITextField.init()
view.placeholder = "enter text here"
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

override init(frame: CGRect) {
super.init(frame: frame)

self.addSubview(textField)
self.setNeedsUpdateConstraints()
}

override func updateConstraints() {
textFieldConstraints()
super.updateConstraints()
}

private func textFieldConstraints() {
NSLayoutConstraint(item: textField, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: textField, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: textField, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: textField, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0.0).isActive = true
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

最佳答案

来自文档:

func layoutIfNeeded()

Use this method to force the view to update its layout immediately.

func invalidateLayout()

This method invalidates the layout of the collection view itself andreturns right away.

解决方案:

查看您的代码,您已经在更新 collectionViewLayout。因此,您无需再次强制更新 collectionView。因此,只需单独删除 self.collectionView?.layoutIfNeeded() 即可解决您的问题。

如下更改代码:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
DispatchQueue.main.async {
self.view.endEditing(true)
self.collectionViewLayout.invalidateLayout()
//self.collectionView?.layoutIfNeeded()
}
}

关于ios - UICollectionViewController 页脚在结束编辑后未正确重新定位自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54893031/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com