self.tableView.reloadData ()가 Swift에서 작동하지 않습니다.
나는 동시에 개발 Swift
의 기본과 배우려고 시도하고 iOS
있으므로 저를 참아주세요. 내가있어 TableViewController
먼저 로컬 구문 분석되는 JSON
파일을하고에 아주 간단한 데이터의 렌더링 TableViewCell
및 SectionHeaderViews을. 동일한 내에서 데이터를 반환 TableViewController
하는 JSON
끝점을 호출하고 있으며 ,이 데이터를 변수로 설정하여 실제로 얻고 자하는 항목에 액세스 할 수 있습니다 (API 구조가 바람직하지 않음). 그래서 마침내 적절한 데이터를 설정하고 self.tableData
호출 self.tableView.reloadData()
했지만 아무 일도 일어나지 않습니다. 무엇을 제공합니까?
import UIKit
class BusinessTableViewController: UITableViewController {
var data: NSMutableData = NSMutableData()
var tableData: NSArray = NSArray()
@lazy var Business: NSArray = {
let pathTCT = NSBundle.mainBundle().pathForResource("TCT", ofType: "json")
let data = NSData.dataWithContentsOfFile(pathTCT, options: nil, error: nil)
return NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as NSArray
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = UIImageView(image: UIImage(named: "growler"))
tableView.registerClass(BeerTableViewCell.self, forCellReuseIdentifier: "cell")
tableView.separatorStyle = .None
fetchKimono()
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
// return Business.count
return 1
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
let biz = Business[section] as NSDictionary
let results = biz["results"] as NSDictionary
let beers = results["collection1"] as NSArray
return beers.count
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath!) as BeerTableViewCell
if let path = indexPath {
let biz = Business[path.section] as NSDictionary
let results = biz["results"] as NSDictionary
let beers = results["collection1"] as NSArray
let beer = beers[path.row] as NSDictionary
cell.titleLabel.text = beer["BeerName"] as String
}
return cell
}
override func tableView(tableView: UITableView!, titleForHeaderInSection section: Int) -> String! {
let biz = Business[section] as NSDictionary
return biz["name"] as String
}
override func tableView(tableView: UITableView!, viewForHeaderInSection section: Int) -> UIView! {
let biz = Business[section] as NSDictionary
let view = LocationHeaderView()
view.titleLabel.text = (biz["name"] as String).uppercaseString
return view
}
override func tableView(tableView: UITableView!, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func fetchKimono() {
var urlPath = "names have been changed to protect the innocent"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.start()
}
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
// Recieved a new request, clear out the data object
self.data = NSMutableData()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
// Append the recieved chunk of data to our data object
self.data.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
// Request complete, self.data should now hold the resulting info
// Convert the retrieved data in to an object through JSON deserialization
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var results: NSDictionary = jsonResult["results"] as NSDictionary
var collection: NSArray = results["collection1"] as NSArray
if jsonResult.count>0 && collection.count>0 {
var results: NSArray = collection as NSArray
self.tableData = results
self.tableView.reloadData()
}
}
}
다음을 UI
통해 스레드 에서 테이블을 다시로드해야합니다 .
//swift 2.3
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
//swift 5
DispatchQueue.main.async{
self.tableView.reloadData()
}
후속 조치 : connection.start()
접근 방식에 대한 더 쉬운 대안 은NSURLConnection.sendAsynchronousRequest(...)
//NSOperationQueue.mainQueue() is the main thread
NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: url), queue: NSOperationQueue.mainQueue()) { (response, data, error) -> Void in
//check error
var jsonError: NSError?
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &jsonError)
//check jsonError
self.collectionView?.reloadData()
}
예를 들어 bytesDownloaded / bytesNeeded를 통해 다운로드 진행률을 계산하고 싶을 수 있습니다.
다음을 입력하면됩니다.
먼저 IBOutlet :
@IBOutlet var appsTableView : UITableView
그런 다음 Action func에서 :
self.appsTableView.reloadData()
연결이 백그라운드 스레드에있는 경우 다음과 같이 메인 스레드에서 UI를 업데이트해야합니다.
self.tblMainTable.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true)
스위프트 4 :
self.tblMainTable.performSelector(onMainThread: #selector(UICollectionView.reloadData), with: nil, waitUntilDone: true)
제 경우에는 테이블이 올바르게 업데이트되었지만 이미지에 대해 setNeedDisplay ()가 호출되지 않았으므로 데이터가 다시로드되지 않는다고 잘못 생각했습니다.
그래서 문제는 @lazy를 부적절하게 사용하려고했기 때문에 비즈니스 변수가 본질적으로 상수가되어 편집 할 수 없게되었습니다. 또한 로컬 json을로드하는 대신 API에서 반환 된 데이터 만로드합니다.
import UIKit
class BusinessTableViewController: UITableViewController {
var data: NSMutableData = NSMutableData()
var Business: NSMutableArray = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = UIImageView(image: UIImage(named: "growler"))
tableView.registerClass(BeerTableViewCell.self, forCellReuseIdentifier: "cell")
tableView.separatorStyle = .None
fetchKimono()
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return Business.count
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
if (Business.count > 0) {
let biz = Business[section] as NSDictionary
let beers = biz["results"] as NSArray
return beers.count
} else {
return 0;
}
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath!) as BeerTableViewCell
if let path = indexPath {
let biz = Business[path.section] as NSDictionary
let beers = biz["results"] as NSArray
let beer = beers[path.row] as NSDictionary
cell.titleLabel.text = beer["BeerName"] as String
} else {
cell.titleLabel.text = "Loading"
}
return cell
}
override func tableView(tableView: UITableView!, viewForHeaderInSection section: Int) -> UIView! {
let view = LocationHeaderView()
let biz = Business[section] as NSDictionary
if (Business.count > 0) {
let count = "\(Business.count)"
view.titleLabel.text = (biz["name"] as String).uppercaseString
}
return view
}
override func tableView(tableView: UITableView!, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func fetchKimono() {
var urlPath = "names have been removed to protect the innocent"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.start()
}
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
// Recieved a new request, clear out the data object
self.data = NSMutableData()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
// Append the recieved chunk of data to our data object
self.data.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
// Request complete, self.data should now hold the resulting info
// Convert the retrieved data in to an object through JSON deserialization
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var results: NSDictionary = jsonResult["results"] as NSDictionary
var collection: NSArray = results["collection1"] as NSArray
if jsonResult.count>0 && collection.count>0 {
Business = jsonResult
tableView.reloadData()
}
}
}
You must always declare a lazy property as a variable (with the var keyword), because its initial value may not be retrieved until after instance initialization completes. Constant properties must always have a value before initialization completes, and therefore cannot be declared as lazy.
Beside the obvious reloadData from UI/Main Thread (whatever Apple calls it), in my case, I had forgotten to also update the SECTIONS info. Therefor it did not detect any new sections!
All the calls to UI should be asynchronous, anything you change on the UI like updating table or changing text label should be done from main thread. using DispatchQueue.main will add your operation to the queue on the main thread.
Swift 4
DispatchQueue.main.async{
self.tableView.reloadData()
}
You must reload your TableView in main thread only. Otherwise your app will be crashed or will be updated after some time. For every UI update it is recommended to use main thread.
//To update UI only this below code is enough
//If you want to do changes in UI use this
DispatchQueue.main.async(execute: {
//Update UI
self.tableView.reloadData()//Your tableView here
})
//Perform some task and update UI immediately.
DispatchQueue.global(qos: .userInitiated).async {
// Call your function here
DispatchQueue.main.async {
// Update UI
self.tableView.reloadData()
}
}
//To call or execute function after some time and update UI
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
//If you want to do changes in UI use this
DispatchQueue.main.async(execute: {
//Update UI
self.tableView.reloadData()
})
}
I was also facing the same issue, what I did wrong was that I'd forgot to add
tableView.delegate = self
tableView.dataSource = self
in the viewDidLoad() {} method. This could be one reason of self.tableView.reloadData() not working.
ReferenceURL : https://stackoverflow.com/questions/24112844/self-tableview-reloaddata-not-working-in-swift
'code' 카테고리의 다른 글
iPhone X에서 UIView의 safeAreaInsets가 0입니다. (0) | 2021.01.10 |
---|---|
대량 API를 사용하여 Python을 사용하여 ES에 키워드를 저장하는 방법 (0) | 2021.01.09 |
Android-알림 빌드, TaskStackBuilder.addParentStack이 작동하지 않음 (0) | 2021.01.09 |
대용량 (14GB) MySQL 덤프 파일을 새 MySQL 데이터베이스로 가져 오려면 어떻게해야합니까? (0) | 2021.01.09 |
GDB를 프로세스에 연결하려고 할 때 "ptrace 작업이 허용되지 않음"을 해결하는 방법은 무엇입니까? (0) | 2021.01.09 |