SwiftUI로 모달 표시를 해보자!

7762 단어 SwiftSwiftUI
이번에는 SwiftUI에서 하프 모달 뷰를 만드는 방법에 대해 소개하고 싶습니다.

동작





「모달 표시」버튼을 누르기→모달 표시
"닫기"or 다시 "모달 표시"를 누르기 → 모달 숨기기
를 전환하고 있습니다.

프로그램



ContentView.swift
import SwiftUI

struct ContentView: View {
    @State var screenHeight: CGFloat = 0.0
    @State private var showHalfModal = false

    var body: some View {
        GeometryReader(content: { geometry in
            ZStack{
                Button(action: {
                    self.showHalfModal.toggle()
                }, label: {
                    Text("モーダルを表示")
                        .font(.largeTitle)
                })
                HalfModal(closedButton: $showHalfModal,
                          sizeY: screenHeight,
                          objectHeight: 400.0)
            }
            .onAppear(perform: {
                screenHeight = geometry.size.height  // スクリーンサイズ(縦幅)を取得
            })
        })
        .ignoresSafeArea(.all) // 上下のセーフエリアを無効化
    }
}

struct HalfModal: View {
    @Binding var closedButton: Bool
    let sizeY: CGFloat
    let objectHeight: CGFloat

    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 50.0)
                .foregroundColor(.red)
            VStack {
                Spacer()
                Button(action: {
                    closedButton.toggle()
                }, label: {
                    Text("閉じる")
                        .foregroundColor(.white)
                        .font(.largeTitle)
                })
                Spacer()
            }
        }
        .frame(height: objectHeight)
        .offset(y: closedButton ? sizeY-objectHeight :  sizeY)
    }
}


프로그램 설명



GeometryReader로 화면 크기 획득


.ignoresSafeArea(.all) 에서 ContentView의 SafeArea를 사용하지 않도록 설정하고 geometry.size.height 에서 전체 화면의 세로 폭을 가져오고 screenHeight 변수에 할당합니다.

ZStack에서 동시에 표시


ContentViewHalfModal 를 ZStack으로 묶어서 한 화면에 두 개의 View 구성 요소를 표시합니다. 그리고, HalfModal측에서 offset() (표시 위치의 이동)를 선언하는 것으로, 화면 하단에 하프 모달이 표시되게 됩니다.

오프셋으로 표시 위치 변경



Swift는 진위 값으로 처리를 분기 할 수 있습니다.
[Bool] ? [trueの処理]:[falseの処理]

같은 처리를 작성할 수 있습니다.

그러므로
  • true : y 좌표를 "전체 세로 너비"위치에 표시
  • false : y 좌표를 "전체 세로 너비"- "모달 세로 너비"위치에 표시합니다

  • 라고 지정해 주면 액션을 일으키는(=Bool치를 변경한다)과 다른 View가 표시되는 처리를 구현할 수가 있습니다.

    소스 코드



    GitHub상에서 공개하고 있으므로, 참고 정도에 부디.

    좋은 웹페이지 즐겨찾기