📱 iOS 플젝 개발일지

[iOS/Swift] 스크롤뷰 안의 테이블뷰가 모두 보이지 않는 현상 (feat. stackview)

dev_zoe 2023. 6. 24. 15:10
반응형

🚨 문제 인식

 

아래 자세히 보면 회고를 1주일 내 이틀이상 작성했는데 짤려있는 듯 하게 보이는 현상이 있었다.

 

❗️ 고민 지점 / 문제 원인

- 이 또한 전에 꽤 나를 애먹였던 scrollview안의 tableview가 온전히 다 보이지 않는, contentSize 이슈인것 같아서 이쪽 위주로 다시 살펴보았다.

- 여기서 1주일간 회고기록이 없을 때 보여주는 뷰가 있는데,  

이 뷰도 스크롤뷰 안에 포함되어있다보니 단순한 isHidden으로는 해당 뷰가 contentView에 걸린 제약도 사라지지 않기 때문에 회고 기록이 있을 때 테이블뷰를 보여주는 부분에서 "회고 작성하러 가기 버튼"의 제약에 맞는 크기까지만 보여주는 이슈가 있었다.

 

이에 따라 회고 기록이 있을 때는 위 뷰의 제약을 다 지워주고, 없을 때는 테이블뷰의 제약을 지워준 다음 보여줘야할 뷰의 제약을 다시 거는 방법으로 했었는데 같은 이슈가 나타나기도 했고 효율적인 방법은 아닌것같아서 다른 방법은 없을지 찾아보기로 했다.

 

// 1. 원래 방법
// 회고기록이 비어있으면            
            noRetrospectView.isHidden = false
            goRetrospectButton.isHidden = false
            
            retrospectListTableView.isHidden = true  // 회고기록 테이블뷰 숨기고 + 제약 제거
            retrospectListTableView.snp.removeConstraints()
            
            noRetrospectView.snp.makeConstraints{ make in   // 위 뷰 2개의 제약 다시 만들기 (회고기록이 있었을 때 마찬가지로 제거가 된 상태이니)
            
            }
            
            goRetrospectButton.snp.makeConstraints{ make in

            }

 

✅ 문제 해결 과정

 

1) https://stackoverflow.com/questions/50275346/what-happens-with-constraints-when-a-view-is-begin-to-be-hidden

 

What happens with constraints when a view is begin to be hidden?

Question is very similar to this but I am interesting in what happen when UIView change isHidden value. For Example: | | | -[ViewA]-[ViewB]-[ViewC]- | | | at draf...

stackoverflow.com

해당 글을 보니 기존에 isHidden은 UI상에서 안보이게 하기 위한 조치일 뿐, constraint는 그대로 살아있다고 나와있다. 그리고 또 읽어보면 UIStackView 안에 있는 하나의 뷰가 isHidden되면 다른 subView들의 constraint를 조정해준다고 나와있다.

 

그래서 스택뷰 안에 회고기록이 없을 때의 뷰 2개와 테이블뷰를 넣고 높이만 제약을 추가해주었다.

        private lazy var stackView = UIStackView().then { view in
            view.addArrangedSubviews([retrospectListTableView,
                                     noRetrospectView,
                                     goRetrospectButton])
            view.axis = .vertical
            view.alignment = .fill
            view.distribution = .equalSpacing
            view.spacing = 15
        }
        
        stackView.snp.makeConstraints { make in
            make.top.equalTo(retrospectTitle.snp.bottom).offset(15)
            make.leading.equalTo(contentView.snp.leading).offset(28)
            make.trailing.equalTo(contentView.snp.trailing).offset(-28)
            make.bottom.equalTo(contentView.snp.bottom).offset(-21)
        }
        
        noRetrospectView.snp.makeConstraints{ make in  // 높이만 지정해줌
            make.height.equalTo(124)
        }

        goRetrospectButton.snp.makeConstraints{ make in
            make.height.equalTo(50)
        }
        
        retrospectListTableView.snp.makeConstraints { make in
            make.height.equalTo(0)
        }
        if result.latestRetrospectionInfos.isEmpty{ // 회고기록이 없을 때
            noRetrospectView.isHidden = false
            goRetrospectButton.isHidden = false
            
            retrospectListTableView.isHidden = true
        }
        else{ // 회고기록이 있을 때
            noRetrospectView.isHidden = true
            goRetrospectButton.isHidden = true
                        
            retrospectListTableView.isHidden = false
            
            retroSpectList.removeAll()
            retroSpectList.append(contentsOf: result.latestRetrospectionInfos)
            retrospectListTableView.reloadData()
            
            retrospectListTableView.snp.updateConstraints { make in // 테이블뷰 내용에 따라서 constraint 업데이트
                make.height.equalTo(66 * retroSpectList.count)
            }
        }

감격 ㅠ ㅠ .. 회고 기록도 모두 보이고, 스크롤도 예상대로 잘 되고있다. 회고 기록이 없는 경우에는 스크롤되지 않게 적용도 되어있었다.

스택뷰를 쓰면 뭐가 좋고, 또 어떻게 뷰의 제약을 자동으로 잡아준건지 등을 더 이해해보기로 했다.

 

2) 스택뷰의 장점

https://velog.io/@eddy_song/stack-view

 

오토레이아웃을 쉽고 빠르게, 스택 뷰(Stack View)

레이아웃을 잡을 땐, 무조건 Stack View부터 쓰자.

velog.io

해당 글에 나온 스택뷰의 정말 큰 장점은 개발자가 직접 복잡하게 제약을 일일이 다 설정할 필요도 없고, 뷰를 중간에 삭제할 일이 있거나 isHidden을 통해 감출 필요가 있을 때에도 자동으로 레이아웃을 설정에 맞게 잡아준다는 점이다.

따라서 개별 뷰의 제약을 세세하게 조정해야한다거나 이러한 상황이 아니면 스택뷰를 최대한 활용하는 것이 편리할듯 하다.

 

3) 개인적인 의문점

❓stackview가 레이아웃을 자동으로 조정해준다는건 알겠는데, 크기까지 자동으로 조정되는가?

 

https://developer.apple.com/documentation/uikit/uistackview

 

UIStackView | Apple Developer Documentation

A streamlined interface for laying out a collection of views in either a column or a row.

developer.apple.com

(역시 공식문서가 짱이다.)

공식문서를 읽어보면 "추가적인 제약 없이도 시스템은 content에 기반하여 스택뷰의 사이즈를 계산한다." 라고 나와있다.

따라서 테이블뷰가 스크롤되기 위해서는 contentSize가 명확해야하는데, stackView가 SubView의 size에 따라서 자동으로 stackView의 크기가 조정되므로 스크롤된것이다.

(이걸 모르고 여태까지 삽질을 했었군,,,,,,,,)

 

 

 

반응형