[UIKit] 테이블뷰 UISwitch의 isOn 속성 유지, 테이블뷰 셀 내부의 스위치 클릭 이벤트

2022. 7. 18. 00:55SWIFT/UIKit

728x90
반응형

셀이 재사용되면서 속성이 변경되는 오류

→ prepareForReuse() 사용 (재사용 가능한 셀을 준비하는 메소드)

 

override func awakeFromNib() {
    super.awakeFromNib()
//        print("TableViewCellOrder -awakeFromNib")

    //이미지 원으로 만들기
    orderTitleImage.layer.cornerRadius = orderTitleImage.frame.height/2
    orderSwitch.isOn = false
}


//셀 제사용하지 않고 초기화시켜주는 메소드
override func prepareForReuse() {
    super.prepareForReuse()

    orderTitleImage.image = nil
    orderTitleLabel.text = nil
    orderSubTitleLabel.text = nil
    orderSwitch.isOn = false

}

처음 실행했을 때부터 false를 기본값으로 두고 초기화도 false로 설정! 

 

처음에만 체크했는데 뒤죽박죽 난리나는 상황 prepareForReuse() 메소드에서 초기화해줌

이후 문제 스위치를 클릭하여 변경하였는 데 스크롤하고 다시 돌아오면 초기화상태로 돌아오게 됨

 

이제 데이터를 변경하는 방법에 대해서 알아봅시다요

일단 테이블뷰 셀에 대한 데이터에서 스위치에 대한 값을 추가해주었다

나는 구조체를 만들어 값을 넣어주었지만 배열로 만들었으면 배열을 추가해주면 된다. 

그 후 이미지랑 텍스트를 넣어줬던 곳에서 스위치 isOn 값을 배열에 넣어준 값으로 넣어주면 된다

cell.orderSwitch.isOn = orderCategoryData[indexPath.row].switchOn

이 한줄을 추가하여 이제 셀에 데이터를 넣어주게 되었다. 이러면 아까 설정했던 초기값을 넣어주지 않아도 되는 데 ㅎㅎ

그리고 이제 중요한 부분!! 스위치를 눌렀을 때 자신의 index값을 가져와서 배열에서 변경을 해줘야한다!

delegate를 사용하여 index 를 주어 값을 변경하였다!!

 

시작!

protocol SwitchOnDelegate {
    func switchChange(index: Int, switchIs: Bool)
}

테이블뷰 셀에서 프로토콜을 설정해준다

var switchOnDelegate: SwitchOnDelegate?
    
var orderCellIndex: Int = 0

클래스 안에 델리게이트와 인덱스 변수를 선언해준다

우리는 인덱스값만 알면 데이터를 넘길 수 있으니 인덱스값과 스위치가 켜져있는지 꺼져있는 지에 대한 값을 가져온다

이제 뷰컨트롤러에서 위임을 받아야한다

테이블뷰는 Datasource에서 셀에 대한 내용을 구성하기때문에 구성할 때의 인덱스값을 넘겨주면 되는 것!

cell.orderCellIndex = indexPath.row
cell.switchOnDelegate = self

 

 

cell은 테이블뷰셀 파일을 연결한 상태이고 셀파일에 인덱스와 델리게이트를 선언해준 것에 대입해준다

이제 테이블뷰가 로드될 때 데이터가 넘어갔을 것이다

그러면 이제 스위치를 눌렀을 때 작동을 해주면 된다

@IBAction func orderSwitchAction(_ sender: Any) {
    if orderSwitch.isOn {
        print("on")
        self.switchOnDelegate?.switchChange(index: orderCellIndex, switchIs: true)

    } else{
        print("off")
        self.switchOnDelegate?.switchChange(index: orderCellIndex, switchIs: false)
    }
}

버튼을 눌렀을 때 Action이벤트이다

해당스위치가 isOn=true 가 되었을 때 델리게이트의 메소드에게 자신의 인덱스와 스위치의 여부를 전달한다.

 

이제 인덱스와 스위치 여부를 전달했으니 이것을 배열에 저장하기만 하면 된다!

메소드정의를 해주기 위해서 다시 테이블뷰가 있는 뷰컨트롤러에 온다

나는 델리게이트 메소드를 따로 보기위해서 extension으로 따로 빼주었다.

extension ViewControllerOrder: SwitchOnDelegate{
    func switchChange(index: Int, switchIs: Bool) {
        orderCategoryData[index].switchOn = switchIs
    }
}

이제 메소드 정의를 해주었기에 스위치를 눌렀을 때 값을 받아와서 배열에 저장해주게 된다!

끝!!!!

 

 

결과화면



 

 

이번 델리게이트 활용을 통해서 프로토콜과 델리게이트 활용방법을 조금은 알게 된 거 같다

근데 아직도 많이 헷갈린다 ....

그래도 계속 하다보면 익숙해지는 날이 오겠지 !!

아자아자 화이팅 

 

 

728x90
반응형