为什么滚动浏览集合视图后视图消失



我正在尝试创建一个在键盘出现时向上滑动的视图,并且在此视图中有一个文本字段用作搜索栏和集合视图来保存搜索结果。视图在键盘上方滑动得很好,但是一旦我点击其中一个单元格以可怕地滚动,视图就会消失。可能导致这种情况的原因是什么。

我认为可能导致问题的代码

var offsetY:CGFloat = 0
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardFrameChangeNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}

@objc func keyboardFrameChangeNotification(notification: Notification) {
    if let userInfo = notification.userInfo {
        let endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect
        let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0
        let animationCurveRawValue = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int) ?? Int(UIViewAnimationOptions.curveEaseInOut.rawValue)
       let animationCurve = UIViewAnimationOptions(rawValue: Int(animationCurveRawValue))
        if let _ = endFrame, endFrame!.intersects(self.myView.frame) {
            self.offsetY = self.myView.frame.maxY - endFrame!.minY
            UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
                self.myView.frame.origin.y = self.myView.frame.origin.y - self.offsetY
            }, completion: nil)
        } else {
            if self.offsetY != 0 {
                UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
                    self.myView.frame.origin.y = self.myView.frame.origin.y + self.offsetY
                    self.offsetY = 0
                }, completion: nil)
            }
        }
    }
}

完整代码

import UIKit
class SearchCollectionViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout, UITextFieldDelegate, UICollectionViewDataSource {
@IBOutlet weak var searchBar: UITextField!
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var myView: UIView!

var genericArray:[String] = ["A","B","C","D","E","F","G","Ab","Abc"]
var currentGenericArray:[String] = [String]()
override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.delegate = self
    collectionView.dataSource = self
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    layout.itemSize = CGSize(width: (UIScreen.main.bounds.width-1)/2, height: (UIScreen.main.bounds.width-1)/2)
    layout.minimumInteritemSpacing = 1
    layout.minimumLineSpacing = 1
    layout.scrollDirection = .horizontal
    self.collectionView.collectionViewLayout = layout

    searchBar.delegate = self
    currentGenericArray = genericArray
    searchBar.addTarget(self, action: #selector(TableSearchViewController.textFieldDidChange), for: .editingChanged)

}
@objc func textFieldDidChange(){
    guard(!(searchBar.text?.isEmpty)!) else{
        currentGenericArray = genericArray
        collectionView.reloadData()
        return
    }
    currentGenericArray = genericArray.filter({letter -> Bool in
        letter.lowercased().contains(searchBar.text!)
    })
    collectionView.reloadData()
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return currentGenericArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionCell
    cell.collectionLabel.text = currentGenericArray[indexPath.row]
    return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}
var offsetY:CGFloat = 0
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardFrameChangeNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}

@objc func keyboardFrameChangeNotification(notification: Notification) {
    if let userInfo = notification.userInfo {
        let endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect
        let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0
        let animationCurveRawValue = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int) ?? Int(UIViewAnimationOptions.curveEaseInOut.rawValue)
        let animationCurve = UIViewAnimationOptions(rawValue: UInt(animationCurveRawValue))
        if let _ = endFrame, endFrame!.intersects(self.myView.frame) {
            self.offsetY = self.myView.frame.maxY - endFrame!.minY
            UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
                self.myView.frame.origin.y = self.myView.frame.origin.y - self.offsetY
            }, completion: nil)
        } else {
            if self.offsetY != 0 {
                UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
                    self.myView.frame.origin.y = self.myView.frame.origin.y + self.offsetY
                    self.offsetY = 0
                }, completion: nil)
            }
        }
    }
}
}

class CollectionCell:UICollectionViewCell{
@IBOutlet weak var collectionLabel: UILabel!
override func awakeFromNib() {
    collectionLabel.textAlignment = .center
}
}

你的代码有点混乱,但我没有看到任何textField函数,除了你从searchBar调用的didChange。尝试添加shouldReturndidEndEditing,以及更新滑块。这是我会做什么的一个例子。尝试一下,看看它是否有所作为。

生命周期

   let keyboardSlider = KeyboardSlider()
   override func viewDidLoad() { 
       super.viewDidLoad()
       keyboardSlider.subscribeToKeyboardNotifications(view: view) 
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        keyboardSlider.unsubscribeFromKeyboardNotifications()
    }

文本字段

// MARK: TextFieldDelegate
func textFieldDidBeginEditing(_ textField: UITextField) {
    // Add Done button  for Keyboard Dismissal
    let toolBar = UIToolbar()
    toolBar.sizeToFit()
    toolBar.barStyle = .default
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.didStopEditing))
    let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
    toolBar.setItems([space, doneButton], animated: false)
    textField.inputAccessoryView = toolBar
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}
/// Helper to dismiss keyboard
@objc func didStopEditing() {
    textFieldShouldReturn(phoneNumberTextField)
}
func textFieldDidEndEditing(_ textField: UITextField) { 
    UIView.setAnimationCurve(UIViewAnimationCurve.easeInOut)
        UIView.animate(withDuration: 0.2) {
            self.view.frame.origin.y = 0
        }
}

键盘滑块

class KeyboardSlider: NSObject {
        // variables to hold and process information from the view using this class
    weak var view: UIView?
    @objc func keyboardWillShow(notification: NSNotification) {
        // method to move keyboard up
        view?.frame.origin.y = 0 - getKeyboardHeight(notification as Notification)
    }
    func getKeyboardHeight(_ notification:Notification) -> CGFloat {
        // get exact height of keyboard on all devices and convert to float value to return for use
        let userInfo = notification.userInfo
        let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue
        return keyboardSize.cgRectValue.height
    }
    func subscribeToKeyboardNotifications(view: UIView) {
        // assigning view to class' counterpart
        self.view = view
        // when UIKeyboardWillShow do keyboardWillShow function
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
    }
    func unsubscribeFromKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
    }

}

这个答案主要是清理你的代码

我有一种感觉,你的问题出在你didChange键盘关闭的方法上。清理代码并单步执行断点将有助于找到问题。

相关内容

  • 没有找到相关文章

最新更新