Skip to content

Commit

Permalink
feat: SafeAreaSize, FaceView, SceneView #14
Browse files Browse the repository at this point in the history
- SafeAreaSize: safeArea 값 전역으로 사용할 수 있도록 Store에 값 추가
- FaceView: 애니메이션 테스트, 상수 데이터 구조체 작성
- SceneView: SequenceView 분리,  FaceView 애니메이션을 위한 상태 추가
  • Loading branch information
yuncoffee committed Mar 28, 2023
1 parent 7c473e2 commit 58dea8a
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 41 deletions.
13 changes: 10 additions & 3 deletions ContentView.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import SwiftUI

struct ContentView: View {

@EnvironmentObject
var globalStore: GlobalStore

var body: some View {
GeometryReader { geo in
VStack(spacing: 0){
SceneView()
CharacterView()
// CharacterView()
ScriptBoxView(width: geo.size.width)
QuizModalView()
// QuizModalView()
}
.border(.red, width: 1)

}
.onAppear{
let safeAreaSize = getSafeAreaSize()
globalStore.updateSafeAreaSize(currentSafeAreaSize: safeAreaSize)
}
}
}
Expand Down
46 changes: 44 additions & 2 deletions Data/Global/globalStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ enum EnumDetailImage: CaseIterable {
enum EnumDirection: CaseIterable {
case left, right, back, front
}

class GlobalStore: ObservableObject {
/**
현재 Scene을 구분하기 위한 enum
Expand All @@ -57,6 +57,16 @@ class GlobalStore: ObservableObject {
*/
@Published
var currentSpeaker = EnumSpeaker.system
/**
현재 스크립트를 말하는 대상들을 알기 위한 enum 배열
*/
@Published
var currentFaces: [EnumSpeaker] = [EnumSpeaker.coffee]
/**
FaceView가 보여지는 상태인지 알기 위한 변수
*/
@Published
var isFaceViewActive = false
/**
현재 오브젝트의 디테일 이미지를 보여주는 팝업뷰가 열려있는지 확인하기 위한 변수
*/
Expand All @@ -68,6 +78,17 @@ class GlobalStore: ObservableObject {
*/
var scriptCount = 0

/**
SafeArea의 값을 들고 있는 변수
*/
@Published
var safeAreaSize: SafeAreaSize = (0, 0) {
didSet {
print("safeArea top: ", safeAreaSize.0)
print("safeArea btm: ", safeAreaSize.1)
}
}

init() {
print("globalStore is ready")
}
Expand All @@ -94,9 +115,23 @@ extension GlobalStore {
}
}

// currentFaces
extension GlobalStore {
func updateCurrentFaces(faces: [EnumSpeaker]) {
currentFaces = faces
}
}

// isFaceViewActive
extension GlobalStore {
func toggleIsFaceViewActive() {
isFaceViewActive.toggle()
}
}

// isPopupActive
extension GlobalStore {
func toggleIsPopupActive(){
func toggleIsPopupActive() {
isPopupActive.toggle()
}
}
Expand All @@ -107,3 +142,10 @@ extension GlobalStore {
scriptCount += 1
}
}

// safeAreaSize
extension GlobalStore {
func updateSafeAreaSize(currentSafeAreaSize: SafeAreaSize) {
safeAreaSize = currentSafeAreaSize
}
}
5 changes: 5 additions & 0 deletions Data/Scene/SceneData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@

import Foundation

struct FACE_VIEW_INFO {
let size = CGSize(width: 150, height: 200)
let srcRoot = "Face"
}

22 changes: 22 additions & 0 deletions Utils/Window/safeArea.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// File.swift
//
//
// Created by Yun Dongbeom on 2023/03/28.
//

import Foundation
import SwiftUI

typealias SafeAreaSize = (CGFloat, CGFloat)

func getSafeAreaSize() -> SafeAreaSize {
var safeAreaSize: SafeAreaSize = (0, 0)

let windowScene = UIApplication.self.shared.connectedScenes.first as? UIWindowScene

safeAreaSize.0 = windowScene?.windows.first?.safeAreaInsets.top ?? 0
safeAreaSize.1 = windowScene?.windows.first?.safeAreaInsets.bottom ?? 0

return safeAreaSize
}
12 changes: 4 additions & 8 deletions View/SceneView/FaceView/FaceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,14 @@
import SwiftUI

struct FaceView: View {

var direction = "left"
var target = EnumSpeaker.coffee

private let VIEW_SIZE = CGSize(width: 150, height: 200)

private let IMAGE_PATH = "Face"

private let structInfo = FACE_VIEW_INFO()

var body: some View {
Image("\(IMAGE_PATH)_\(target)")
.frame(width: VIEW_SIZE.width, height: VIEW_SIZE.height)
.background(Color.green)
Image("\(structInfo.srcRoot)_\(target)")
.frame(width: structInfo.size.width, height: structInfo.size.height)
}
}
102 changes: 74 additions & 28 deletions View/SceneView/SceneView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,90 @@ import SwiftUI
*/
struct SceneView: View {



@EnvironmentObject
var globalStore: GlobalStore

private let FACE_VIEW_INFO_SIZE = FACE_VIEW_INFO().size

/**
rightFaceView의 애니메이션 효과를 위한 값
*/
@State
private var rightFaceViewPositionX = 0.0

/**
leftFaceView의 애니메이션 효과를 위한 값
*/
@State
private var leftFaceViewPositionX = 0.0

private func updateRightFaceViewPositionX(value: CGFloat) {
rightFaceViewPositionX = value
}

private func updateLeftFaceViewPositionX(value: CGFloat) {
leftFaceViewPositionX = value
}

private func setSequenceView(currentScene: EnumScene) -> any View {
switch currentScene {
case .opeaning:
return SequenceOpeningView()
case .sequence1:
return SequenceOneView()
case .sequence2:
return SequenceTwoView()
case .sequence3:
return SequenceThreeView()
case .ending:
return SequenceEndingView()
}
}

/**
동작 테스트용 코드
*/
private func delayText() {
setTimeoutClosure(timeCount: 3) {
globalStore.isPopupActive = true
globalStore.updateCurrentFaces(faces: [.coffee, .muho])
}
}

var body: some View {
GeometryReader {
geo in

let deviceWidth = geo.size.width
let deviceHeight = geo.size.height



ZStack(alignment:.leading) {
if globalStore.currentScene == .opeaning {
SequenceOpeningView()
.onAppear{
print(globalStore.currentSpeaker)
delayText()
}
}else if globalStore.currentScene == .sequence1 {
SequenceOneView()
// SequenceViewContainer
HStack {
AnyView(setSequenceView(currentScene: globalStore.currentScene))
}
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let windows = windowScene.windows {
let safeAreaBtm = windows.first?.safeAreaInsets.bottom ?? 0
FaceView()
.frame(width: deviceWidth, height: deviceHeight)
.background(Color.green)
// FaceViewArea
if globalStore.isFaceViewActive {
let facePositionY = deviceHeight - 212 - FACE_VIEW_INFO_SIZE.height + globalStore.safeAreaSize.1
// 시작은 무조건 오른쪽부터 시작
FaceView(direction: "right", target: globalStore.currentFaces[0])
.border(.red)
.offset(x: deviceWidth - 150 ,y: deviceHeight - 212 - 200 + safeAreaBtm
)
.background(Color.cyan)
.animation(.linear(duration: 0.4), value: rightFaceViewPositionX)
.offset(x: rightFaceViewPositionX, y: facePositionY)
.onAppear{
print(deviceHeight)
print(deviceWidth)
print(geo.safeAreaInsets.bottom)
print(geo.safeAreaInsets.top)
print(geo.safeAreaInsets.leading)
print(geo.safeAreaInsets.trailing)
print(safeAreaBtm)
// updateRightFaceViewPositionX(value: deviceWidth - FACE_VIEW_INFO_SIZE.width) // 동작 테스트 용 코드
}
// currentFaces의 index 1번째가 있을 경우 무조건 왼쪽에서 보여짐.
if globalStore.currentFaces.count > 1 {
FaceView(direction: "left", target: globalStore.currentFaces[1])
.border(.red)
.background(Color.yellow)
.animation(.linear(duration: 0.4), value: leftFaceViewPositionX)
.offset(x: leftFaceViewPositionX, y: facePositionY)
.onAppear{
// updateLeftFaceViewPositionX(value: 0) // 동작 테스트용 코드
}
}
}
if globalStore.isPopupActive {
Expand All @@ -68,6 +107,13 @@ struct SceneView: View {
}
.frame(width: deviceWidth, height: deviceHeight)
.background(Color.brown)
.onAppear{
// 동작 테스트용 코드
// globalStore.updateCurrentFaces(faces: [.coffee])
// globalStore.toggleIsFaceViewActive()
// updateRightFaceViewPositionX(value: deviceWidth)
// updateLeftFaceViewPositionX(value: -FACE_VIEW_INFO_SIZE.width)
}
}
}
}

0 comments on commit 58dea8a

Please sign in to comment.