본문 바로가기

IOS Swift/Festagram

Swift 프로젝트 : FestaGram 04 게시물 작성 화면 02

 

이번엔 collectionView 다중 선택을 해볼게요

https://www.youtube.com/watch?v=jQ8EUsQZJ5g&t=1s

이 영상을 보고 만들었는데 후반부의 custom부분은 구현을 하지 않았기 때문에 커스텀 부분은 선택사항입니다!

저어엉말 어려웠어요ㅠ

 

 

일단 새로운 Swift파일을 만들어서 enum하나를 만들어주세요

 

그 다음 저번에 초기화한 외부변수들 말고 또 하나를 만들겠습니다.

var mMode: Mode = .view {
        didSet {
            switch mMode {
            case .view:
                for (key, value) in dictionarySelectedIndecPath {
                    if value {
                        MyAlbumView.deselectItem(at: key, animated: true)
                    }
                }
                setPostingButton.isUserInteractionEnabled = false
                setPostingButton.alpha = 0.6
                dictionarySelectedIndecPath.removeAll()
                selectedImages.removeAll()
                urlString.removeAll()
                selectedAssetIndex.removeAll()
                alertImageCountLabel.text = "선택 없음"
                itemsSelectedButton.setTitle("선택", for: .normal)
                MyAlbumView.allowsSelection = true
                MyAlbumView.allowsMultipleSelection = false
            case .select:
                itemsSelectedButton.setTitle("취소", for: .normal)
                MyAlbumView.allowsMultipleSelection = true
            }
        }
    }
    
    @objc func didSelectButtonClicked(_ sender: UIButton) {
        mMode = mMode == .view ? .select : .view
    }

이렇게 길고긴 클로져하나와 @objc를 만들어주세요 

didSelectButtonClicked는 1개만 선택하는 상황과 여러개를 선택하는 상황을 구별하는 UIButton event입니다.

삼항연산자로 button을 눌렀을 때 양자택일 상태를 만드는겁니다.

 

 

이렇게 양쪽에 UILabel 두개 가운데 UIButon을 설정해주세요

 

 

collection DIdslectedView/ collection deselected 함수 두개를 구현해주세요 didselet와 deselect이렇게만 입력하면 자동완성으로 뜰거에요

 

그 안에 아래 코드를 넣어주세요

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let asset = fetchResult?.object(at: indexPath.item) else { return }
        
        switch mMode {
        case .view:
            collectionView.deselectItem(at: indexPath, animated: true)
            imageManager.requestImage(for: asset,
                                      targetSize: TcgSize,
                                      contentMode: .aspectFit,
                                      options: nil) { image, _ in
                                        guard let image = image else { return }
                                        self.selectedImg.image = image
            }
            
        case .select:
            dictionarySelectedIndecPath[indexPath] = true
            selectAsset = asset
            selectedAssetIndex.insert(indexPath.item, at: 0)
            
            imageManager.requestImage(for: asset,
                                      targetSize: TcgSize,
                                      contentMode: .aspectFit,
                                      options: nil) { image, _ in
                                        guard let image = image else { return }
                                        self.selectedImg.image = image
                                        self.selectedImages.insert(image, at: 0)
            }
            
            selectedImages.remove(at: 0)
            
            if selectedAssetIndex.count >= 1 {
                setPostingButton.alpha = 1.0
                setPostingButton.isUserInteractionEnabled = true
                alertImageCountLabel.text = "\(selectedAssetIndex.count)개 선택"
            }else {
                alertImageCountLabel.text = "선택 없음"
            }
        }
    }
    
    func searchIndex(_ seletedIndex:[Int],_ indexPath:Int) -> Int {
        var index = -1
        for i in 0 ... seletedIndex.count {
            if seletedIndex[i] == indexPath {
                index = i
                return index
            }
        }
        return index
    }
    
    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        if selectedAssetIndex.count >= 1, commentInputText.text.count >= 1 {
            setPostingButton.isUserInteractionEnabled = true
            setPostingButton.alpha = 1.0
            
        }else {
            setPostingButton.isUserInteractionEnabled = false
            setPostingButton.alpha = 0.6
        }
        
        if mMode == .select {
            dictionarySelectedIndecPath[indexPath] = false
            let index = searchIndex(selectedAssetIndex, indexPath.item)
            
            if index < 0 {
                print("out of indexpath out of range")
            }else {
                selectedAssetIndex.remove(at: index)
                selectedImages.remove(at: index)
                
                if selectedAssetIndex.count == 0 {
                    setPostingButton.isUserInteractionEnabled = false
                    setPostingButton.alpha = 0.6
                    alertImageCountLabel.text = " 선택 없음"
                }else {
                    setPostingButton.isUserInteractionEnabled = true
                    setPostingButton.alpha = 1.0
                    alertImageCountLabel.text = "\(selectedAssetIndex.count)개 선택"
                }
            }
        }
    }

작성하기 UIButton의 예외 처리와 같이 해야 해요 입력된 글이나 선택한 사진도 없는데 버튼이 눌려서 포스팅 되버리면 안돼니까요

isUserInteractionEnabled를 적용해주세요

 

중간에 있는 searchIndex()라는 함수는 didselect한 collectionCell의 indexPath값을 알아내서 반환하는 함수입니다

이거 이해하다가 며칠을 밤샜는지;;

 

 

  override func viewDidLoad() {
        super.viewDidLoad()

        commentInputText.delegate = self
        commentInputText.backgroundColor = .white
        follows = LoadFile.shread.followString
        let tapEndEditing = UITapGestureRecognizer(target: self, action: #selector(selectProfileImg))
        postingContentView.addGestureRecognizer(tapEndEditing)
        itemsSelectedButton.addTarget(self, action: #selector(didSelectButtonClicked(_:)), for: .touchUpInside)
        sendingPostIndicator.isHidden = true
        MyAlbumView.reloadData()
    }

 

viewdidload()/viewwillAppear() 안에 이 코드들을 체워주시고

글을 쓸 때 키패드가 사라지기 위해 제스쳐 @objc 하나를 만들어 넣어주세요

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        mMode = .view
        PHPhotoLibrary.shared().register(self)
        phothAurhorizationStatus()
        requestImageCollection()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        PHPhotoLibrary.shared().unregisterChangeObserver(self)
    }
    
    @objc func selectProfileImg(_ gesture: UITapGestureRecognizer) {
        commentInputText.resignFirstResponder()
    }

 

 

extension AlbumViewController: UITextViewDelegate {
    func textViewDidBeginEditing(_ textView: UITextView) {
        textView.becomeFirstResponder()
        if textView.text == "입력할 내용" {
            textView.text = ""
        }
    }
    
    func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        textView.resignFirstResponder()
        return true
    }
}

UITextView에는 placeholder가 없기 때문에 delegate로 이렇게 설정해 주면 placeholder처럼 쓸 수 있답니다.

 

시간이 없어서 설명이 조금 부족해서 나중에 다시 수정할게요!

 

수정과 함께 다음 포스팅에 Firebase에 전송 기능을 구현해보겠습니다,