๐จ SwiftUI๋ UIKit์์์ Present๋ฅผ ๋ค์ ์ํธ๋ฅผ ์ผ๋ถ ๊ฐ๋ฆฌ๋ฉฐ Swipe๋ก ๋ด๋ฆด ์ ์๋ Present, ๋ค ์ํธ๋ฅผ ์ ๋ถ ๊ฐ๋ฆฌ๋ฉฐ Swipe๋ก ๋ด๋ฆด ์ ์๋ Fullscreen ๋ ๊ฐ์ง ๋ชจ๋ํ์ด์ด๋ก ๋๋์๋ค. ์ด ๋์ ๋ ๊ฐํธํ๊ฒ ์ฌ์ฉํ๊ณ ์ถ์๋ค.
๊ธฐ์กด ์ฝ๋์ ๋ฌธ์ ์
- ๊ธฐ์กด ์ฝ๋) Swift Enum ์ฐ๊ด๊ฐ์ ํตํ Present, FullScreen ๋ถ๋ฆฌ ์ํ ์ผ์ด์ค ์์ฑ
extension ProfileView{
enum SheetType:String, Identifiable{
var id: String{ self.rawValue}
case profile // ํ๋กํ์ผ ๋ทฐ๋ก ๊ฐ๊ธฐ ์ํ ์ฒ๋ฆฌ
}
enum FullscreenType:String, Identifiable{
var id: String{ self.rawValue}
case settings // ์ค์ ๋ทฐ๋ก ๊ฐ๊ธฐ ์ํ ์ฒ๋ฆฌ
}
enum PresentType:Equatable{
case sheet(SheetType)
case fullscreen(FullscreenType)
}
...
}
- ๋ฌธ์ 1) ๋ถ๊ธฐ ์ฒ๋ฆฌ์ ๋ณต์กํจ๊ณผ ๋ทฐ ์ปดํฌ๋ํธ ๋ด๋ถ์
@State
์ฝ๋ ์ฆ๊ฐ
struct ProfileView: View{
...
@State var presentType:PresentType? = nil
@State var sheetType: SheetType? = nil
@State var fullScreenType: FullscreenType? = nil
...
}
- ๋ฌธ์ 2) ์ฐ๊ด ๊ฐ์ ์ด์ฉํ ๋ทฐ ์ปดํฌ๋ํธ ๋ด๋ถ ์ฒ๋ฆฌ ๋ก์ง ๊ตฌ์ฑ
struct ProfileView: View{
...
.onChange(of: presentType, perform: { value in
switch value{
case .fullscreen(let fullScreen):
self.fullScreenType = fullScreen
self.sheetType = nil
case .sheet(let sheet):
self.sheetType = sheet
self.fullScreenType = nil
case .none: break
}
self.presentType = nil
})
...
}
⇒ ์ฌ์ค ์ด ๋ก์ง์ Extension์ผ๋ก ๋นผ๋ ๋จ
โ ๋ทฐ ์ปดํฌ๋ํธ์์ ์ฒ๋ฆฌํ๋ ์ฝ๋์ ์๋ฅผ ์ค์ฌ๋ณด์!!
ํด๊ฒฐ ๋ฐ ํ๊ณ์
ํด๊ฒฐ
- ๋ชจ๋ ํ์ด์ด ์์ฑ ๋ฐ ๋ด๋ถ ๋ก์ง ์ฒ๋ฆฌ
extension ProfileView{
...
struct SheetModifier<A: View,B:View>: ViewModifier{
@Binding var presentType:PresentType?
@ViewBuilder var sheet:((SheetType) -> A)
@ViewBuilder var fullScreen:((FullscreenType) -> B)
@State private var fullScreenType: ProfileView.FullscreenType? = nil
@State private var sheetType: SheetType? = nil
func body(content: Content) -> some View {
content
.sheet(item: $sheetType, content:sheet)
.fullScreenCover(item: $fullScreenType,content: fullScreen)
.onChange(of: presentType, perform: { value in
switch value{
case .fullscreen(let fullScreen):
self.fullScreenType = fullScreen
self.sheetType = nil
case .sheet(let sheet):
self.sheetType = sheet
self.fullScreenType = nil
case .none: break
}
self.presentType = nil
})
}
}
}
- ๋ทฐ ์ปดํฌ๋ํธ ํ์ผ ๋ด๋ถ์ extension
struct ProfileView{
...
}
fileprivate extension View{
func present<A:View,B:View>(presentType:Binding<ProfileView.PresentType?>,sheet:@escaping ((ProfileView.SheetType) -> A),fullScreen:@escaping ((ProfileView.FullscreenType) -> B))->some View{
self.modifier(ProfileView.SheetModifier(presentType: presentType, sheet: sheet, fullScreen: fullScreen))
}
}
- ์ฌ์ฉ ์์
struct ProfileView{
...
@State var presentType:PresentType? = nil
...
.present(presentType: $presentType) { item in
switch item{
case .profile: ProfileEditView()
}
} fullScreen: { item in
switch item{
case .settings: SettingView()
}
}
}
ํ๊ณ์
- Detent (Sheet ๋์ด๋ฅผ ์ปค์คํ ํ๋ ๊ธฐ๋ฅ) ์ฒ๋ฆฌ๋ ํ ์ ์๋ค.
- ๊ฐ๊ฐ์ ๋ทฐ ๋ง๋ค ์๋ง๋ PresentType, FullscreenType, ๋ชจ๋ํ์ด์ด๋ฅผ ์ง์ ์ ๋ ฅ ํด์ผํ๋ค.
- PresentType, FullScreenType์ด ๋ทฐ๋ฅผ ํ์ํ๊ธฐ ์ํ Enum ํ์ ์ผ๋ก ๊ธฐ์กด .sheet์์ ์ํ๋ ์์ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ๊ณผ ๋ฌ๋ฆฌ ์ถ๊ฐ์ ์ธ ๋ก์ง ์ฒ๋ฆฌ๊ฐ ํ์ํ ์ ์๋ค.
'์ด๋ชจ์ ๋ชจ > SwiftUI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TCA - ๋ฝ๋ชจ๋๋ก ์ฑ, Timer View Interaction (0) | 2024.05.07 |
---|---|
TCA์์ Stream ์์ฑ ๋ฐ ์ฃผ์ (0) | 2024.04.13 |
Using @globalActor RealmSwift in TCA (0) | 2024.03.25 |
TCA - Pagination TabView ์ฌ์ฉ (0) | 2024.03.17 |
์น ํต์ ๊ณผ ObservedObject, StateObject (0) | 2024.02.20 |
๋๊ธ