如何在不重新加载标题的情况下重新加载 UICollectionView 中的单元格?
Posted
技术标签:
【中文标题】如何在不重新加载标题的情况下重新加载 UICollectionView 中的单元格?【英文标题】:How do I reload cells in UICollectionView without reloading the header? 【发布时间】:2018-07-18 18:55:03 【问题描述】:我正在尝试根据用户在标题中的 textField 中输入的内容来更新 UICollectionView 中单元格的内容。我在这里查看了其他类似的问题,但他们的答案似乎都不起作用。我什至尝试实现 UICollectionView 的扩展,该扩展通过该部分中的每个单元格尝试重新加载其数据,但这会导致崩溃,因为数量用户进入 textField 后,单元格会发生变化
我试图解决问题的功能,我只有一个部分,所以我在该部分中进行了硬编码
@objc func textFieldDidChange()
guard(!(feedSearchBar.text?.isEmpty)!) else
VC.currentTagsArray = VC.genericTagsArray
VC.feedScreenCollectionView.reloadData()
return
VC.currentTagsArray = VC.genericTagsArray.filter(letter -> Bool in
if feedSearchBar.text!.count > letter.count
return false
let stringRange = letter.index(letter.startIndex, offsetBy: feedSearchBar.text!.count)
let subword = letter[..<stringRange]
return subword.lowercased().contains(feedSearchBar.text!.lowercased())
)
if VC.currentTagsArray.isEmpty
VC.currentTagsArray.insert(feedSearchBar.text!, at: 0)
VC.feedScreenCollectionView.reloadItems(inSection: 0)
extension UICollectionView
func reloadItems(inSection section:Int = 0)
print("made it to reload")
for i in 0..<self.numberOfItems(inSection: section)
self.reloadItems(at: [IndexPath(item: i, section: section)])
这是项目的全部代码
import UIKit
class ViewController: UIViewController,UICollectionViewDelegateFlowLayout,UICollectionViewDelegate,UICollectionViewDataSource,printDelegateWorkedDelegate,updateCollectionView
func updateCollectionView()
self.feedScreenCollectionView.reloadData()
func printDelegateWorkedDelegate()
print("The delegate worked")
var genericTagsArray:[String] = ["tag1","tag2","tag3","tag4","tag5","tag6","tag7","tag8","tag9","tag10","tag11","tag12","A","B","C","D","E","F","G","Ab","Abc","za","tag1","tag2","tag3","tag4","tag5","tag6","tag7","tag8","tag9","tag10","tag11","tag12","A","B","C","D","E","F","G","Ab","Abc","za"]
var currentTagsArray:[String] = [String]()
var tagsSelected:[String] = [String]()
let keyboardSlider = KeyboardSlider()
var header:feedViewHeader = feedViewHeader()
@IBOutlet weak var feedScreenCollectionView: UICollectionView!
override func viewDidLoad()
super.viewDidLoad()
keyboardSlider.subscribeToKeyboardNotifications(view: view)
currentTagsArray = genericTagsArray
let viewTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(feedViewHeader.viewTapped(gestureRecognizer:)))
viewTapGestureRecognizer.cancelsTouchesInView = false
self.feedScreenCollectionView.addGestureRecognizer(viewTapGestureRecognizer)
feedScreenCollectionView.delegate = self
//
feedScreenCollectionView.dataSource = self
//
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 5, left: 1, bottom: 0, right: 1)
layout.minimumLineSpacing = 0
layout.headerReferenceSize = CGSize(width: 50, height: 75)
layout.sectionHeadersPinToVisibleBounds = true
feedScreenCollectionView.collectionViewLayout = layout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
return CGSize(width: 50, height: 75)
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "feedViewHeader", for: indexPath) as! feedViewHeader
header.VC = self
return header
//
//Data Source
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return currentTagsArray.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "feedViewCell", for: indexPath) as! feedViewCell
cell.feedImageView.backgroundColor = .blue
cell.feedImageView.clipsToBounds = true
cell.feedImageView.layer.cornerRadius = CGFloat((cell.feedImageView.frame.width)/5)
cell.feedLabel.text = currentTagsArray[indexPath.item]
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
return 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
return 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let collectionViewWidth = collectionView.bounds.width/4.0
let collectionViewHeight = collectionViewWidth
return CGSize(width: collectionViewWidth-4, height: collectionViewHeight+25)
var lastContentOffset:CGFloat = 0
func scrollViewDidScroll(_ scrollView: UIScrollView)
if self.lastContentOffset > self.feedScreenCollectionView.contentOffset.y && self.feedScreenCollectionView.contentOffset.y > 0 && self.feedScreenCollectionView.contentOffset.y < self.feedScreenCollectionView.frame.maxY
self.lastContentOffset = scrollView.contentOffset.y
header.isHidden = false
else if (self.lastContentOffset < self.feedScreenCollectionView.contentOffset.y) && (self.feedScreenCollectionView.contentOffset.y < self.feedScreenCollectionView.frame.maxY) && (self.feedScreenCollectionView.contentOffset.y > 0)
print("you scrolled down,content offSet: \(scrollView.contentOffset.y)->\(self.feedScreenCollectionView.contentOffset.y)")
header.isHidden = true
else
self.lastContentOffset = scrollView.contentOffset.y
print("content offSet: \(scrollView.contentOffset.y)")
print("Nothing happened")
// self.headerDelegate?.hideHeaderView(hide: true)
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardFrameChangeNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
var offsetY:CGFloat = 0
@objc func keyboardFrameChangeNotification(notification: Notification)
class feedViewCell:UICollectionViewCell
@IBOutlet weak var feedImageView: UIImageView!
@IBOutlet weak var feedLabel: UILabel!
let keyboardSlider = KeyboardSlider()
override func awakeFromNib()
super.awakeFromNib()
feedLabel.translatesAutoresizingMaskIntoConstraints = false
feedImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
feedImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
feedImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
feedImageView.bottomAnchor.constraint(equalTo: self.feedLabel.topAnchor).isActive = true
feedImageView.translatesAutoresizingMaskIntoConstraints = false
feedLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
feedLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
feedLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
feedLabel.topAnchor.constraint(equalTo: self.feedImageView.bottomAnchor).isActive = true
feedLabel.textAlignment = .center
class feedViewHeader:UICollectionReusableView,UITextFieldDelegate,UICollectionViewDelegate
@IBOutlet weak var feedSearchBar: UITextField!
var delegateWorked:printDelegateWorkedDelegate?
var updateCV:updateCollectionView?
var VC:ViewController!
var collectionView:UICollectionView?
var stringToBeSet = "String to be set"
override func awakeFromNib()
super.awakeFromNib()
feedSearchBar.delegate = self
feedSearchBar.autocorrectionType = .no
feedSearchBar.keyboardType = .default
feedSearchBar.addTarget(self, action: #selector(feedViewHeader.textFieldDidChange), for: .editingChanged)
self.feedSearchBar.borderStyle = .roundedRect
self.feedSearchBar.layer.borderColor = UIColor.black.cgColor
self.feedSearchBar.layer.borderWidth = 4
var searchBarHeight = self.feedSearchBar.bounds.height
self.feedSearchBar.placeholder = "Tap To Search"
self.feedSearchBar.returnKeyType = .search
self.feedSearchBar.rightViewMode = .always
@objc func viewTapped(gestureRecognizer:UIGestureRecognizer)
if feedSearchBar.isFirstResponder
feedSearchBar.resignFirstResponder()
func textFieldShouldReturn(_ textField: UITextField) -> Bool
textField.resignFirstResponder()
VC.feedScreenCollectionView.reloadData()
//VC.feedScreenCollectionView.reloadSections([0])
return true
/// Helper to dismiss keyboard
@objc func didStopEditing()
func textFieldDidEndEditing(_ textField: UITextField)
UIView.setAnimationCurve(UIViewAnimationCurve.easeInOut)
UIView.animate(withDuration: 0.2)
self.VC.view.frame.origin.y = 0
@objc func textFieldDidChange()
guard(!(feedSearchBar.text?.isEmpty)!) else
VC.currentTagsArray = VC.genericTagsArray
VC.feedScreenCollectionView.reloadData()
return
VC.currentTagsArray = VC.genericTagsArray.filter(letter -> Bool in
if feedSearchBar.text!.count > letter.count
return false
let stringRange = letter.index(letter.startIndex, offsetBy: feedSearchBar.text!.count)
let subword = letter[..<stringRange]
return subword.lowercased().contains(feedSearchBar.text!.lowercased())
)
if VC.currentTagsArray.isEmpty
VC.currentTagsArray.insert(feedSearchBar.text!, at: 0)
VC.feedScreenCollectionView.reloadItems(inSection: 0)
extension Notification.Name
static let showKeyboard = Notification.Name("showKeyboard")
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)
print("made it to keyboard will show")
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)
class blankView:UICollectionReusableView
extension UICollectionView
func reloadItems(inSection section:Int = 0)
print("made it to reload")
for i in 0..<self.numberOfItems(inSection: section)
self.reloadItems(at: [IndexPath(item: i, section: section)])
【问题讨论】:
【参考方案1】:你可以调用方法
Objective-C
- (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths
斯威夫特
func reloadItems(at indexPaths: [IndexPath])
您可以在其中传递要更新的 indexPaths 数组。 更多信息在Apple Documentation
【讨论】:
感谢您的回复,我尝试在 UICollectionView 的扩展中这样做: func reloadItems(inSection section:Int = 0) var indicies:[IndexPath] = [IndexPath]() for我在 0..以上是关于如何在不重新加载标题的情况下重新加载 UICollectionView 中的单元格?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不注销并重新登录的情况下重新加载 .bashrc 设置?
如何在不重新加载 visibleCell 的情况下在 collectionView 上重新加载数据