[SwiftUI] Keyboard ViewTapDismiss 구현하기

쩡현·2022년 6월 20일
1

[SwiftUI]

목록 보기
1/1
post-thumbnail

이것이 무엇이냐?

주로 keyboard를 화면을 터치하여 dismiss 할 때에 사용합니다

이런식으로요

swiftUI에 이러한 component가 없어서 스니펫을 작성해보았어요.

어떻게 사용해요?

일단 keyboard를 dismiss하는 extension을 선언해야 합니다.

import Foundation
import UIKit

extension UIApplication {
  func endEditing() {
    sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
  }
}

이렇게 UIApplication extension을 선언해줍니다.
이 친구가 키보드의 dismiss를 맡아줄 겁니다.

실행은

UIApplication.shared.endEditing()

이런식으로 하면 됩니다.

그리고 이제 ‘View를 클릭했을 때’ 라는 조건을 구현해야겠죠?
component를 만들어, 구현해 봅시다ㅏ

import SwiftUI

struct BackgroundTapGesture<Content: View>: View {
  private var content: Content
  
  init(@ViewBuilder content: @escaping () -> Content) {
    self.content = content()
  }
  
  var body: some View {
    Color.white
      .overlay(content)
  }
}

이름은 BackgroundTapGesture라고 만들었습니다.

이 친구로 ‘View를 클릭했을때’ 라는 조건에서 어떠한 코드든 실행 할 수 있기 때문이죱

메커니즘은 대충 저 BackgroundTapGesture라는 친구를 var body: some View의 바로 하위 객체로 담아서 사용하는 겁니다.

var body: some View {
  BackgroundTapGesture {
    VStack(spacing: 30) {
      Text("텍스트를 입력해주세요.")
       
      TextEditor(text: $someText)
    }
  }
  .onTapGesture { // View를 클릭했을 때
    UIApplication.shared.endEditing()
  }
}

이런식으로 사용하면 keyboard가 잘 dismiss 됩니다.

여기서 응용 좀 하고가실게요!

보시면 아시겠지만

아까 BackgroundTapGesture를 선언 할 때

var body: some View {
  Color.white
    .overlay(content)
}

Color를 white라고 주었기 때문에 사용자가 혹여 다크모드라도 키게 된다면 이 view만 혼자 금쪽이가 되는 엑시던트가 생기겠죠?

그렇게 때문에 이를 해결해주어야 합니다.

해결 방법은 Assets.xcassets에 앱의 Default가 되는 ColorSet을 하나 넣어서 그 컬러셋을 BackgroundTapGesture에 적용하면 해결 할 수 있습니다.

저는 Color라는 그룹에 background ColorSet을 만들었습니다.

이런식으로 다크모드에 어두운 색상을 넣으시면 되고 왼쪽의 Any Appearance는 기본값이라고 생각하시면 됩니다.

저는 하얀색 배경의 앱이기 때문에 저렇게 구현하였습니답.

자, 이렇게 만들어 놓고 Assets.xcassets에 넣은 색상을 코드로 사용할 수 있도록 ColorExtension을 생성하겠습니다.

import SwiftUI

extension Color {
  static var background: Color { Color("background") }
	// 아래에 다른 색상도 추가하여 사용할 수 있습니다.
}

이렇게 생성한 후에 BackgroundTapGesture의 Color.white를 background로 바꾸어 주면?

var body: some View {
  Color.background
    .overlay(content)
}

짠 색깔까지 예외처리가 완료되었습니다~

궁금하신 점은 댓글 달아주세요!

profile
어서오세유 iOS앱 개발 배우는 19살 학생입니다.

0개의 댓글