【发布时间】:2016-02-23 23:04:01
【问题描述】:
简而言之,我想确定用户的位置,从源中获取一些 JSON 数据(这需要首先知道位置),然后根据返回的数据创建一个表。
我在 Xcode 7 中有一个使用 Swift 的自定义 UITableView 和一个原型单元。当这个表视图是初始视图时,它加载得很好。
现在,我正在尝试 1) 将其嵌入到另一个 UIView 的容器中,并且 2) 在其数据更改时更新它。两者都不起作用......容器中的表格永远不会出现。我在这上面花了将近一个星期的时间,现在有点疯狂(这是我的第一个 iOS 应用)。
我注意到的一些事情:
- reloadData、setNeedsDisplay 和 setNeedsLayout 似乎没有任何作用。
- cellForRowAtIndexPath 未被调用,但 numberOfRowsInSection 被调用。
- 我尝试从父 UIView 和 TableViewController 调用项目符号 1 中列出的所有函数。
下面是代码当前的样子: 视图控制器:
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?
这篇文章很长,但如果我遗漏了任何必要的细节,请告诉我。感谢您的帮助。
【问题讨论】:
-
在 getLocations() 中 currentLatLong 是否曾经是一个非空字符串?当您在新视图中嵌入 uitableview 时,通常不会保留整个 uitableviewcontroller。您只需将 tableview 设置为第一个视图控制器的子视图,并根据需要实现 UITableViewDataSource 和 UITableViewDelegate。
-
试试Xcode View Debugger看看tableview在哪里。也许有一个约束迫使它离开屏幕。另外,从 numberOfRowsInSection 返回的值是否不是 0?
-
-
@Clever - 我什至不知道它的存在。一旦我让表中的数据出现但它更小并且完全偏离目标,它确实有助于解决一个问题。这是一个超级有用的实用程序。