2017-02-11 1 views
0

행이 아닌 섹션에 셀이있는 맞춤형 UITableView가 있습니다. 총 셀 수는 5 개입니다. 각 셀에는 단추가 있고 다섯 번째 셀 단추 (tableButton)에 나머지 제목이 달려 있습니다.Swift : cellForRowAtIndexPath에서 예기치 않은 결과가 발생했습니다.

이 코드는 아래 코드와 모두 잘 작동합니다. 첫 번째 4 셀에는 처음에 코드 당 올바른 제목이 있습니다. 그러나 5 번째 셀 (예상 제목 있음)을 아래로 스크롤 한 다음 첫 번째 셀까지 스크롤하면 첫 번째 셀이 이제 다섯 번째 셀에만 한정된 제목으로 변경되었습니다.

if cell.tableButton.tag == 4 조건문에 print 문을 추가했으며 다섯 번째 셀까지 스크롤 할 때마다 인쇄됩니다.

import UIKit 
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet weak var tableView: UITableView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     tableView.delegate = self 
     tableView.dataSource = self 
    } 

    func numberOfSections(in tableView: UITableView) -> Int { 
     // #warning Incomplete implementation, return the number of sections 
     return 5 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     // #warning Incomplete implementation, return the number of rows 
     return 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell 
     cell.layer.borderWidth = 1 
     cell.layer.borderColor = UIColor.gray.cgColor 

     cell.tableButton.tag = indexPath.section 
     if indexPath.section == 4 { 
      cell.tableTitle.isHidden = true 
      cell.tableButton.setTitle("Special", for: .normal) 
     } else { 
      cell.tableButton.setTitle("Normal", for: .normal) 
     } 

     return cell 
    } 


    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 15)) 
     returnedView.backgroundColor = UIColor.groupTableViewBackground 

     return returnedView 
    } 

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
     return 15 
    } 
} 

CustomCell.swift :

import UIKit 
class CustomCell: UITableViewCell { 

    @IBOutlet weak var tableButton: UIButton! 
    @IBOutlet weak var tableTitle: UILabel! 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(_ selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

} 
+1

아마도 셀의 상태가 변경되었을 수 있습니다. 모든 경우에 대해'.normal'을'[]'로 바꾸십시오. – penatheboss

+0

5 셀이있는 섹션이 5 개 있습니까? – iAviator

+0

각 섹션이 1 셀인 5 섹션, 총 5 셀. –

답변

0

난 당신이 dequeReusableCell 방법을 사용하고 있기 때문에 이런 일이 발생 같아요. 테이블 뷰에 5 개의 셀만 있기 때문에 더 이상 셀을 비우지 않고 항상 매번 셀의 새 인스턴스를 만드는 것이 좋을 것이라고 생각하지 않습니다. 그것은 최선의 방법은 아니지만 쉬운 해결책입니다!

+1

이것은 좋은 접근법이 아닙니다. 메모리 사용량이 쌓이게 될 것입니다. – iAviator

+0

그는'prepareForReuse' 메서드를 사용할 수도 있지만 tableview에있는 셀의 수는 정적이며 단지 5 셀입니다. 많은 피해를 입히지 않고도 그를위한 더 쉬운 해결책이 될 수 있습니다. –

+0

그는 셀 내용을 설정하기 위해'prepareForReuse'를 사용해서는 안됩니다. 그 위임 메서드는 그 것을 의미하지 않습니다. 'tableView (_ : cellForRowAt :)'에있는 테이블 뷰의 델리게이트는 항상 셀을 재사용 할 때 모든 내용을 재설정해야합니다. –

0

시나리오를 다시 만들었지 만 제대로 작동시키는 데 문제가 없습니다. 나는 그것이 당신의 CustomCell에서 무언가와 관련이 있을지도 모른다고 생각합니다.

ViewController.swift :

import UIKit 

class ViewController: UIViewController { 
    @IBOutlet weak var tableView: UITableView! 
} 

extension ViewController: UITableViewDataSource { 

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

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

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

     if indexPath.section == 4 { 
      cell.tableButton.setTitle("Special", for: .normal) 
     } else { 
      cell.tableButton.setTitle("Normal", for: .normal) 
     } 

     return cell 
    } 

} 

extension ViewController: UITableViewDelegate { 
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return 250 
    } 
} 

CustomCell.swift :

import UIKit 

class CustomCell: UITableViewCell { 

    @IBOutlet weak var tableButton: UIButton! 

    override func prepareForReuse() { 
     tableButton.setTitle("RESET", for: .normal) 
    }  
} 
물론

하는 UITableView의 단순화 구현하지만, 예에 코드를 더 추가 다른 사람들이 귀하의 문제를 보거나 재현 할 수 있습니다. 당신이

tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)를 사용하여 세포를 재사용하기 때문에

+0

두 개의 다른 동작 (하나는 "특수"버튼 용이고 "normal"버튼은 specialAction 및 normalAction이라고 함)을 추가 한 경우 prepareForResuse를 사용하여 첫 번째 셀이 실행되는 순간과 같이 셀을 동작하게하는 방법은 무엇입니까? 두 가지 행동 모두! –

+0

걱정하지 마라. prepareForReuse의 버튼에서 타겟을 제거했다. –

+0

'PrepareForReuse' 메서드는 셀을 재사용에 적합한 상태로 재설정하고 새 데이터를 설정하기위한 것이 아닙니다. 최악의 경우, 셀의 동작이 여전히 틀린 경우,'UITableView'에서'willDisplayCell' 델리게이트 메소드로 셀의 내용을 설정할 수 있습니다. 늦은 답신을 드려서 죄송합니다. _life_가 끼어 들었습니다.) –

0

이 당신은 여기에 몇 가지 솔루션을 가지고, 셀 재사용 문제처럼 보인다. 첫 번째는 재사용하지 않고 새 메모리를 만드는 것이지만 더 많은 메모리가 사용되므로 성능면에서는 좋지 않습니다.

더 나은 해결책은 tableViewCell에서 재사용을 준비하는 것입니다. 사용자 정의 tableViewCell에서 메서드 prepareForReuse을 재정의해야합니다. 이 메소드에서 뷰를 초기 상태 (텍스트, 알파 등)로 설정하십시오. 먼저 super.prepareForReuse으로 전화하십시오.

+0

'prepareForReuse'를 사용하는 것은 매우 좋은 접근 방법입니다. 그러나 이것을 작동시키기 위해서는 전제 조건이 아니어야합니다. 'UITableViewDelegate'는'CellForRowAtIndexPath'를 호출해야하는데, 차례대로 셀 (new 또는 dequeued)을 가져오고 그 위에'tableButton'의 값을 변경합니다. –

+0

감사합니다.이 메서드는 버튼 제목을 재설정하는 데 사용됩니다. 어떻게 이것을 단추 작업에 사용할 수 있습니까? "특별"버튼에 다른 버튼과 다른 액션을 주면 첫 번째 셀은 실제로 정상 동작과 특수 동작 모두를 수행합니다. –

+0

버튼에 대한 작업을 어떻게 설정하고 있습니까? 코드에 표시되지 않습니다. –

관련 문제