본문 바로가기
iOS Swift/Study

[Swift] 책검색 App (6) - 담은 책 삭제 (CollectionView Cell 삭제)

by 야고이 2024. 5. 7.
728x90

삭제하시겠습니까 알림창도 안띄워주는 불친절한 앱이지만 일단 삭제가 됩니다!

 

아래 사진 처럼 편집을 누르면 선택한걸 보여주고 삭제까지 해볼게요

 

 

삭제시 선택셀 하이라이트 만들기

 

멀티셀렉션으로 하다가 포기한.. 기록이라도 남겨 놓습니다

더보기
let highLightView = UIView()

저 노란 선택택 표시를 위해 uiview 를 생성해줬습니다

highLightView.snp.makeConstraints {
    $0.edges.equalToSuperview()
}

컨텐트뷰 전체로 오토레이아웃 잡아줬어요

highLightView.backgroundColor = .ybyellow
highLightView.layer.opacity = 0.3
highLightView.layer.borderColor = UIColor.ybyellow.cgColor
highLightView.layer.borderWidth = 3

색상을 설정할 때 어떤건 그냥 색상값을 넣고 또 어떤건 UIColor. 어쩌구로 넣는걸까요

따로 공부해봐야겠습니다. 

uiview 에 opacity 값을 주니까 보더에도 투명도가 들어가네요

테투리만 진하게 하고 싶은데

highLightView.backgroundColor = .ybyellow
highLightView.layer.opacity = 0.3
highLightBorderView.layer.borderColor = UIColor.ybyellow.cgColor
highLightBorderView.layer.borderWidth = 3
highLightBorderView.layer.cornerRadius = 6

UIView 를 하나더 깔아서 해도 테두리에 투명도가 들어갑니다

highLightView.addSubview(highLightBorderView)

노란색뷰 위에 테투리뷰를 addSubview 해서 그런것 같아요

contentView.addSubview(highLightBorderView)

컨텐트뷰로 잡아줍니다

원하는대로 그려졌어요

기본값은 hide 로 해주고 편집시에 선택하면 보여지도록 구현해야합니다

 

구글링해서 찾은 예제를 토대로 멀티셀렉션을 구현해보려했는데 

너무 어려워서 포기,, 하루종일 했는데 못해서 아쉽지만 일단 삭제 기능만 구현하는걸 목표로 하려고 한다

담에 다시 도전한다!!

Edit 누르면 셀을 선택 할 수 있고 Delet 누르면 선택한 셀 삭제 Done 을 누르면 콜렉션뷰 리로드 하고 싶었다,, 정말 하고 싶었어,,

참고블로그

참고블로그2


위 더보기 실패기록에 적혀있지만 다시 적어볼게요,, 새로운 마음으로

 

<cell 파일에서 작성>

let highLightView = UIView()
let highLightBorderView = UIView()

테두리도 넣고 싶어서 UIView을 두개 만들어줬습니다

투명도 처리된 바탕뷰와 보더뷰

 

contentView.addSubview(highLightView)
contentView.addSubview(highLightBorderView)

둘 다 contentView 에 깔아줍니다

 

highLightView.snp.makeConstraints {
    $0.top.leading.equalToSuperview().offset(-4)
    $0.bottom.trailing.equalToSuperview().inset(-4)
}

highLightBorderView.snp.makeConstraints {
    $0.top.leading.equalToSuperview().offset(-4)
    $0.bottom.trailing.equalToSuperview().inset(-4)
}

오토레이아웃 잡아주는건 똑같아요

//바탕뷰
highLightView.backgroundColor = .ybyellow
highLightView.layer.opacity = 0.3 //투명도값
highLightView.layer.cornerRadius = 6
highLightView.isHidden = true
//보더뷰
highLightBorderView.layer.borderColor = UIColor.ybyellow.cgColor
highLightBorderView.layer.borderWidth = 3
highLightBorderView.layer.cornerRadius = 6
highLightBorderView.isHidden = true

바탕뷰에는 backgroundColor 값을 넣어주고 투명도 값을 넣어줍니다!

보더뷰에는 바탕색을 넣지 않고 보더컬러만 넣어줘요 

여기서 중요한건 둘 다 일단 숨김처리를 해줘야합니다!!

셀을 선택했을 때만 이 하이라이트가 보여져야 하니깐요

 

override var isSelected: Bool {
   didSet {
       highLightView.isHidden = !isSelected
       highLightBorderView.isHidden = !isSelected
   }
}

속성이 바뀔 때마다 didSet 이 인지를 합니다

즉 셀을 선택하면 만들어놓은 하이라이트뷰가 보여집니다

 

 

 

<Controller 구현코드>

 

var dictionarySelectedIndexPath: [IndexPath : Bool] = [:]

