⚠️ 문제: searchBar.backgroundColor 미적용

searchBar.backgroundColor = .red
위 코드를 적용했으나 의도한 색상과는 달리 흐리게 표현된다.
❗️ 원인: UISearchBarBackground 이미지

.red로 설정된 background 위에 하나의 뷰가 더 올라가있다.
UISearchBarBackground 이미지뷰로 추정된다. 이때문에 backgroundColor 자체는 빨간색으로 잘 변경되었지만 이미지뷰에 겹쳐져 의도했던 색상으로 보이지 않았던 것이다.
🤔 해결과정: backgroundImage를 없애보기
처음에는 이전에 겪었던 UISegmentControl backgroundColor 설정 문제와 비슷한 것 같아 backgroundImage = nil을 설정해보았다.
searchBar.backgroundImage = nil
그러나 여전히 처음과 같이 배경색상이 흐릿하게 보였다.
searchBar는 image를 3가지 가지고 있다.
문제 파악을 위해 세 이미지를 모두 출력해보았다.
print(searchBar.backgroundImage)
print(searchBar.scopeBarBackgroundImage)
print(searchBar.largeContentImage)
// 모두 nil 출력
세 가지 모두 nil을 출력하였다. 원래부터 존재하지 않았으니 backgroundImage = nil을 할당하여도 결과가 바뀌지 않았던 것이다.
그렇다면 UISegmentControl을 해결했을 때와 동일하게 커스텀 searchBar를 만들어 layoutSubviews를 건드려보자.
class SearchBar: UISearchBar {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
}
override func layoutSubviews() {
super.layoutSubviews(()
let imagesView = subviews.compactMap { $0 as? UIImageView }.prefix(1)
imageView.first!.isHidden = true
}
}
UISegmentControl은 segment의 개수만큼 이미지뷰를 가지고 있었다. 그래서 layoutSubviews()에서 해당 이미지뷰를 숨겼을 때 설정한 backgroundColor를 의도한 대로 볼 수 있었다.
그러나 UISearchBar는 UISegmentControl에서 했던 방법대로 커스텀 객체를 만들어보아도 결과가 바뀌지 않았다.
사실 위에서 이미 UISearchBar의 backgroundImage가 nil이라 확인했으니 이 방법이 작동할 가능성이 낮다고 보긴 했었다.
그럼 어떻게 해야하나. 인터넷을 찾아보았다.
✅ 해결: searchBarStyle = .minimal로 변경
UISearchBar는 searchBarStyle이라는 속성을 가지고 있다.
The style
UISearchBar.Style.minimalprovides no default background color or image but will display one if customized as such.
출처: searchBarStyle | Apple Developer Documentation
.default가 아닌 .minimal로 설정하면 기본 backgroundColor나 image를 가지고 있지 않다고 한다.
searchBar.searchBarStyle = .minimal
해당 스타일을 적용하자 의도한대로 backgroundColor를 적용할 수 있었다.

⚠️ 문제: UICollectionView 스크롤 시 콘솔에 warning 출력

UICollectionView로 구현한 ListView를 스크롤하니 콘솔에 위와 같은 경고가 출력되었다.
❗️ 원인: ListCell의 Height 충돌
컬렉션뷰의 셀로 사용하고 있는 ListCell의 height가 충돌하고 있는 것으로 보인다.
private func setLayout() {
let labelStack = setLabelStackView()
contentView.addSubview(labelStack)
contentView.addSubview(rateLabel)
contentView.snp.makeConstraints{
$0.directionalEdges.equalToSuperview()
$0.height.equalTo(60)
}
labelStack.snp.makeConstraints {
$0.leading.equalToSuperview().offset(16)
$0.centerY.equalToSuperview()
}
rateLabel.snp.makeConstraints {
$0.trailing.equalToSuperview().inset(16)
$0.centerY.equalToSuperview()
$0.leading.greaterThanOrEqualTo(labelStack.snp.trailing).offset(16)
$0.width.equalTo(120)
}
}
ListCell의 contentView는 요구사항에 따라 height를 60으로 두고 있다.
또한 top.bottom.left.right 모두 equalToSuperVeiw()로 제약을 두고 있다.
그러나 top.bottom을 superView에 맞추면 height가 52가 되어버려서 기존에 제약을 둔 60과 충돌이 발생하고 있다.
✅ 해결: Autolayout 제약 수정
func setLayout() {
...
contentView.snp.makeConstraints {
$0.top.horizontalEdges.equalToSuperView()
$0.height.equalTo(60)
}
...
}
기존에는 contentView.top.bottom을 모두 equalToSuperView()하고 있었기 때문에 ListCell의 height 제약에 충돌이 발생했다.
따라서 contentView의 오토레이아웃 제약을 bottom을 삭제한 $0.top.horizontalEdges.equalToSuperView()로 수정하였다.
$0.height.equalTo(60)이 존재하기 때문에 bottom을 제한해주지 않아도 오토레이아웃은 알아서 셀이 끝나는 위치를 알고 있다.

문제없이 작동하는 것을 확인하였다.
⚠️ 문제: 시뮬레이터에서 searchBar textField 클릭 시 콘솔에 경고 출력

searchBar.delegate 설정밖에 안했는데 시뮬레이터에서 textField 영역을 클릭하니 CHHapticPattern과 UIKBFeedBackGenerator 관련 오류가 발생했다.
⏸️ 해결 보류: Apple 공식에서 확인중

검색해보니 Apple Developer Forum에서 같은 오류가 발생한 글을 찾았고, Apple 측에서 '인지하고 있으나 아직 명확한 해결법 없음'이라는 내용의 답변을 달아준 것을 확인하였다.
나중에 XCode 업데이트하면서 고쳐주지 않을까 싶다.
출처: hapticpatternlibrary.plist error with Text entry fields in Simulator only