gpt4 book ai didi

ios - CollectionView 与 TableView(快速)

转载 作者:行者123 更新时间:2023-11-28 08:00:21 25 4
gpt4 key购买 nike

我有两个类做完全相同的事情,加载用户位置附近所选类别的位置,但一个使用 collectionView,另一个使用 tableView(和特定动画)。

我只添加了解决问题的代码部分,虽然有些名称不同,但 Storyboard和其他类的所有链接都是相同的,因为您可以看到这两个类之间的大部分代码非常相似。

我的问题是带有 collectionView 的类工作得很好,但是使用 tableView 的类没有显示 tableView 的单元格(好像它没有正确加载它)如果有人能看到是否有错误,我会不胜感激。

这是使用 collectionView 的类:

import UIKit
import CoreLocation
import AVFoundation

private let reuseIdentifier = "PlacesCell"

extension UIViewController {
func present(viewController : UIViewController, completion : (() -> ())? = nil ){
if let presented = self.presentedViewController {
presented.removeFromParentViewController()
}
self.present(viewController, animated: true, completion: completion)
}
}

class NearbyPlacesViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

var locationManager:CLLocationManager?

let minimumSpacing : CGFloat = 15 //CGFloat(MAXFLOAT)
let cellWidth: CGFloat = 250
let radius = 5000 // 5km
var category : QCategory?
var currentLocation : CLLocationCoordinate2D?
var places: [QPlace] = []

var isLoading = false
var response : QNearbyPlacesResponse?

override func viewDidLoad() {
super.viewDidLoad()

//self.collectionView
self.title = category?.name

collectionView?.contentInset = UIEdgeInsets.init(top: 0, left: minimumSpacing, bottom: 0, right: minimumSpacing)
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

determineMyCurrentLocation()
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
category?.markView()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func canLoadMore() -> Bool {
if isLoading {
return false
}

if let response = self.response {
if (!response.canLoadMore()) {
return false
}
}
return true
}

func loadPlaces(_ force:Bool) {

if !force {
if !canLoadMore() {
return
}
}

print("load more")
isLoading = true
NearbyPlacesController.getNearbyPlaces(by: category?.name ?? "food", coordinates: currentLocation!, radius: radius, token: self.response?.nextPageToken, completion: didReceiveResponse)
}

func didReceiveResponse(response:QNearbyPlacesResponse?, error : Error?) -> Void {
if let error = error {
let alertController = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
let actionDismiss = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil)
let actionRetry = UIAlertAction(title: "Retry", style: .default, handler: { (action) in
DispatchQueue.main.async {
self.loadPlaces(true)
}
})
alertController.addAction(actionRetry)
alertController.addAction(actionDismiss)
DispatchQueue.main.async {
self.present(viewController: alertController)
}
}
if let response = response {
self.response = response
if response.status == "OK" {
if let placesDownloaded = response.places {
places.append(contentsOf: placesDownloaded)
}

self.collectionView?.reloadData()
} else {
let alert = UIAlertController.init(title: "Error", message: response.status, preferredStyle: .alert)
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
alert.addAction(UIAlertAction.init(title: "Retry", style: .default, handler: { (action) in
DispatchQueue.main.async {
self.loadPlaces(true)
}
}))
self.present(viewController: alert)
}
isLoading = false
}
else {
print("response is nil")
}
}

// MARK: UICollectionViewDataSource

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return places.count
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PlacesCell

let place = places[indexPath.row]
cell.update(place: place)

if indexPath.row == places.count - 1 {
loadPlaces(false)
}

return cell
}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
performSegue(withIdentifier: "maps-vc", sender: indexPath)
}

// MARK: UICollectionViewDelegateFlowLayoutDelegate

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return minimumSpacing
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

let cellPadding: CGFloat = 20.0
let columnWidth:CGFloat = cellWidth
let imageWidth = columnWidth
let labelWidth = columnWidth - cellPadding * 2

let photoHeight = heightForPhotoAtIndexPath(indexPath: indexPath, withWidth: imageWidth)
let annotationHeight = heightForAnnotationAtIndexPath(indexPath: indexPath, withWidth: labelWidth)
let height = photoHeight + annotationHeight

return CGSize.init(width: columnWidth, height: height)
}

// Calculates the height of photo
func heightForPhotoAtIndexPath(indexPath: IndexPath,
withWidth width: CGFloat) -> CGFloat {

var size = CGSize.init(width: CGFloat(MAXFLOAT), height: 1)
let place = places[indexPath.row]

guard let photo = place.photos?.first, place.photos?.first?.photoRef != nil else {
return 0
}

size = CGSize.init(width: CGFloat(photo.width!), height: CGFloat(photo.height!))

let boundingRect = CGRect(x: 0, y: 0, width: width, height: CGFloat(MAXFLOAT))
let rect = AVMakeRect(aspectRatio: size, insideRect: boundingRect)

return rect.size.height
}

// Calculates the height label
func heightForAnnotationAtIndexPath(indexPath: IndexPath, withWidth width: CGFloat) -> CGFloat {

let place = places[indexPath.row]
let annotationPadding = CGFloat(5)

let font = UIFont.systemFont(ofSize: 15)
let commentHeight = place.heightForComment(font, width: width)

let height = annotationPadding + commentHeight + annotationPadding

return height
}

// did receive location

