UICollectionViewCell 在刷新 swift 3 时失去价值
Posted
技术标签:
【中文标题】UICollectionViewCell 在刷新 swift 3 时失去价值【英文标题】:UICollectionViewCell loses value on refresh swift 3 【发布时间】:2017-04-18 08:50:26 【问题描述】:第一张图片显示,每当我单击 collectionview 上的单元格时,它都会在 View Controller 的标题视图上显示所选单元格的 ID: 现在我的问题是,每当我对集合视图的标题进行排序并单击一个单元格时,ID 就消失了:
我现在不知道该怎么办,因为我找不到有关此的相关帖子。这是我的代码:
import UIKit
private let reuseIdentifier = "Cell"
class MovieCollectionViewController: UICollectionViewController
private let leftAndRightPadding: CGFloat = 24.0
private let numberItemsPerRow: CGFloat = 2.0
private let heightAdustment: CGFloat = 90.0
var movies: [MOVIE]?
var filteredMovies: [MOVIE]?
var searchControllerMovie: UISearchController!
func filterContentForSearchTextMovie(searchText: String)
filteredMovies = movies?.filter
movie in
return (movie.movTitle?.lowercased().contains(searchText.lowercased()))!
collectionView?.reloadData()
override func viewDidLoad()
super.viewDidLoad()
self.searchControllerMovie = UISearchController(searchResultsController: nil)
self.searchControllerMovie.searchResultsUpdater = self
self.searchControllerMovie.searchBar.text = ""
self.searchControllerMovie.hidesNavigationBarDuringPresentation = false
self.searchControllerMovie.dimsBackgroundDuringPresentation = true
self.searchControllerMovie.obscuresBackgroundDuringPresentation = false
searchControllerMovie.searchBar.becomeFirstResponder()
self.navigationItem.titleView = searchControllerMovie.searchBar
//SPACING BETWEEN COLLECTION VIEW CELLS
let width = (collectionView!.frame.width - leftAndRightPadding) / numberItemsPerRow
let layout = collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: width + heightAdustment)
//LOADER
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
fetchMovie()
// Do any additional setup after loading the view.
setupNavBarButtons()
func setupNavBarButtons()
let sortAsc = UIBarButtonItem(image: UIImage(named: "arrow_up")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(sortMovieByAsc))
let sortDesc = UIBarButtonItem(image: UIImage(named: "arrow_down")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(sortMovieByDesc))
navigationItem.rightBarButtonItems = [sortDesc, sortAsc]
func sortMovieByAsc()
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
let queryItems = [NSURLQueryItem(name: "sortQuery", value: "Title Ascending" )]
let urlComps = NSURLComponents(string: "http://192.168.81.118:8080/mobileweb/android/getSortMovie")!
urlComps.queryItems = queryItems as [URLQueryItem]?
let URL = urlComps.url!
URLSession.shared.dataTask(with: URL, completionHandler: (data, response, error) -> Void in
if error != nil
print(error!)
return
do
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
self.movies = [MOVIE]()
for dictionary in json as! [[String: AnyObject]]
let movie = MOVIE()
movie.movTitle = dictionary["TITLE"] as? String
movie.movImage = dictionary["PHOTO_DIR"] as? String
self.movies?.append(movie)
DispatchQueue.main.async
self.dismiss(animated: false, completion: nil)
self.collectionView?.reloadData()
catch let jsonError
print(jsonError)
).resume()
func sortMovieByDesc()
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
let queryItems = [NSURLQueryItem(name: "sortQuery", value: "Title Descending" )]
let urlComps = NSURLComponents(string: "http://192.168.81.118:8080/mobileweb/Android/getSortMovie")!
urlComps.queryItems = queryItems as [URLQueryItem]?
let URL = urlComps.url!
URLSession.shared.dataTask(with: URL, completionHandler: (data, response, error) -> Void in
if error != nil
print(error!)
return
do
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
self.movies = [MOVIE]()
for dictionary in json as! [[String: AnyObject]]
let movie = MOVIE()
movie.movTitle = dictionary["TITLE"] as? String
movie.movImage = dictionary["PHOTO_DIR"] as? String
self.movies?.append(movie)
DispatchQueue.main.async
self.dismiss(animated: false, completion: nil)
self.collectionView?.reloadData()
self.collectionView?.reloadData()
catch let jsonError
print(jsonError)
).resume()
func fetchMovie()
let url = URL(string: "http://192.168.81.118:8080/mobileweb/Android/getMovie")
URLSession.shared.dataTask(with: url!, completionHandler: (data, response, error) -> Void in
if error != nil
print(error!)
return
do
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
self.movies = [MOVIE]()
for dictionary in json as! [[String: AnyObject]]
let movie = MOVIE()
movie.movTitle = dictionary["TITLE"] as? String
movie.movImage = dictionary["PHOTO_DIR"] as? String
movie.movID = dictionary["ID"] as? String
self.movies?.append(movie)
DispatchQueue.main.async
self.dismiss(animated: false, completion: nil)
self.collectionView?.reloadData()
catch let jsonError
print(jsonError)
).resume()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
*/
// MARK: UICollectionViewDataSource
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
if searchControllerMovie.isActive && searchControllerMovie.searchBar.text != ""
return (filteredMovies?.count)!
// #warning Incomplete implementation, return the number of items
return movies?.count ?? 0
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cellIdentifier = "MovieCollectionViewCell"
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? MovieCollectionViewCell
if searchControllerMovie.isActive && searchControllerMovie.searchBar.text != ""
cell?.movie = filteredMovies?[indexPath.row]
else
// Configure the cell
cell?.movie = movies?[indexPath.row]
return cell!
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
print("Row:\(indexPath.row)")
// let cell = collectionView.cellForItem(at: indexPath);
// self.performSegue(withIdentifier: "showDetail", sender: cell)
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if let indexPath = self.collectionView?.indexPath(for: sender as! UICollectionViewCell)
let movieDetail: MOVIE
if searchControllerMovie.isActive && searchControllerMovie.searchBar.text != ""
movieDetail = (filteredMovies?[indexPath.item])!
else
movieDetail = (movies?[indexPath.row])!
let controller = segue.destination as! MovieDetailsViewController
controller.movieDetail = movieDetail
extension MovieCollectionViewController: UISearchResultsUpdating
func updateSearchResults(for searchController: UISearchController)
filterContentForSearchTextMovie(searchText: searchController.searchBar.text!)
【问题讨论】:
1. i.stack.imgur.com/EJ2Se.png2.i.stack.imgur.com/FRIsV.png 当您在此处打印movieDetail 时,movieDetail 始终是正确的MOVIE 对象:controller.movieDetail = movieDetail。 ? 我没有明白你的意思,先生@rett 【参考方案1】:你需要添加这一行,过滤数据时忘记添加这一行..
func sortMovieByDesc()
for dictionary in json as! [[String: AnyObject]]
let movie = MOVIE()
movie.movTitle = dictionary["TITLE"] as? String
movie.movImage = dictionary["PHOTO_DIR"] as? String
movie.movID = dictionary["ID"] as? String // this line
self.movies?.append(movie)
func sortMovieByAsc()
for dictionary in json as! [[String: AnyObject]]
let movie = MOVIE()
movie.movTitle = dictionary["TITLE"] as? String
movie.movImage = dictionary["PHOTO_DIR"] as? String
movie.movID = dictionary["ID"] as? String // this line
self.movies?.append(movie)
【讨论】:
我是这里的新手,所以现在(我需要获得 15 个声望),以便我可以为您的评论点赞。对不起【参考方案2】:collectionViews 不使用 indexPath.row,它们使用 indexPath.item。
改变
movieDetail = (movies?[indexPath.row])!
收件人
movieDetail = (movies?[indexPath.item])!
【讨论】:
我已经将其更改为(项目),但当我对集合视图进行排序时,我无法获取所选单元格的值以上是关于UICollectionViewCell 在刷新 swift 3 时失去价值的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionViewCell 在刷新 swift 3 时失去价值
iOS bug记录UICollectionviewCell刷新变得这么莫名其妙?
使用 reloadItemsAtIndexPaths 重新加载 UICollectionViewCell 的 footerView