2016-11-02 3 views
0

이 데이터를 표시하려고합니다. image.Swift : 파싱 된 JSON 데이터를 TableView 내의 CollectionView에 표시하는 방법?

제 문제는 배열의 모든 데이터를 표시해야하지만 테이블 뷰 행에 표시되는 데이터는 모두 똑같은 것입니다.

var onlineNews = ["local", "Economy", "Variety", "international", "sport"] 

var storedOffsets = [Int: CGFloat]() 

var tableIndexPath: IndexPath! 

@IBOutlet var listTableView: UITableView! 

var tableIndex: Int = 0 

var categoryResults = [JSON]() { 
    didSet { 
     listTableView.reloadData() 
    } 
} 

let requestManager = RequestManager() 


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

    for i in onlineNews { 
     requestManager.categoryList(sectionName: i) 
    } 
} 


func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! NewsTableViewCell 

    tableIndex = indexPath.row 

    return cell 
} 

func tableView(_ tableView: UITableView, 
       willDisplay cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 
     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: (indexPath as NSIndexPath).row) 
     tableViewCell.collectionViewOffset = storedOffsets[(indexPath as NSIndexPath).row] ?? 0 
} 

func tableView(_ tableView: UITableView, 
       didEndDisplaying cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 

     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     storedOffsets[(indexPath as NSIndexPath).row] = tableViewCell.collectionViewOffset 
} 

func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 1 
} 

func collectionView(_ collectionView: UICollectionView, 
        numberOfItemsInSection section: Int) -> Int { 

    return categoryResults.count 
} 

func collectionView(_ collectionView: UICollectionView, 
        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColCell", 
                for: indexPath) as! NewsCollectionViewCell 


    cell.contentType.text = categoryResults[indexPath.row]["ContentType"].stringValue **// This is where I get the same values for all table view rows** 
    cell.sectionName.text = onlineNews[tableIndex] 


    return cell 
} 

나는 그것이 작동하도록 단지 작은 비틀기를 소요 알고있는 누군가가 절대적으로이 좀 도와 수 있습니다 확신 :

이 내가있는 tableView 내부의 collectionView을 표시하는 데 사용되는 코드는 , 그러나 확실하지 않은 곳.

업데이트 : 나는 JSON 배열을 선언하는 것입니다 내가 일을한다고 생각하는 방법을 따랐다

이 [[JSON]]처럼, 다음 categoryResults [collection.tag] [사용 indexPath.item] [ "ContentType"]. 값을 얻기위한 stringValue. 그러나, 그것은 나를 "범위를 벗어난 색인"메시지를 제공합니다. 어떻게 문제를 해결할 수 있는지 실마리가 있습니까?

var onlineNews = ["local", "Economy", "Variety", "international", "sport"] 

var storedOffsets = [Int: CGFloat]() 

@IBOutlet var listTableView: UITableView! 

var tableIndex: Int = 0 

var categoryResults = [[JSON]]() { // updated 
    didSet { 
     listTableView.reloadData() 
    } 
} 

let requestManager = RequestManager() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    requestManager.resetCategory() 

    updateSearchResults() 

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateSearchResults), name: NSNotification.Name(rawValue: "categoryResultsUpdated"), object: nil) 


} 

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

    for i in 0..<onlineNews.count { 
     requestManager.categoryList(sectionName: onlineNews[i]) 


    } 

} 

func updateSearchResults() { 
    categoryResults = [requestManager.categoryResults] // updated 
} 

func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! NewsTableViewCell 

    tableIndex = indexPath.row 

    return cell 
} 

func tableView(_ tableView: UITableView, 
       willDisplay cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 
     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: (indexPath as NSIndexPath).row) 
     tableViewCell.collectionViewOffset = storedOffsets[(indexPath as NSIndexPath).row] ?? 0 

} 