func didReceiveUserLocation(_ userLocation:CLLocation) {
currentLocation = userLocation.coordinate

loadPlaces(true)
}
// 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?) {
if segue.identifier == "maps-vc" && sender is IndexPath {
let dvc = segue.destination as! MapViewController
dvc.index = (sender as! IndexPath).row
dvc.places = places
dvc.userLocation = currentLocation
}
}
}

这是使用 tableView 的类:

import UIKit
import MapKit
import CoreLocation
import GoogleMaps
import GooglePlaces
import Social
import AVFoundation

private let resueIdentifier = "MyTableViewCell"

extension UIViewController {
func present(viewController : UIViewController, completion : (() -> ())? = nil ){
if let presented = self.presentedViewController {
presented.dismiss(animated: true, completion: {
self.present(viewController, animated: true, completion: completion)
})
} else {
self.present(viewController, animated: true, completion: completion)
}
}
}

class CourseClass2: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

var locationManager:CLLocationManager?
let minimumSpacing : CGFloat = 15 //CGFloat(MAXFLOAT)
let cellWidth: CGFloat = 250
let radius = 5000 // 5km
var category : QCategoryy?
var currentLocation : CLLocationCoordinate2D?
var places: [QPlace] = []
var isLoading = false
var response : QNearbyPlacesResponse?
var rows = 0

override func viewDidLoad() {
super.viewDidLoad()
self.title = category?.name
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
determineMyCurrentLocation()
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

rows = 0
insertRowsMode3()
tableView.reloadData()
category?.markView()
}
@IBAction func refreshTapped(_ sender: Any) {
rows = 0
insertRowsMode3()
tableView.reloadData()
}

func canLoadMore() -> Bool {
if isLoading {
return false
}
if let response = self.response {
if (!response.canLoadMore()) {
return false
}
}
return true
}

func loadPlaces(_ force:Bool) {

if !force {
if !canLoadMore() {
return
}
}

print("load more")
isLoading = true
NearbyPlaces.getNearbyPlaces(by: category?.name ?? "food", coordinates: currentLocation!, radius: radius, token: self.response?.nextPageToken, completion: didReceiveResponse)
}

func didReceiveResponse(response:QNearbyPlacesResponse?, error : Error?) -> Void {
if let error = error {
let alertController = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
let actionDismiss = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil)
let actionRetry = UIAlertAction(title: "Retry", style: .default, handler: { (action) in
DispatchQueue.main.async {
self.loadPlaces(true)
}
})
alertController.addAction(actionRetry)
alertController.addAction(actionDismiss)
DispatchQueue.main.async {
self.present(viewController: alertController)

}
}
if let response = response {
self.response = response
if response.status == "OK" {
if let placesDownloaded = response.places {
places.append(contentsOf: placesDownloaded)
}

self.tableView?.reloadData()
} else {
let alert = UIAlertController.init(title: "Error", message: response.status, preferredStyle: .alert)
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
alert.addAction(UIAlertAction.init(title: "Retry", style: .default, handler: { (action) in
DispatchQueue.main.async {
self.loadPlaces(true)
}
}))
self.present(viewController: alert)
}
isLoading = false
}
else {
print("response is nil")
}
}
func insertRowsMode2() {

tableView.beginUpdates()
for i in 0..<places.count {
insertRowMode2(ind: i, usr: places[i])
}
tableView.endUpdates()
}

func insertRowMode2(ind:Int,usr:QPlace) {
tableView.beginUpdates()
let indPath = IndexPath(row: ind, section: 0)

rows = ind + 1
tableView.insertRows(at: [indPath], with: .right)
tableView.endUpdates()
}

func insertRowsMode3() {
tableView.beginUpdates()
rows = 0

insertRowMode3(ind: 0)
tableView.endUpdates()
}
func insertRowMode3(ind:Int) {
tableView.beginUpdates()
let indPath = IndexPath(row: ind, section: 0)
rows = ind + 1
tableView.insertRows(at: [indPath], with: .right)

guard ind < places.count-1 else { return }
DispatchQueue.main.asyncAfter(deadline: .now()+0.20) {

self.insertRowMode3(ind: ind+1)
}
tableView.endUpdates()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return places.count /* rows */
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell

let place = places[indexPath.row]
cell.update(place: place)

if indexPath.row == places.count - 1 {
loadPlaces(false)
}

return (cell)
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

tableView.deselectRow(at: indexPath, animated: true)

UIView.animate(withDuration: 0.2, animations: {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
})

performSegue(withIdentifier: "goToLast" , sender: indexPath.row)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

if editingStyle == UITableViewCellEditingStyle.delete {

places.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)

}
}
func didReceiveUserLocation(_ userLocation:CLLocation) {
currentLocation = userLocation.coordinate

loadPlaces(true)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToLast" && sender is IndexPath {

let dvc = segue.destination as! FinalClass
dvc.index = (sender as! IndexPath).row
dvc.places = places
dvc.userLocation = currentLocation

}
}

@IBAction func IndTapped(_ sender: Any) {
dismiss(animated: true, completion: nil)

}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

最佳答案

您是否将 CourseClass2 类设置为您的 tableView 的委托(delegate)/数据源?

尝试添加

tableView.dataSource = self
tableView.delegate = self

到您的 viewDidLoad 方法。

几乎每次我遇到像你这样的问题都是因为我忘记设置委托(delegate)或数据源。

编辑:我之前只在我的回答中添加了委托(delegate),感谢丹尼斯提醒我数据源。

关于ios - CollectionView 与 TableView(快速),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46814257/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com