为什么 IQKeyboardManager 不滚动我的 UITableView 以使我的自定义单元格的文本字段可见
Why doesn't IQKeyboardManager scroll my UITableView to make my custom cell's textfield visible
这是我目前得到的结果(不需要的):https://vimeo.com/459984986.
这是我使用变通方法得到的结果(几乎是我想要的):https://vimeo.com/459986233.
关于我的问题的总结如下:(1)我已经安装了“IQKeyboardManagerSwift”cocoapod,(2) 我的 UITableViewController 中有一个自定义单元格,它是一个 FolingCell(另一个 cocoapod)并且包含一个文本字段,当我点击内部时 (3)文本字段,我希望视图自动向上滚动以使文本字段可见(在键盘上方),这应该由 IQKeyboardManager 自动处理(是的,我添加了“启用" 我的 AppDelegate 中的代码)。
如上面“不需要的”结果视频所示,视图似乎试图滚动但最终只是上下抖动 在键盘向上滑动并不希望地覆盖文本字段时,稍微结束在原始位置之前。
此外,我发现我不想接受的小“解决方法”是将以下行添加到文本字段的 IBAction editingDidEnd outlet/action 函数中:“ sender.becomeFirstResponder()”。在我 iPhone 上更新到 XCode 12 和 iOS 14 之前,我 运行 并测试我的应用程序,我不必为“.becomeFirstResponder()”操心或“.resignResponder()”,因为那是 IQKeyboardManager 自动执行的操作。现在,添加上述代码行允许 UITableViewController 将视图移动到键盘上方。 但是, 如果你仔细观察,它位于键盘顶部的文本字段,这显然不是 IQKeyboardManager 因为 IQKeyboardManager 在文本字段和键盘之间的默认偏移量为 CGFloat(10)。
我认为 代码的相关部分 是我的 自定义单元格 (称为“SavedImageFoldingImageCell”),因为那是我创建文本字段的地方有问题和我的 UITableViewController(称为“SavedImageTableViewController”)。
拜托,你能提供的任何帮助、建议和忠告都会对我有很大帮助,我将不胜感激。谢谢!
是的,我的代码看起来很糟糕,因为我没有适当的 training/education 编码或一般编码的最佳实践。那里的建议也将不胜感激!如果您发现我可以缩短和组织代码的方法,请务必泄露您的秘密!
自定义单元格代码:
import UIKit
import FoldingCell
import LGButton
import TextFieldEffects
import SCLAlertView
class SavedImageFoldingImageCell: FoldingCell, UITextFieldDelegate {
// CLOSED
@IBOutlet weak var enterAGreetingLabelClosed: UILabel!
@IBOutlet weak var savedImageView1Closed: UIImageView!
@IBOutlet weak var savedImageView2Closed: UIImageView!
@IBOutlet weak var openCellButton: LGButton!
// OPEN
@IBOutlet weak var confirmLabelOpen: UILabel!
@IBOutlet weak var englishLabelOpen: UILabel!
@IBOutlet weak var spanishLabelOpen: UILabel!
@IBOutlet weak var savedImageView1Open: UIImageView!
@IBOutlet weak var savedImageView2Open: UIImageView!
@IBOutlet weak var enterAGreetingLabelOpen: UILabel!
@IBOutlet weak var enterAGreetinTextFieldOpen: HoshiTextField!
@IBOutlet weak var barViewOpen: UIView!
// 'Continue' Button
@IBOutlet weak var continueButton: LGButton!
// Hamburger Button
@IBOutlet weak var hamburgerButton: UIButton!
// MARK: - Setting-up Labels
// CLOSED Labels
var enterAGreetingClosed: String = "" {
didSet {
enterAGreetingLabelClosed.text = String(enterAGreetingClosed)
}
}
// OPEN Labels
var englishOpen: String = "" {
didSet {
englishLabelOpen.text = String(englishOpen)
}
}
var spanishOpen: String = "" {
didSet {
spanishLabelOpen.text = String(spanishOpen)
}
}
var enterAGreetingOpen: String = "" {
didSet {
enterAGreetingLabelOpen.text = String(enterAGreetingOpen)
}
}
var confirmOpen: String = "" {
didSet {
confirmLabelOpen.text = String(confirmOpen)
}
}
override func awakeFromNib() {
barViewOpen.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively
barViewOpen.clipsToBounds = true
foregroundView.layer.cornerRadius = 10
foregroundView.layer.masksToBounds = true
super.awakeFromNib()
// Initialization code
enterAGreetinTextFieldOpen.delegate = self
}
override func animationDuration(_ itemIndex: NSInteger, type: FoldingCell.AnimationType) -> TimeInterval {
let durations = [0.26, 0.2, 0.2]
return durations[itemIndex]
}
@IBAction func enterAGreetingTextFieldEditingDidBegin(_ sender: HoshiTextField) {
print("@enterAGreetingTextFieldEditingDidBegin -> cell.swift: does nothing as of now.")
}
@IBAction func enterAGreetingTextFieldEditingDidEnd(_ sender: HoshiTextField) {
if sender.text!.isEmpty != true {
// Activates and shows the 'Continue' button
continueButton.isEnabled = true
continueButton.alpha = 1
print("enterAGreetingTextFieldEditingDidEnd@Cell -> cell.swift: activated 'Continue' button because textField contained text after editing ended.")
} else if sender.text!.isEmpty == true {
// Deactivates and hides the 'Continue' button
continueButton.isEnabled = false
continueButton.alpha = 0.5
print("enterAGreetingTextFieldEditingDidEnd@Cell: deactivated 'Continue' button because textField was empty after editing ended.")
}
}
// JUST FYI, THIS DOES NOT GET CALLED
private func textFieldShouldReturn(_ textField: HoshiTextField) -> Bool {
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let savedImageTableVC = storyboard.instantiateViewController(withIdentifier: "SavedImageTableViewController") as! SavedImageTableViewController
savedImageTableVC.loadViewIfNeeded()
if textField.text?.isEmpty == false {
savedImageTableVC.liveGreeting = textField.text!
savedImageTableVC.savedImageTableView.reloadData()
print(".CELL @textFieldShouldReturn() -> savedImageTableVC.savedImagesArray: \(savedImageTableVC.savedImagesArray).")
let indexPathRow = textField.tag
StructOperation.globalVariable.tappedCellIndexRow = indexPathRow
print(".CELL @textFieldShouldReturn() -> StructOperation.globalVariable.tappedCellIndexRow: \(StructOperation.globalVariable.tappedCellIndexRow).")
savedImageTableVC.goToSend()
print("User entered a greeting in enterAGreetingTextField: \(savedImageTableVC.liveGreeting).")
} else if textField.text?.isEmpty == true {
savedImageTableVC.liveGreeting = ""
SCLAlertView().showError("Error", subTitle: "To send an image, a greeting must also be specified.", closeButtonTitle: "Done", timeout: nil, colorStyle: SCLAlertViewStyle.error.defaultColorInt, colorTextButton: 0xFFFFFF, circleIconImage: nil, animationStyle: .topToBottom)
print("User did not enter a greeting in enterAGreetingTextField.")
}
return true
}
}
// MARK: - Actions ⚡️
extension SavedImageFoldingImageCell {
@IBAction func openCellButtonTapped() {
// print("The open-cell button was tapped (just a downward arrow).")
}
@IBAction func enterAGreetingTextfieldOpenEditingDidEnd() {
// print("'enterAGreetingTextField' finished editing.")
}
@IBAction func continueButtonTapped(_: AnyObject) {
// print("The 'Continue' button was tapped.")
}
@IBAction func hamburgerButtonTapped(_: AnyObject) {
// print("The hamburger button was tapped.")
}
}
UITableViewController 的代码:
import UIKit
import TextFieldEffects
import SCLAlertView
import MessageUI
import FoldingCell
import MLKitTranslate
class SavedImageTableViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, MFMessageComposeViewControllerDelegate, UITextFieldDelegate, UIContextMenuInteractionDelegate {
@IBOutlet var savedImageTableView: UITableView!
*** Omitted other irrelevant outlets, vars, & constants ***
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
activityIndicator() // Omitted because nothing regarding the textfield is called here
refresh() // Omitted ""
}
override func viewDidLoad() {
super.viewDidLoad()
setup() // Omitted ""; (assigned self to tableview's delegate and dataSource here)
checkIfSavedImages() // Omitted ""
getDeadlineInSeconds() // Omitted ""
// For deadline countdown timer
countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
// Stops loading spinner and hides view
self.indicator.stopAnimating()
self.indicator.hidesWhenStopped = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
}
@IBAction func enterAGreetingTextFieldEditingDidEnd(_ sender: HoshiTextField) {
let cell = savedImageTableView.dequeueReusableCell(withIdentifier: "SavedImageFoldingImageCell") as! SavedImageFoldingImageCell
if sender.text?.isEmpty == true {
sender.text = ""
cell.continueButton.isEnabled = false
cell.continueButton.alpha = 0.5
// sender.resignFirstResponder()
} else if sender.text?.isEmpty == false {
self.liveGreeting = sender.text!
cell.continueButton.isEnabled = true
cell.continueButton.alpha = 1
}
}
@IBAction func enterAGreetingTextFieldEditingDidBegin(_ sender: HoshiTextField) {
sender.becomeFirstResponder() // Fixes IQKeyboardManager (rather, allows UITableViewController to properly scroll)
let indexPathRow = sender.tag
StructOperation.globalVariable.tappedCellIndexRow = indexPathRow
print("enterAGreetingTextFieldEditingDidEnd()@ViewController -> StructOperation.globalVariable.tappedCellIndexRow: \(StructOperation.globalVariable.tappedCellIndexRow).")
}
//MARK: - TableView Functions
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard case let cell as SavedImageFoldingImageCell = cell else {
return
}
cell.enterAGreetingClosed = "Enter a Greeting"
cell.enterAGreetingOpen = "Enter a Greeting"
cell.englishOpen = "English"
cell.spanishOpen = "Spanish"
cell.confirmOpen = "Confirm"
// Greeting TextField
cell.enterAGreetinTextFieldOpen.delegate = self
cell.enterAGreetinTextFieldOpen.tag = indexPath.row
// Open-cell button (downward arrow)
cell.openCellButton.tag = indexPath.row
// 'Continue' button
cell.continueButton.tag = indexPath.row
cell.continueButton.isEnabled = false
cell.continueButton.alpha = 0.5
// Hamburger button
cell.hamburgerButton.tag = indexPath.row
// Closed/Open Images (English, Spanish)
let calculatedIndex = (indexPath.row * 2) + 1
cell.savedImageView1Closed.image = savedImagesArray[calculatedIndex - 1]
cell.savedImageView2Closed.image = savedImagesArray[calculatedIndex]
cell.savedImageView1Open.image = savedImagesArray[calculatedIndex - 1]
cell.savedImageView2Open.image = savedImagesArray[calculatedIndex]
cell.backgroundColor = .clear
if cellHeights[indexPath.row] == Constants.closeCellHeight {
cell.unfold(false, animated: false, completion: nil)
} else {
cell.unfold(true, animated: false, completion: nil)
}
// Allows recognition of tapping the 'Continue' button by connecting that button's outlet to a newly created function down below a little
cell.continueButton.addTarget(self, action: #selector(SavedImageTableViewController.continueButtonTapped(_:)), for: .touchUpInside)
// Allows recognition of tapping the 'open cell' button (just a downward arrow) by connecting that button's outlet to a newly created function down below a little
cell.openCellButton.addTarget(self, action: #selector(openCellButtonTapped(_:)), for: .touchUpInside)
// Allows recognition of tapping the 'hamburger' button (just three horizontal lines as a button) by connecting that button's outlet to a newly created function down below a little
cell.hamburgerButton.addTarget(self, action: #selector(hamburgerButtonTapped(_:)), for: .touchUpInside)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = savedImageTableView.dequeueReusableCell(withIdentifier: "SavedImageFoldingImageCell", for: indexPath) as! FoldingCell
let durations: [TimeInterval] = [0.26, 0.2, 0.2]
cell.durationsForExpandedState = durations
cell.durationsForCollapsedState = durations
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard case let cell as FoldingCell = tableView.cellForRow(at: indexPath) else {
return
}
if cell.isAnimating() {
return
}
var duration = 0.0
let cellIsCollapsed = cellHeights[indexPath.row] == Constants.closeCellHeight
if cellIsCollapsed {
cellHeights[indexPath.row] = Constants.openCellHeight
cell.unfold(true, animated: true, completion: nil)
duration = 0.5
} else {
cellHeights[indexPath.row] = Constants.closeCellHeight
cell.unfold(false, animated: true, completion: nil)
duration = 0.8
}
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
tableView.beginUpdates()
tableView.endUpdates()
// fix https://github.com/Ramotion/folding-cell/issues/169
if cell.frame.maxY > tableView.frame.maxY {
tableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.bottom, animated: true)
}
}, completion: nil)
// Provide haptic feedback of success
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)
}
***Rest is Omitted because I think its irrelevant to the problem***
我通过简单地将 class 从 UITableViewController -> UIViewController 切换来解决我自己的问题。我在 IQKeyboardManager 的 Github 页面上浏览了已关闭的问题,发现由于 Apple 的 UITableViewController 自动处理视图和键盘的移动,IQKeyboardManager 的 开发人员选择忽略 UITableViewController 中的文本字段。因此,您必须将 class 更改为 UIViewController 或另一个受支持的 class 才能让 IQKeyboardManager.
识别文本字段
这是我目前得到的结果(不需要的):https://vimeo.com/459984986.
这是我使用变通方法得到的结果(几乎是我想要的):https://vimeo.com/459986233.
关于我的问题的总结如下:(1)我已经安装了“IQKeyboardManagerSwift”cocoapod,(2) 我的 UITableViewController 中有一个自定义单元格,它是一个 FolingCell(另一个 cocoapod)并且包含一个文本字段,当我点击内部时 (3)文本字段,我希望视图自动向上滚动以使文本字段可见(在键盘上方),这应该由 IQKeyboardManager 自动处理(是的,我添加了“启用" 我的 AppDelegate 中的代码)。
如上面“不需要的”结果视频所示,视图似乎试图滚动但最终只是上下抖动 在键盘向上滑动并不希望地覆盖文本字段时,稍微结束在原始位置之前。
此外,我发现我不想接受的小“解决方法”是将以下行添加到文本字段的 IBAction editingDidEnd outlet/action 函数中:“ sender.becomeFirstResponder()”。在我 iPhone 上更新到 XCode 12 和 iOS 14 之前,我 运行 并测试我的应用程序,我不必为“.becomeFirstResponder()”操心或“.resignResponder()”,因为那是 IQKeyboardManager 自动执行的操作。现在,添加上述代码行允许 UITableViewController 将视图移动到键盘上方。 但是, 如果你仔细观察,它位于键盘顶部的文本字段,这显然不是 IQKeyboardManager 因为 IQKeyboardManager 在文本字段和键盘之间的默认偏移量为 CGFloat(10)。
我认为 代码的相关部分 是我的 自定义单元格 (称为“SavedImageFoldingImageCell”),因为那是我创建文本字段的地方有问题和我的 UITableViewController(称为“SavedImageTableViewController”)。
拜托,你能提供的任何帮助、建议和忠告都会对我有很大帮助,我将不胜感激。谢谢!
是的,我的代码看起来很糟糕,因为我没有适当的 training/education 编码或一般编码的最佳实践。那里的建议也将不胜感激!如果您发现我可以缩短和组织代码的方法,请务必泄露您的秘密!
自定义单元格代码:
import UIKit
import FoldingCell
import LGButton
import TextFieldEffects
import SCLAlertView
class SavedImageFoldingImageCell: FoldingCell, UITextFieldDelegate {
// CLOSED
@IBOutlet weak var enterAGreetingLabelClosed: UILabel!
@IBOutlet weak var savedImageView1Closed: UIImageView!
@IBOutlet weak var savedImageView2Closed: UIImageView!
@IBOutlet weak var openCellButton: LGButton!
// OPEN
@IBOutlet weak var confirmLabelOpen: UILabel!
@IBOutlet weak var englishLabelOpen: UILabel!
@IBOutlet weak var spanishLabelOpen: UILabel!
@IBOutlet weak var savedImageView1Open: UIImageView!
@IBOutlet weak var savedImageView2Open: UIImageView!
@IBOutlet weak var enterAGreetingLabelOpen: UILabel!
@IBOutlet weak var enterAGreetinTextFieldOpen: HoshiTextField!
@IBOutlet weak var barViewOpen: UIView!
// 'Continue' Button
@IBOutlet weak var continueButton: LGButton!
// Hamburger Button
@IBOutlet weak var hamburgerButton: UIButton!
// MARK: - Setting-up Labels
// CLOSED Labels
var enterAGreetingClosed: String = "" {
didSet {
enterAGreetingLabelClosed.text = String(enterAGreetingClosed)
}
}
// OPEN Labels
var englishOpen: String = "" {
didSet {
englishLabelOpen.text = String(englishOpen)
}
}
var spanishOpen: String = "" {
didSet {
spanishLabelOpen.text = String(spanishOpen)
}
}
var enterAGreetingOpen: String = "" {
didSet {
enterAGreetingLabelOpen.text = String(enterAGreetingOpen)
}
}
var confirmOpen: String = "" {
didSet {
confirmLabelOpen.text = String(confirmOpen)
}
}
override func awakeFromNib() {
barViewOpen.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively
barViewOpen.clipsToBounds = true
foregroundView.layer.cornerRadius = 10
foregroundView.layer.masksToBounds = true
super.awakeFromNib()
// Initialization code
enterAGreetinTextFieldOpen.delegate = self
}
override func animationDuration(_ itemIndex: NSInteger, type: FoldingCell.AnimationType) -> TimeInterval {
let durations = [0.26, 0.2, 0.2]
return durations[itemIndex]
}
@IBAction func enterAGreetingTextFieldEditingDidBegin(_ sender: HoshiTextField) {
print("@enterAGreetingTextFieldEditingDidBegin -> cell.swift: does nothing as of now.")
}
@IBAction func enterAGreetingTextFieldEditingDidEnd(_ sender: HoshiTextField) {
if sender.text!.isEmpty != true {
// Activates and shows the 'Continue' button
continueButton.isEnabled = true
continueButton.alpha = 1
print("enterAGreetingTextFieldEditingDidEnd@Cell -> cell.swift: activated 'Continue' button because textField contained text after editing ended.")
} else if sender.text!.isEmpty == true {
// Deactivates and hides the 'Continue' button
continueButton.isEnabled = false
continueButton.alpha = 0.5
print("enterAGreetingTextFieldEditingDidEnd@Cell: deactivated 'Continue' button because textField was empty after editing ended.")
}
}
// JUST FYI, THIS DOES NOT GET CALLED
private func textFieldShouldReturn(_ textField: HoshiTextField) -> Bool {
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let savedImageTableVC = storyboard.instantiateViewController(withIdentifier: "SavedImageTableViewController") as! SavedImageTableViewController
savedImageTableVC.loadViewIfNeeded()
if textField.text?.isEmpty == false {
savedImageTableVC.liveGreeting = textField.text!
savedImageTableVC.savedImageTableView.reloadData()
print(".CELL @textFieldShouldReturn() -> savedImageTableVC.savedImagesArray: \(savedImageTableVC.savedImagesArray).")
let indexPathRow = textField.tag
StructOperation.globalVariable.tappedCellIndexRow = indexPathRow
print(".CELL @textFieldShouldReturn() -> StructOperation.globalVariable.tappedCellIndexRow: \(StructOperation.globalVariable.tappedCellIndexRow).")
savedImageTableVC.goToSend()
print("User entered a greeting in enterAGreetingTextField: \(savedImageTableVC.liveGreeting).")
} else if textField.text?.isEmpty == true {
savedImageTableVC.liveGreeting = ""
SCLAlertView().showError("Error", subTitle: "To send an image, a greeting must also be specified.", closeButtonTitle: "Done", timeout: nil, colorStyle: SCLAlertViewStyle.error.defaultColorInt, colorTextButton: 0xFFFFFF, circleIconImage: nil, animationStyle: .topToBottom)
print("User did not enter a greeting in enterAGreetingTextField.")
}
return true
}
}
// MARK: - Actions ⚡️
extension SavedImageFoldingImageCell {
@IBAction func openCellButtonTapped() {
// print("The open-cell button was tapped (just a downward arrow).")
}
@IBAction func enterAGreetingTextfieldOpenEditingDidEnd() {
// print("'enterAGreetingTextField' finished editing.")
}
@IBAction func continueButtonTapped(_: AnyObject) {
// print("The 'Continue' button was tapped.")
}
@IBAction func hamburgerButtonTapped(_: AnyObject) {
// print("The hamburger button was tapped.")
}
}
UITableViewController 的代码:
import UIKit
import TextFieldEffects
import SCLAlertView
import MessageUI
import FoldingCell
import MLKitTranslate
class SavedImageTableViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, MFMessageComposeViewControllerDelegate, UITextFieldDelegate, UIContextMenuInteractionDelegate {
@IBOutlet var savedImageTableView: UITableView!
*** Omitted other irrelevant outlets, vars, & constants ***
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
activityIndicator() // Omitted because nothing regarding the textfield is called here
refresh() // Omitted ""
}
override func viewDidLoad() {
super.viewDidLoad()
setup() // Omitted ""; (assigned self to tableview's delegate and dataSource here)
checkIfSavedImages() // Omitted ""
getDeadlineInSeconds() // Omitted ""
// For deadline countdown timer
countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
// Stops loading spinner and hides view
self.indicator.stopAnimating()
self.indicator.hidesWhenStopped = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
}
@IBAction func enterAGreetingTextFieldEditingDidEnd(_ sender: HoshiTextField) {
let cell = savedImageTableView.dequeueReusableCell(withIdentifier: "SavedImageFoldingImageCell") as! SavedImageFoldingImageCell
if sender.text?.isEmpty == true {
sender.text = ""
cell.continueButton.isEnabled = false
cell.continueButton.alpha = 0.5
// sender.resignFirstResponder()
} else if sender.text?.isEmpty == false {
self.liveGreeting = sender.text!
cell.continueButton.isEnabled = true
cell.continueButton.alpha = 1
}
}
@IBAction func enterAGreetingTextFieldEditingDidBegin(_ sender: HoshiTextField) {
sender.becomeFirstResponder() // Fixes IQKeyboardManager (rather, allows UITableViewController to properly scroll)
let indexPathRow = sender.tag
StructOperation.globalVariable.tappedCellIndexRow = indexPathRow
print("enterAGreetingTextFieldEditingDidEnd()@ViewController -> StructOperation.globalVariable.tappedCellIndexRow: \(StructOperation.globalVariable.tappedCellIndexRow).")
}
//MARK: - TableView Functions
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard case let cell as SavedImageFoldingImageCell = cell else {
return
}
cell.enterAGreetingClosed = "Enter a Greeting"
cell.enterAGreetingOpen = "Enter a Greeting"
cell.englishOpen = "English"
cell.spanishOpen = "Spanish"
cell.confirmOpen = "Confirm"
// Greeting TextField
cell.enterAGreetinTextFieldOpen.delegate = self
cell.enterAGreetinTextFieldOpen.tag = indexPath.row
// Open-cell button (downward arrow)
cell.openCellButton.tag = indexPath.row
// 'Continue' button
cell.continueButton.tag = indexPath.row
cell.continueButton.isEnabled = false
cell.continueButton.alpha = 0.5
// Hamburger button
cell.hamburgerButton.tag = indexPath.row
// Closed/Open Images (English, Spanish)
let calculatedIndex = (indexPath.row * 2) + 1
cell.savedImageView1Closed.image = savedImagesArray[calculatedIndex - 1]
cell.savedImageView2Closed.image = savedImagesArray[calculatedIndex]
cell.savedImageView1Open.image = savedImagesArray[calculatedIndex - 1]
cell.savedImageView2Open.image = savedImagesArray[calculatedIndex]
cell.backgroundColor = .clear
if cellHeights[indexPath.row] == Constants.closeCellHeight {
cell.unfold(false, animated: false, completion: nil)
} else {
cell.unfold(true, animated: false, completion: nil)
}
// Allows recognition of tapping the 'Continue' button by connecting that button's outlet to a newly created function down below a little
cell.continueButton.addTarget(self, action: #selector(SavedImageTableViewController.continueButtonTapped(_:)), for: .touchUpInside)
// Allows recognition of tapping the 'open cell' button (just a downward arrow) by connecting that button's outlet to a newly created function down below a little
cell.openCellButton.addTarget(self, action: #selector(openCellButtonTapped(_:)), for: .touchUpInside)
// Allows recognition of tapping the 'hamburger' button (just three horizontal lines as a button) by connecting that button's outlet to a newly created function down below a little
cell.hamburgerButton.addTarget(self, action: #selector(hamburgerButtonTapped(_:)), for: .touchUpInside)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = savedImageTableView.dequeueReusableCell(withIdentifier: "SavedImageFoldingImageCell", for: indexPath) as! FoldingCell
let durations: [TimeInterval] = [0.26, 0.2, 0.2]
cell.durationsForExpandedState = durations
cell.durationsForCollapsedState = durations
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard case let cell as FoldingCell = tableView.cellForRow(at: indexPath) else {
return
}
if cell.isAnimating() {
return
}
var duration = 0.0
let cellIsCollapsed = cellHeights[indexPath.row] == Constants.closeCellHeight
if cellIsCollapsed {
cellHeights[indexPath.row] = Constants.openCellHeight
cell.unfold(true, animated: true, completion: nil)
duration = 0.5
} else {
cellHeights[indexPath.row] = Constants.closeCellHeight
cell.unfold(false, animated: true, completion: nil)
duration = 0.8
}
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
tableView.beginUpdates()
tableView.endUpdates()
// fix https://github.com/Ramotion/folding-cell/issues/169
if cell.frame.maxY > tableView.frame.maxY {
tableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.bottom, animated: true)
}
}, completion: nil)
// Provide haptic feedback of success
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)
}
***Rest is Omitted because I think its irrelevant to the problem***
我通过简单地将 class 从 UITableViewController -> UIViewController 切换来解决我自己的问题。我在 IQKeyboardManager 的 Github 页面上浏览了已关闭的问题,发现由于 Apple 的 UITableViewController 自动处理视图和键盘的移动,IQKeyboardManager 的 开发人员选择忽略 UITableViewController 中的文本字段。因此,您必须将 class 更改为 UIViewController 或另一个受支持的 class 才能让 IQKeyboardManager.
识别文本字段