- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试创建一个程序,当用户在 UITextField
中输入文本时动态更新 collectoinView。下面是我为实现此目的而创建的扩展
我已经根据您的建议更新了代码以包含插入和删除语句,我仍在重构和添加委托(delegate)的过程中,但是虽然代码不会导致错误,但它不允许用户继续输入并关闭键盘我是否正确执行了所有操作
更新#2(感谢您的所有帮助)
import UIKit
class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate, UISearchBarDelegate {
lazy var collectionView : UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .white
cv.delegate = self
cv.dataSource = self
return cv
}()
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]() {
didSet {
collectionView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(collectionView)
collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header")
collectionView.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: self.view.leadingAnchor, bottom: self.view.bottomAnchor, trailing: self.view.trailingAnchor, padding: .init(top: 30, left: 0, bottom: 30, right: 0))
collectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return currentTagsArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
cell.label.text = currentTagsArray[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header", for: indexPath) as! Header
header.searchBar.delegate = self
return header
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.contentSize.width, height: 75)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.view.frame.size.width, height: 50)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.currentTagsArray = self.genericTagsArray.filter { (text) -> Bool in
return text.contains(searchText.lowercased())
}
}
}
class Cell : UICollectionViewCell {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
self.backgroundColor = .gray
self.addSubview(label)
label.anchor(top: self.topAnchor, leading: self.leadingAnchor, bottom: self.bottomAnchor, trailing: self.trailingAnchor)
}
}
class Header: UICollectionReusableView{
var searchBar = UISearchBar(frame: .zero)
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
self.backgroundColor = .gray
self.addSubview(searchBar)
searchBar.anchor(top: self.topAnchor, leading: self.leadingAnchor, bottom: nil, trailing: self.trailingAnchor, padding: .init(top: 0, left: 5, bottom: 0, right: 5), size: .init(width: 0, height: 50))
}
}
extension UIView {
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top {
topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
}
if let leading = leading {
leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
}
if let bottom = bottom {
bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true
}
if let trailing = trailing {
trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true
}
if size.width != 0 {
widthAnchor.constraint(equalToConstant: size.width).isActive = true
}
if size.height != 0 {
heightAnchor.constraint(equalToConstant: size.height).isActive = true
}
}
}
通过编辑更新函数
@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.feedScreenCollectionView.deleteItems()
VC.currentTagsArray.insert(feedSearchBar.text!, at: 0)
VC.feedScreenCollectionView.insertItems(at: [IndexPath(item: 0, section: 0)])
//VC.feedScreenCollectionView.reloadItems(inSection: 0)
// VC.feedScreenCollectionView.reloadItems(at: [IndexPath(item: 0, section: 0)])
}
//VC.feedScreenCollectionView.reloadData()
VC.feedScreenCollectionView.reloadItems(inSection: 0)
}
extension UICollectionView{
func reloadItems(inSection section:Int = 0) {
var indicies:[IndexPath] = [IndexPath]()
print("current number of items to reload \(self.numberOfItems(inSection: section))")
for i in 0..<self.numberOfItems(inSection: section){
indicies.append(IndexPath(item: i, section: section))
print("current item number: \(i)")
}
self.reloadItems(at: indicies)
// self.insertItems(at: indicies)
}
func deleteItems(inSection section:Int = 0){
var indicies:[IndexPath] = [IndexPath]()
for i in 0..<self.numberOfItems(inSection: section){
indicies.append(IndexPath(item: i, section: section))
}
self.deleteItems(at: indicies)
}
}
原始函数:
extension UICollectionView{
func reloadItems(inSection section:Int = 0) {
var indicies:[IndexPath] = [IndexPath]()
for i in 0..<self.numberOfItems(inSection: section){
indicies.append(IndexPath(item: i, section: section))
}
self.reloadItems(at: indicies)
}
}
但是,当我在编辑文本字段后调用此函数时,程序会因错误而崩溃
* Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.54.4/UICollectionView.m:5867 2018-07-18 16:28:02.226606-0400 FeedScreenReuseableView[87752:9704142] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert item 6 into section 0, but there are only 6 items in section 0 after the update'
我不确定如何解决这个问题。有没有更好的方法来重新加载不影响标题的单元格。提前感谢您的所有帮助。以下是该项目的完整代码。
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)])
}
}
}
最佳答案
你正在向你的 VC.currentTagsArray
添加一个新的字符串,但是你没有在你的 Collection View 上调用 insertItems(at:)
,所以当 numberOfItemsInSection
突然开始返回比之前更多的项目,你会得到一致性异常。
关于风格的一些其他观察:
VC
应该是vc
。大写第一个字母是一个类currentTags
而不是 currentTagsArray
关于ios - 调用 `reloadItems(at:)` 导致程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51411333/
我正在尝试使用 Spark 从 Cassandra 读取数据。 DataFrame rdf = sqlContext.read().option("keyspace", "readypulse
这是代码: void i_log_ (int error, const char * file, int line, const char * fmt, ...) { /* Get erro
我必须调试一个严重依赖 Gtk 的程序。问题是由于某些原因,在使用 GtkWindow 对象时开始出现许多运行时警告。问题是,即使 Gtk 提示严重错误,它也不会因这些错误而中止。我没有代码库的更改历
我正在尝试从已有效编译和链接的程序中检索二进制文件。我已经通过 GL_PROGRAM_BINARY_LENGTH 收到了它的长度。该文档说有两个实例可能会发生 GL_INVALID_OPERATION
我有一个托管在 Azure 环境中的服务。我正在使用控制台应用程序使用该服务。这样做时,我得到了异常: "The requested service, 'http://xxxx-d.yyyy.be/S
我有以下代码,它被 SEGV 信号杀死。使用调试器表明它被 main() 中的第一个 sem_init() 杀死。如果我注释掉第一个 sem_init() ,第二个会导致同样的问题。我试图弄清楚是什么
目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用核心数据进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数
我对 Xamarin.Forms 还是很陌生。我在出现的主页上有一个非常简单的功能 async public Task BaseAppearing() { if (UserID
这是我的代码的简化版本。 public class MainActivity extends ActionBarActivity { private ArrayList entry = new Arr
我想弄明白为什么我的两个 Java 库很难很好地协同工作。这是场景: 库 1 有一个类 A,其构造函数如下: public A(Object obj) { /* boilerplate */ } 在以
如果网站不需要身份验证,我的代码可以正常工作,如果需要,则在打印“已创建凭据”后会立即出现 EXC_BAD_ACCESS 错误。我不会发布任何内容,并且此代码是直接从文档中复制的 - 知道出了什么问题
我在使用 NSArray 填充 UITableView 时遇到问题。我确信我正在做一些愚蠢的事情,但我无法弄清楚。当我尝试进行简单的计数时,我得到了 EXC_BAD_ACCESS,我知道这是因为我试图
我在 UITableViewCell 上有一个 UITextField,在另一个单元格上有一个按钮。 我单击 UITextField(出现键盘)。 UITextField 调用了以下方法: - (BO
我有一个应用程序出现间歇性崩溃。崩溃日志显示了一个堆栈跟踪,这对我来说很难破译,因此希望其他人看到了这一点并能为我指出正确的方向。 基本上,应用程序在启动时执行反向地理编码请求,以在标签中显示用户的位
我开发了一个 CGImage,当程序使用以下命令将其显示在屏幕上时它工作正常: [output_view.layer performSelectorOnMainThread:@selector(set
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
我有一个中继器,里面有一些控件,其中一个是文本框。我正在尝试使用 jquery 获取文本框,我的代码如下所示: $("#").click(function (event) {}); 但我总是得到 nu
在以下场景中观察到 TTS 初始化错误,太随机了。 已安装 TTS 引擎,存在语音集,并且可以从辅助功能选项中播放示例 tts。 TTS 初始化在之前初始化和播放的同一设备上随机失败。 在不同的设备(
maven pom.xml org.openjdk.jol jol-core 0.10 Java 类: public class MyObjectData { pr
在不担心冲突的情况下,可以使用 MD5 作为哈希值,字符串长度最多为多少? 这可能是通过为特定字符集中的每个可能的字符串生成 MD5 哈希来计算的,长度不断增加,直到哈希第二次出现(冲突)。没有冲突的
我是一名优秀的程序员,十分优秀!