gpt4 book ai didi

ios - 嵌入容器中的 UITableView 不刷新

转载 作者:行者123 更新时间:2023-11-30 13:40:42 32 4
gpt4 key购买 nike

简而言之,我想确定用户的位置,从源获取一些 JSON 数据(需要首先知道位置),然后根据返回的数据创建一个表。

我在 Xcode 7 中使用 Swift 有一个带有一个原型(prototype)单元的自定义 UITableView。当此 TableView 是初始 View 时,它加载得很好。

现在,我尝试 1)将其嵌入到另一个 UIView 的容器中,2)在数据发生变化时更新它。两者都不起作用...容器中的表格永远不会出现。我已经在这上面花了近一周的时间,现在有点疯狂(这是我的第一个 iOS 应用程序)。

我注意到的一些事情:

  1. reloadData、setNeedsDisplay 和 setNeedsLayout 似乎没有执行任何操作。
  2. cellForRowAtIndexPath 未被调用,但 numberOfRowsInSection 被调用。
  3. 我尝试从父 UIView 以及 TableViewController 调用第 1 条中列出的所有函数。

以下是当前代码的样子: View Controller :

import UIKit
import MapKit
import CoreLocation
var currentLatLong: String = ""



class ViewController: UIViewController, CLLocationManagerDelegate {
// global var for location
let locationManager = CLLocationManager()
var currentLocation = CLLocation()
var lastLatLong: String = ""

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

// get permission and user's location
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.startUpdatingLocation()
} else {
print("Location services are not enabled")
}
}

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

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
currentLocation = locations.last!
currentLatLong = "\(currentLocation.coordinate.latitude)%2C\(currentLocation.coordinate.longitude)"
if lastLatLong != currentLatLong {
lastLatLong = currentLatLong
NSNotificationCenter.defaultCenter().postNotificationName("updateOverview", object: nil)
self.view.setNeedsDisplay()
self.view.setNeedsLayout()
print("Found user's location: \(location)")

}
//print("Found user's location: \(location)")
}
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Failed to find user's location: \(error.localizedDescription)")
}
}

UITableViewController:

import UIKit
import MapKit
import CoreLocation

class OverviewTableViewController: UITableViewController {

var LocRepositories = [LocationJSON]()
var TimesRepositories = [TimesJSON]()
var retrieved = [dataModelDefn]()

override func viewDidLoad() {
super.viewDidLoad()


NSNotificationCenter.defaultCenter().removeObserver(self, name: "updateOverview", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "checkRes", name: "updateOverview", object: nil)


// fetch location data

let backgroundQueue:dispatch_queue_t = dispatch_queue_create("com.example.workQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(backgroundQueue, {
self.getLocations()
dispatch_async(dispatch_get_main_queue(), {self.tableView.reloadData()})
})
}

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

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return retrieved.count
}



override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

// initialize data & cell
var cell = tableView.dequeueReusableCellWithIdentifier("EDOverviewCell", forIndexPath: indexPath) as! OverviewTableCell
var rowData = retrieved[indexPath.row]


/* update cell */

// border for cell
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
self.tableView.separatorColor = UIColor(red:(0/255.0), green:(128/255.0), blue:(128/255.0), alpha:1)


// alternating row colors
if indexPath.row % 2 == 0 {
cell.backgroundColor = UIColor(red:(249/255.0), green:(238/255.0), blue:(188/255.0), alpha:0.5)
}
else{
cell.backgroundColor = UIColor(red:(252/255.0), green:(244/255.0), blue:(220/255.0), alpha:0.5)
}

return cell
}

func checkRes()
{
// fetch new data because location available
getLocations()
//self.tableView.reloadData()
//dispatch_async(dispatch_get_main_queue(),{ self.tableView.reloadData() })
}

func getLocations(){
// fetch demographic/location info

// abort call if no location
if currentLatLong == "" {
return
}

/* get JSON data */
}
}

以下是我尝试模仿解决方案的一些相关问题: Loading data after one second in uitableview. Any alternate way to eliminate this delay

How to stop UITableView from loading until data has been fetched?

UITableView doesn't populate when waiting for CLLocationManagerDelegate 's didUpdateToLocation method on iPhone SDK

这是一篇很长的文章,但如果我遗漏了任何必要的细节,请告诉我。我感谢任何帮助。

最佳答案

您当前拥有以下代码:

    let backgroundQueue:dispatch_queue_t = dispatch_queue_create("com.example.workQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(backgroundQueue, {
self.getLocations()
dispatch_async(dispatch_get_main_queue(), {self.tableView.reloadData()})
})

这将在后台线程中运行getLocations,然后在主线程上刷新表tableView。都好。然而,getLocations 本身会执行一个 JSON 调用(当前只是一个注释),这无疑也在另一个后台线程上运行。因此,getLocations 将几乎立即返回,远远早于 JSON 完成。

您应该将完成处理程序传递给 getLocations,并且当 JSON 完成时(在其完成处理程序中),调用您自己的完成处理程序。大致如下:

    let backgroundQueue:dispatch_queue_t = dispatch_queue_create("com.example.workQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(backgroundQueue, {
self.getLocations(completion: {
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
})
})

(我这里的大括号可能不匹配)。然后 getLocations 定义为:

func getLocations(completion completion: (() -> Void)){
// fetch demographic/location info

// abort call if no location
if currentLatLong == "" {
return
}

getTheJsonAndInItsCompletion(... success: {
completion()
})
}

实际的 JSON 实现将取决于您使用的库。

关于ios - 嵌入容器中的 UITableView 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35589996/

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