[SwiftUI] 토스트 뷰 생성 방법

3596 단어


사용하는 방법




struct ContentView: View {
    @State var presentTop: Bool = false

    var body: some View {
        VStack {
            TPButton(title: "☝️", action: {
                presentTop = true
            })
        }
        .navigationBarTitleDisplayMode(.inline) // if it's needed
        .toast(isPresented: $presentTop, edge: .top) { toastContent }
    }

    var toastContent: some View {
        HStack {
            Image(systemName: "checkmark.circle").font(.headline)
            Text("Toast!").font(.headline)
        }
        .frame(maxHeight: .infinity)
        .padding()
        .background(RoundedRectangle(cornerRadius: 8.0).foregroundColor(.random)) // set color whatever you want
    }



3단계


  • ToastView 만들기
  • ViewModifier 생성
  • ViewModifier 생성

  • 1단계: ToastView 만들기

    struct Toast<Content:View>: View {
        @Binding var isPresented: Bool
        @State var edge: Edge
        var content: Content
        let action: (() -> Void)?
    
        private var alignment: Alignment {
            switch edge {
            case .top: return .top
            case .leading: return .leading
            case .bottom: return .bottom
            case .trailing: return .trailing
            }
        }
    
        init(isPresented: Binding<Bool>, edge: Edge, action: (() -> Void)? = nil, @ViewBuilder content: () -> Content) {
            _isPresented = isPresented
            _edge = State(wrappedValue: edge)
            self.action = action
            self.content = content()
        }
    
        var body: some View {
            ZStack(alignment: alignment) {
                Spacer().frame(maxWidth: .infinity, maxHeight: .infinity)
                content
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding()
            .animation(.spring(), value: isPresented)
            .transition(.move(edge: edge).combined(with: .opacity))
            .onTapGesture {
                withAnimation {
                    isPresented = false
                    action?()
                }
            }
        }
    }
    


    2단계: ViewModifier 생성

    struct ToastModifier<ToastContent: View>: ViewModifier {
    
        @Binding var isPresented: Bool
        var toast: Toast<ToastContent>
    
        init(isPresented: Binding<Bool>, edge: Edge, action: (() -> Void)? = nil, @ViewBuilder toastContent: () -> ToastContent) {
            _isPresented = isPresented
            toast = Toast(isPresented: isPresented, edge: edge, action: action, content: toastContent)
        }
    
        public func body(content: Content) -> some View {
            ZStack {
                content
                if isPresented { toast }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.clear.ignoresSafeArea(.all, edges: .all))
            .animation(.spring(), value: isPresented)
        }
    }
    


    3단계: 확장 보기

    public extension View {
        func toast<Content:View>(isPresented: Binding<Bool>, edge: Edge, action: (() -> Void)? = nil, @ViewBuilder content: () -> Content) -> some View {
            self.modifier(ToastModifier(isPresented: isPresented, edge: edge, action: action, toastContent: content))
        }
    }
    

    좋은 웹페이지 즐겨찾기