func tableView(_ tableView: UITableView, 
       didEndDisplaying cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 

     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     storedOffsets[(indexPath as NSIndexPath).row] = tableViewCell.collectionViewOffset 


} 

func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 1 
} 


func collectionView(_ collectionView: UICollectionView, 
        numberOfItemsInSection section: Int) -> Int { 
    return categoryResults[collectionView.tag].count // updated 
} 


func collectionView(_ collectionView: UICollectionView, 
        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColCell", 
                for: indexPath) as! NewsCollectionViewCell 


    cell.contentType.text = categoryResults[collectionView.tag][indexPath.row]["ContentType"].stringValue // updated 



    return cell 
} 

이 (필자는 API를 호출) RequestManager 클래스의 내용

:

var categoryResults = [JSON]() 

func categoryList(sectionName: String) { 

    let url = "http://mobile.example.com/api/Content?MobileRequest=GetCategoryNews&PageNo=1&RowsPerPage=10&Category=\(sectionName)&IssueID=0&Type=online" 
    print("this is the url \(url)") 

    Alamofire.request(url, method: .get).responseJSON{ response in 
     if let results = response.result.value as? [String:AnyObject] { 
      let items = JSON(results["Data"]?["OnlineCategoryNews"]! as Any).arrayValue 

      self.categoryResults += items 

      NotificationCenter.default.post(name: NSNotification.Name(rawValue: "categoryResultsUpdated"), object: nil) 

     } 

    } 

} 

func resetCategory() { 
    categoryResults = [] 
} 

deinit { 
    NotificationCenter.default.removeObserver(self) 
} 

업데이트 2 : 여기

그리고는 collectionView.tag가 할당되는 방법이다. 이것은 tableViewCell 클래스에 추가됩니다.

func setCollectionViewDataSourceDelegate 
    <D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>> 
    (dataSourceDelegate: D, forRow row: Int) { 

    collectionView.delegate = dataSourceDelegate 
    collectionView.dataSource = dataSourceDelegate 
    collectionView.tag = row 
    collectionView.bounds.size.width = self.bounds.size.width 
    collectionView.reloadData() 



} 

답변

0

컬렉션 뷰 대리자 메서드는 컬렉션 뷰의 컨텍스트를 알 수 없습니다. 내부 컬렉션 뷰 인덱스 경로 인 indexPath.row를 사용하는 대신 collectionView 인스턴스에 따라 onlineNews 인덱스를 계산해야합니다.

편집 : 더 나은 옵션 (스크롤 및 레이아웃 문제를 방지하기 위해)은 셀이 행으로 그룹화되어있는 단일 컬렉션보기를 사용하는 것입니다.

cell.contentType.text = categoryResults[indexPath.row]["ContentType"].stringValue 

는이 컬렉션 뷰의 지역 indexPath를 사용하면 레이아웃 관리자로 지정하지 않는 경우, 섹션

Edit2가 사이 작지만 매우 넓은 구분 뷰를 추가하여 같은 레이아웃을 달성 할 수있다. 원하는 categoryResults index 값을 사용하여 tableViewCell.collectionView에 태그를 지정할 수 있습니다. 그런 다음이 태그를 categoryResults[collectionView.tag]

+0

와 같이 사용할 수 있습니다. 답장을 보내 주셔서 감사합니다. 그 인덱스를 사용하여 결과를 표시하는 방법과 위치를 더 자세히 설명해 주시겠습니까? indexPath.row 대신 collectionView.tag를 사용하는 등 다른 방법을 시도했지만 작동하지 않았지만 JSON 결과를 표시하는 데 인덱스를 할당하는 방법을 잘 모릅니다. 좀 더 설명해주세요. – Maryoomi1

+0

JSON 결과를 얻는 데 도움이되도록 언급 한대로 색인을 계산하는 방법에 대한 설명이 필요하다는 뜻입니다. – Maryoomi1

+0

내 대답 업데이트 – user1232690

관련 문제