programing

self.tableView.reloadData()가 Swift에서 작동하지 않음

sourcejob 2023. 2. 16. 21:36
반응형

self.tableView.reloadData()가 Swift에서 작동하지 않음

배우려고 노력중이야Swift및 기본iOS동시에 dev도 할 수 있으니까 조금만 참아주세요.나 있어TableViewController즉, 우선 로컬을 해석하는 것입니다.JSON매우 간단한 데이터를 파일로 저장하고 렌더링합니다.TableViewCell및 섹션헤더 뷰같은 범위 내에서TableViewController에 전화를 걸고 있습니다.JSONendpoint: 데이터를 반환하고, 이를 변수로 설정하여 실제로 원하는 항목에 액세스할 수 있도록 합니다(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()
}

따라서 바이트를 추적할 수 있는 유연성은 없습니다.예를 들어 다운로드 진행 상황을 bytes를 통해 계산할 수 있습니다.다운로드/bytes Needed

다음을 입력하기만 하면 됩니다.

첫 번째 IBOutlet:

@IBOutlet var appsTableView : UITableView

다음으로 액션 기능:

self.appsTableView.reloadData()

연결이 백그라운드 스레드에 있는 경우 다음과 같이 메인 스레드에서 UI를 업데이트해야 합니다.

self.tblMainTable.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true)

이미 말씀드린 바와 같이

Swift 4:

self.tblMainTable.performSelector(onMainThread: #selector(UICollectionView.reloadData), with: nil, waitUntilDone: true)

저의 경우 테이블은 올바르게 갱신되어 있습니다만, 이미지에 대해 set Need Display()가 호출되지 않았기 때문에 데이터가 새로고침되지 않은 것으로 착각하고 있었습니다.

그래서 문제는 @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()
        }
    }
}

@lazy의 Swift Docs:

인스턴스 초기화가 완료될 때까지 초기값이 취득되지 않을 수 있으므로 항상 lazy 속성을 변수로 선언해야 합니다(var 키워드를 지정).상수 속성은 초기화가 완료되기 전에 항상 값이 있어야 하므로 지연으로 선언할 수 없습니다.

명백한 reloadData from UI/Main Thread(애플이 뭐라고 부르든) 외에 Sections 정보도 업데이트하지 않았습니다.그 때문에, 새로운 섹션은 검출되지 않았습니다.

UI에 대한 모든 호출은 비동기여야 합니다. UI에서 테이블 업데이트나 텍스트 레이블 변경 등 변경하는 모든 작업은 메인 스레드에서 수행해야 합니다.DispatchQueue.main을 사용하면 메인스레드의 큐에 조작이 추가됩니다.

스위프트 4

DispatchQueue.main.async{
    self.tableView.reloadData()
}

TableView는 메인 스레드에서만 새로고침해야 합니다.그렇지 않으면 앱이 크래시되거나 잠시 후에 업데이트됩니다.모든 UI 업데이트에는 메인 스레드를 사용하는 것이 좋습니다.

//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()
    })
}

시험: tableView.reloadSections(IndexSet(정수))입력: 0...0) (.automatic 포함)그것은 나에게 도움이 되었다

저도 같은 문제에 직면해 있었습니다만, 제가 잘못했던 것은, 추가되는 것을 잊은 것입니다.

tableView.delegate = self    
tableView.dataSource = self

viewDidLoad() {} 메서드로 지정합니다.이는 self.tableView.reloadData()가 작동하지 않는 이유 중 하나일 수 있습니다.

언급URL : https://stackoverflow.com/questions/24112844/self-tableview-reloaddata-not-working-in-swift

반응형