-
SwiftUI - isDetailLink (With. NavigationLink)SwiftUI 2022. 8. 23. 11:38
안녕하세요. 그린입니다🍏
이번 포스팅에서는 SwiftUI에서 isDetailLink라는 메서드를 알아보려고 합니다🙋🏻
우선 이 메서드는 SwiftUI에서 화면 전환을 담당해주는 NavigationView를 통해 실제적인 화면 전환 링크인 NavigationLink를 통해서 이뤄지게 됩니다.
그럴때 이 해당 NavigationLink라는 구조체를 사용할때 isDetailLink라는 메서드를 기능으로 붙여줄 수 있습니다.
그럼 실제적으로 이 isDetailLink가 무엇인지 어떤 역할을 하는지 한번 알아보시죠!
isDetailLink?
인스턴스 메서드로 정의는 이렇습니다.
"네비게이션 뷰를 포함하는 디테일 요소로 나타내도록 네비게이션 링크를 설정한다"
이 한문장이 핵심이라고 생각합니다.
즉 상위뷰에서 하위뷰와 그 하위뷰의 하위뷰가 있는 구조일 시 상위뷰에서 NavigationLink로 하위뷰를 노출하면 하하위뷰를 네비게이션 가지고 있는 뷰를 띄워주는것이죠.
고로 하하위뷰를 가지고 있는 하위뷰를 띄워줬을때 그 하위뷰를 한 뷰에서가 아닌 디테일 요소로 나타내도록 설정해주는것입니다.
이렇게 들으면 당연히 단박에 이해가 안가는게 팩트일거에요..😭
저도 그렇구요.
그렇기에 한번 해당 공식문서의 구현부와 설명을 조금 더 파해쳐보고 예시까지 한번 구현해보죠!
isDetailLink 메서드 선언 및 부가 설명
func isDetailLink(_ isDetailLink: Bool) -> some View
메서드 시그니쳐는 간단합니다.
isDetailLink할것인지 Bool 값을 받아 뷰로 반환 시켜줍니다!
즉 반환값은 지정한 네비게이션 링크 동작이 적용된 뷰입니다.
이 메서드는 네비게이션 링크가 NavigationSplitView 또는 ColumnNavigationViewStyle을 사용하는것과 같은 다중 열 네비게시연 뷰에서 사용될 때 설정한다고 해요
이말인 즉슨, 쉽게 생각되는 그림은 아이패드와 같이 스플릿뷰가 있는 환경에서 메모 앱을 떠올려보자구요.
그럼 아래와 같이 좌측은 메모 목록을 우측은 메모 목록 클릭이 된 디테일한 뷰를 보여줍니다.
iOS 즉 아이폰 디바이스에서는 한 뷰에서 모두 보이고 네비게이션 전환으로 이뤄지지만 아이패드는 다르죠.
위와 같은 화면이죠.
이 네비게이션 방식이 바로 디테일링크 설정을 true로 준것입니다.
false로 주게 된다면 우측 디테일 뷰가 나타나는것 없이 좌측에서 모두 네비게이션이 이뤄지는것이에요.
자 그럼 이론만으로 충분히 이해가 되지 않을 수 있으니 실제로 구현해보죠!
isDetailLink 구현하기
우선 3개의 뷰를 계층 구조로 만들어볼께요.
즉 상위뷰에서 하위뷰가 있고 하위뷰에서는 하하위뷰가 있고 이 모든 방식은 네비게이션 화면 전환을 따르는 뷰가 있습니다.
그럼 우선 isDetailLink 설정을 true로 했을때 어떻게 동작되는지 한번 보겠습니다.
isDetailLink(true)
import SwiftUI struct ParentView: View { @State var isActive : Bool = false var body: some View { NavigationView { NavigationLink( destination: ChildView(parentViewIsActive: self.$isActive), isActive: self.$isActive ) { Text("I'm Parent View") } .isDetailLink(true) .navigationBarTitle("Parent") } } } struct ChildView: View { @Binding var parentViewIsActive : Bool var body: some View { NavigationLink( destination: GrandsonView(shouldPopToParentView: self.$parentViewIsActive) ) { Text("I'm Child View") } .isDetailLink(true) .navigationBarTitle("Child") } } struct GrandsonView: View { @Binding var shouldPopToParentView : Bool var body: some View { VStack { Text("I'm Grandson View") Button ( action: { self.shouldPopToParentView = false } ) { Text("Pop to Parent View") } } .navigationBarTitle("Grandson") } }
우선 코드는 이렇습니다.
여기서 상위뷰는 ParentView고 그 하위뷰는 ChildView 그리고 그 하하위뷰는 GrandsonView입니다.
Parent에서 Child로 네비게이션 되기 위해 링크를 설정하고 스플릿 화면에서 나눠 전환될 수 있도록 디테일 링크를 true로 설정합니다.
그럼 아래와 같이 동작될거에요.
즉 스플릿뷰에서 익숙한 사용성처럼 동작하죠.
그럼 반대로 해당 옵션이 false일때 어떻게 동작하는지 보시죠!
isDetailLink(false)
코드는 위와 동일하게 단순히 .isDetailLink(false) 로 변경한것 뿐이니 따로 추가하진 않겠습니다!
바로 구동 영상 보시죠🙌
차이가 단번에 나오죠?
우측 스플릿 뷰 즉 디테일 화면을 이용하지 않습니다.
해당 Parent View 화면 영역에서 모든게 이뤄지죠.
이 차이가 있습니다🙌
마무리
제가 아이패드 앱 개발은 서툰데 이걸 왜했냐면 아이폰 즉 iOS 환경에서도 isDetailLink의 false 설정이 필요할때가 있습니다.
아마 알기론 해당 설정이 없다면 true로 기본적으로 되어 있는것 같은데 iOS에서 저런 메모 앱을 예를들어 계층 화면 전환을 할때 간헐적으로 하위뷰들에서 다시 상위뷰로 back이 되지 않더라구요.
그 정확한 원인과 증상이 발현되는 조건은 잘 모르겠습니다ㅠㅠ
아직 못찾았어요..! 누군가 아신다면 공유 부탁드립니다🙌
그렇기에 사실 iOS 앱 개발 시 해당 조건을 false로 원인모를 에러 방지 처럼 사용하게 되었어요.
나중에 정확하게 알게되면 저도 공유하겠습니다🙏🏻
아, 참고로 해당 코드는 아래 제 깃헙에 올려두었습니다~!!
https://github.com/GREENOVER/playground/tree/main/isDetailLink
[참고자료]
https://developer.apple.com/documentation/swiftui/navigationlink/isdetaillink(_:)
'SwiftUI' 카테고리의 다른 글
Redacted를 통한 뷰 모자이크 (6) 2022.09.08 @FocusState 사용하기 (2) 2022.09.05 SwiftUI에서 MVVM 사용을 멈춰야 하는가? (6) 2022.07.28 SwiftUI 4.0 - NavigationPath (0) 2022.06.23 SwiftUI 4.0 - NavigationStack (0) 2022.06.20