뉴스를 검색할 수 있는 화면을 추가했습니다.
매우 멋진 기능이에요!😄
이번 작업에서의 핵심은 FirstResponderTextField를 다루는 것이었습니다.
* FirstResponderTextField: 텍스트필드가 보여지면 자동으로 포커싱되는 기능을 가진 텍스트필드
SwiftUI로 iOS 14에 FirstResponderTextField를 구현하려면 다음과 같이 긴 코드를 생성해줘야 합니다.
(제가 쓰고 있는 코드라서 불필요한 변수들이 있습니다!)
struct FirstResponderTextField: UIViewRepresentable {
class Coordinator: NSObject, UITextFieldDelegate {
@Binding var searchText: String
@Binding var didReturn: Bool
var becameFirstResponder = false
init(searchText: Binding<String>, didReturn: Binding<Bool>) {
self._searchText = searchText
self._didReturn = didReturn
}
func textFieldDidChangeSelection(_ textField: UITextField) {
searchText = textField.text ?? ""
textField.text = String(searchText.prefix(15)) // 글자 수 제한
}
// 리턴키를 누르면 포커스 해제됩니다.
// 리턴키를 누르면 didReturn이 토글됩니다.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
didReturn.toggle()
textField.resignFirstResponder()
return true
}
}
@Binding var searchText: String
@Binding var didReturn: Bool
let placeHolder: String
func makeUIView(context: Context) -> some UIView {
let textField = UITextField()
textField.delegate = context.coordinator
textField.placeholder = placeHolder
return textField
}
func makeCoordinator() -> Coordinator {
return Coordinator(searchText: $searchText, didReturn: $didReturn)
}
func updateUIView(_ uiView: UIViewType, context: Context) {
if !context.coordinator.becameFirstResponder {
uiView.becomeFirstResponder()
context.coordinator.becameFirstResponder = true
}
}
}
프로젝트에서 사용했지만, return 버튼이 눌릴 때 액션을 발생시키는 등의 작업은 어떻게 하는지 잘 알지 못했습니다.
이번에 검색 기능을 구현하면서 텍스트 필드의 동작 여부를 파악해야 했고, 덕분에 좋은 공부가 되었습니다.
화면을 구성하는 코드는 다음과 같습니다.
struct HeadlineSearchView: View {
@Environment(\.presentationMode) var presentationMode
@State private var searchText = ""
@State private var keyword = ""
@State private var didReturn = false
@State private var refreshList = false
var body: some View {
VStack(spacing: 0) {
searchBar
Divider()
if keyword.isEmpty {
Spacer()
} else {
if refreshList {
HeadlineListView(keyword: keyword)
} else {
HeadlineListView(keyword: keyword)
}
}
}
.background(Color.theme.background.ignoresSafeArea())
.navigationBarHidden(true)
// 키보드에서 return을 누르면 didReturn이 토글됩니다.
// onChange를 통해 didReturn이 변하면 keyword에 값을 바꿔주고 리스트를 새로고침해줍니다!
.onChange(of: didReturn) { _ in
keyword = searchText
refreshList.toggle()
}
}
}
private extension HeadlineSearchView {
var searchBar: some View {
HStack {
SearchBarView(searchText: $searchText, didReturn: $didReturn)
Spacer()
Text("취소")
.foregroundColor(Color.theme.textColor)
.font(.subheadline)
.padding(.leading, 5)
.onTapGesture {
UIApplication.shared.endEditing()
presentationMode.wrappedValue.dismiss()
self.searchText = ""
}
}
.frame(maxWidth: UIScreen.main.bounds.width)
.padding()
.padding(.bottom, -8)
}
}
지금의 검색 화면에서 조금 더 사용성이 좋게 발전시키고 싶은데.. 다음과 같이 개선하면 어떨까 싶어요.
유튜브 앱의 검색기능을 관찰해보면 텍스트 필드의 포커싱 여부에 따라서 뷰가 변하는 것을 알 수 있습니다.
이에 따라서 저도 isFocus: Bool 변수를 만들어서 조금 더 사용성이 좋은 화면을 만들어 보겠습니다!
디자인 실력이 없으니.. 좋은 앱의 사용자경험을 모방하는 것이 현재로썬 최선인 것 같아요.. 하하 😅😀😀🥲
홧팅!
'Project > SwiftUI 블록와이드' 카테고리의 다른 글
RestAPI vs WebSocketAPI. 현재 해결해야 할 문제 (0) | 2023.03.07 |
---|---|
블록와이드 1.1.4 업데이트 소식 (0) | 2023.02.27 |
[블록와이드] 뉴스 키워드 편집 기능 추가 (0) | 2023.02.11 |
[SwiftUI] @AppStorage로 배열(Array) 다루기 (0) | 2023.02.05 |
해결해야하는 콘솔로그: Bound preference PositionPreferenceKey tried to update multiple times per frame. (0) | 2023.01.25 |
댓글