콜렉션뷰에서 선택한 셀의 IndexPath를 Key로, 선택 여부를 value로 가지며, 선택한 셀들의 정보를 담는 변수를 만들어줬습니다

 

cv.allowsSelection = false

만들어 놓은 콜렉션뷰가 선택되지 않도록 allowSelection 을 false 로 설정해 둡니다

 

열거형으로 모드 구성

enum Mode {
    case view
    case select
}

편집시 모드를 select 편집 안할시 모드를 view라고 할게요

 

 

모드가 변경 될 때마다 설정값을 바꿔줍니다

var editMode: Mode = .view {

모드의 초기값은 .view 로 설정합니다

 

.view 모드일 때

switch editMode {
        // view mode
        case .view:
            for (key, value) in dictionarySelectedIndexPath {
                if value {
                    libraryCollectionView.deselectItem(at: key, animated: true)
                }
            }

.view 모드로 변경 되면 담아놓은 배열의 모든 값을 확인하여 선택된 항목을 선택 해제 합니다

dictionarySelectedIndexPath.removeAll() //뷰 모드로 전환 될 때 딕셔너리의 모든 항목 삭제
editButton.setTitle("Edit", for: .normal) // 버튼 이름 설정
editButton.setTitleColor(.ybgray, for: .normal) //버튼 컬러설정
libraryCollectionView.allowsSelection = false // 콜렉션뷰셀 선택 막기
trashButton.isHidden = true // 삭제버튼 숨기기

선택 모드에서 뷰 모드로 변경할 때,

선택한 셀들을 모두 선택 해제하고 선택된 셀의 indexPath를 저장하는 딕셔너리를 비우는 이유는
다시 선택할 때에는 새로운 셀을 담아야하기 때문이다

 

 

.select 모드 일 때

case .select:
    editButton.setTitle("Done", for: .normal) // 버튼 이름 Done 으로 변경
    trashButton.isHidden = false // 삭제 버튼 보이게 하기
    libraryCollectionView.allowsSelection = true // 콜렉션뷰 셀 선택 가능

전체코드

더보기
var editMode: Mode = .view {
    didSet {
        switch editMode {
        // view mode
        case .view:
            for (key, value) in dictionarySelectedIndexPath {
                if value {
                    libraryCollectionView.deselectItem(at: key, animated: true)
                }
            }
            dictionarySelectedIndexPath.removeAll()
            editButton.setTitle("Edit", for: .normal)
            editButton.setTitleColor(.ybgray, for: .normal)
            libraryCollectionView.allowsSelection = false
            trashButton.isHidden = true

        case .select:
            editButton.setTitle("Done", for: .normal)
            trashButton.isHidden = false
            libraryCollectionView.allowsSelection = true
        }
    }
}

Edit 버튼을 누를 때 모드를 변경해주는 코드

//편집 -  뷰 모드 변경 토글
    @objc func EditButton(_ sender: UIButton) {
        print("편집모드변경 토글")
        editMode = editMode == .view ? .select : .view
    }

삼항연산자로 구현 했는데

삼항연산자를 간단히 말하면 [00 ? 11 : 22] --> 요런식에서  00이 참이면 11 거짓이면 22가 되는 식이라고 보면 된다

editMode 가 .view 일 경우에는 .select 모드로 바뀌고 아닐 때에는 .view 모드로 전환이 된다

 

 

삭제 버튼 누를시 선택 된 책이 삭제 되는 기능

삭제할 때에는 순서가 중요하다

1) 코어 데이터에 저장된 해당셀 삭제

2) 코어데이터 변경사항 저장

3) 선택한 항목 배열에서 삭제

4) 그려진 콜렉션뷰 삭제 즉, UI 상에서 삭제

순서대로 삭제하지 않으면 데이터가 꼬이게 된다 

@objc func didSelectDelectButton(_ sender: UIButton) {
    print("삭제버튼")
    guard let context = self.persistentContainer?.viewContext else { return } //viewVontext 생성

    // 선택한 셀의 IndexPath를 기반으로 CoreData에서 해당 항목 삭제
    for (indexPath, _) in dictionarySelectedIndexPath {
        context.delete(bookList[indexPath.item])
    }

    // CoreData 변경사항 저장
    try? context.save()

    // 선택 되지 않는 책만 남김
    bookList = bookList.filter { book in
        let indexPath = IndexPath(item: bookList.firstIndex(of: book)!, section: 0)
        if dictionarySelectedIndexPath[indexPath] == nil {
            return true
        } else {
            return false
        }
    }

    dictionarySelectedIndexPath.removeAll() // 선택한 셀 제거 후 딕셔너리 초기화
    libraryCollectionView.reloadData()
    editMode = .view // 모드를 "뷰"로 변경
}

필터 부분을 다 이해하진 못해서 낼 공부해보겠어요,,

 

이제 라이브러리에서도 선택하면 디테일뷰를 띄워줘야해요

728x90

댓글