programing

Swift에서 기본 탐색 모음 공간을 제거하는 방법UI 탐색 보기

muds 2023. 4. 26. 23:49
반응형

Swift에서 기본 탐색 모음 공간을 제거하는 방법UI 탐색 보기

나는 스위프트가 처음입니다.UI(대부분의 사용자와 마찬가지로) 및 위에 있는 빈 공간을 제거하는 방법을 알아보려고 합니다.List에 것.NavigationView.

이 이미지에서, 당신은 위에 약간의 공백이 있는 것을 볼 수 있습니다.List.

현재 버전

제가 이루고 싶은 것은 다음과 같습니다.

이상적인 버전

다음을 사용해 보았습니다.

.navigationBarHidden(true)

하지만 눈에 띄는 변화는 없었습니다.

현재 탐색을 설정하는 중입니다.다음과 같이 보기:

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
        .navigationBarHidden(true)
}

FileBrowserView는 가있뷰입다니가 뷰입니다.List그리고.FileCell과 같이 됩니다.

List {
   Section(header: Text("Root")) {
       FileCell(name: "Test", fileType: "JPG",fileDesc: "Test number 1")
       FileCell(name: "Test 2", fileType: "txt",fileDesc: "Test number 2")
       FileCell(name: "test3", fileType: "fasta", fileDesc: "")
    }
}

여기서 궁극적인 목표는 이러한 셀을 클릭하여 파일 트리를 더 깊이 탐색할 수 있으므로 더 깊이 탐색할 때 표시줄에 뒤로 단추를 표시하는 것이지만, 초기 보기에서는 맨 위에 아무것도 표시하지 않습니다.

이유에서인지 스위프트, .하려면 UI를 ..navigationBarTitle위해서.navigationBarHidden제대로 작동합니다.

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
        .navigationBarTitle("")
        .navigationBarHidden(true)
}

갱신하다

@Peacemoon이 설명에서 지적했듯이, 설정 여부에 관계없이 탐색 스택에서 더 깊이 탐색할 때 탐색 막대는 숨겨집니다.navigationBarHiddenfalse은 애플의 문서일 뿐입니다(알겠습니까,할 "도 모릅니다).제가 논평에서 말했듯이, 이것은 애플의 잘못된 구현의 결과이거나 단지 끔찍한 문서일 뿐입니다(누가 알겠습니까, 이것을 달성할 "올바른" 방법이 있을지도 모릅니다).

어쨌든, 저는 원래 포스터의 원하는 결과를 만들어 낼 수 있는 해결책을 생각해냈습니다.불필요하게 촌스러워 보여서 추천하기가 망설여지지만, 내비게이션 바를 숨기고 숨기는 간단한 방법이 없다면, 이것이 제가 할 수 있는 최선입니다.

이 예에서는 세 가지 보기를 사용합니다.View1숨있진모탐습이니다음색겨▁a,▁baration있다습니▁hidden가 있습니다.View2그리고.View3둘 다 제목이 있는 가시적인 탐색 모음이 있습니다.

struct View1: View {
    @State var isNavigationBarHidden: Bool = true

    var body: some View {
        NavigationView {
            ZStack {
                Color.red
                NavigationLink("View 2", destination: View2(isNavigationBarHidden: self.$isNavigationBarHidden))
            }
            .navigationBarTitle("Hidden Title")
            .navigationBarHidden(self.isNavigationBarHidden)
            .onAppear {
                self.isNavigationBarHidden = true
            }
        }
    }
}

struct View2: View {
    @Binding var isNavigationBarHidden: Bool

    var body: some View {
        ZStack {
            Color.green
            NavigationLink("View 3", destination: View3())
        }
        .navigationBarTitle("Visible Title 1")
        .onAppear {
            self.isNavigationBarHidden = false
        }
    }
}

struct View3: View {
    var body: some View {
        Color.blue
            .navigationBarTitle("Visible Title 2")
    }
}

navigationBarHiddenfalse더 재정의하지 것 .navigationBarHiddentrue따라서 새로운 보기를 탐색 스택에 밀어 넣을 때 바인딩을 사용하여 원래 보기의 기본 설정을 변경할 수 있는 유일한 해결 방법이 있었습니다.

제가 말씀드렸듯이, 이것은 진부한 해결책이지만, 애플의 공식적인 해결책이 없다면, 이것은 제가 생각해 낼 수 있는 최고의 해결책입니다.

View 수정자를 사용하면 다음과 같은 이점이 있습니다.

//ViewModifiers.swift

struct HiddenNavigationBar: ViewModifier {
    func body(content: Content) -> some View {
        content
        .navigationBarTitle("", displayMode: .inline)
        .navigationBarHidden(true)
    }
}

extension View {
    func hiddenNavigationBarStyle() -> some View {
        modifier( HiddenNavigationBar() )
    }
}

예:

import SwiftUI

struct MyView: View {
    var body: some View {
        NavigationView {
            VStack {
                Spacer()
                HStack {  
                    Spacer()
                    Text("Hello World!")
                    Spacer()
                }
                Spacer()
            }
            .padding()
            .background(Color.green)
            //remove the default Navigation Bar space:
            .hiddenNavigationBarStyle()
        }
    }
}

의 .NavigationView보기 위에 탐색 모음을 추가하는 것입니다.표준의 두 .OS에서는 대형 내비게이션과 일반 내비게이션의 두 가지 종류가 있습니다.

여기에 이미지 설명 입력

탐색 모음을 사용하지 않으려면:

FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))

대형 탐색 모음(일반적으로 최상위 보기에 사용됨)을 원하는 경우:

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
    .navigationBarTitle(Text("Title"))
}

일반적으로 하위 수준 보기에 사용되는 표준(인라인) 탐색 모음을 원하는 경우:

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
    .navigationBarTitle(Text("Title"), displayMode: .inline)
}

이 답변이 도움이 되길 바랍니다.

추가 정보:애플 문서

iOS 14+

탐색 모음에 공간을 덜 차지하도록 하는 전용 수식어가 있습니다.

.navigationBarTitleDisplayMode(.inline)

편집

에는 경에따야할수있다습니도해가추우라다있을 추가해야 할 ..navigationBarHidden(true)

공간을 제거할 보기의 제목을 인라인으로 설정하면 탐색 보기가 있는 보기에서 이 작업을 수행할 필요가 없고 탐색 보기도 수행할 수 있습니다.

.navigationBarTitle("", displayMode: .inline)

발행시작 용액 1 그런 다음 탐색 모음 모양을 변경합니다.

init() {
    UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
    UINavigationBar.appearance().shadowImage = UIImage()
}

초기 NavigationView를 보유한 뷰에 표시됩니다.최종 해결책

화면에서 화면으로 모양을 변경하려면 해당 보기에서 모양 변경

저는제를 요..navigationBarTitle에▁NavigationView 지도마가 하지.List범인이었습니다..1 Xcode 11.2.1에서 합니다.

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: DetailView()) {
                    Text("I'm a cell")
                }
            }.navigationBarTitle("Title", displayMode: .inline)
        }
    }
}

상단에 공백이 없는 탐색 모음 및 목록

이것은 Swift에 있는 버그입니다.UI(Xcode 11.2.1 기준).나는 썼습니다.ViewModifier를 해결하기 는 기존의 코드를 으로 합니다.

public struct NavigationBarHider: ViewModifier {
    @State var isHidden: Bool = false

    public func body(content: Content) -> some View {
        content
            .navigationBarTitle("")
            .navigationBarHidden(isHidden)
            .onAppear { self.isHidden = true }
    }
}

extension View {
    public func hideNavigationBar() -> some View {
        modifier(NavigationBarHider())
    }
}

저는 또한 이 페이지에 언급된 모든 솔루션을 시도해 보았는데, @gray campbell 솔루션이 잘 작동하고 애니메이션이 잘 작동하는 솔루션이라는 것만 발견했습니다.그래서 저는 hackingwithswift.com 의 예를 통해 어디서나 액세스할 수 있는 앱 전체에서 사용할 수 있는 값을 만들려고 했습니다.

다음을 생성했습니다.ObservableObject

class NavBarPreferences: ObservableObject {
    @Published var navBarIsHidden = true
}

그리고 그것을 의 초기 보기로 전달합니다.SceneDelegate

var navBarPreferences = NavBarPreferences()
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))

다음에그에서.ContentView우리는 이 관찰 가능한 물체를 그렇게 추적하고 링크를 만들 수 있습니다.SomeView:

struct ContentView: View {
    //This variable listens to the ObservableObject class
    @EnvironmentObject var navBarPrefs: NavBarPreferences

    var body: some View {
        NavigationView {
                NavigationLink (
                destination: SomeView()) {
                    VStack{
                        Text("Hello first screen")
                            .multilineTextAlignment(.center)
                            .accentColor(.black)
                    }
                }
                .navigationBarTitle(Text(""),displayMode: .inline)
                .navigationBarHidden(navBarPrefs.navBarIsHidden)
                .onAppear{
                    self.navBarPrefs.navBarIsHidden = true
            }
        }
    }
}

그런 다음 두 번째 보기(SomeView)에 액세스할 때 다음과 같이 다시 숨깁니다.

struct SomeView: View {
    @EnvironmentObject var navBarPrefs: NavBarPreferences

    var body: some View {
        Text("Hello second screen")
        .onAppear {
            self.navBarPrefs.navBarIsHidden = false
        }
    } 
}

미리 보기를 계속 작동시키려면 다음과 같이 NavBar Preferences를 미리 보기에 추가합니다.

struct SomeView_Previews: PreviewProvider {
    static var previews: some View {
        SomeView().environmentObject(NavBarPreferences())
    }
}

는 없고 ▁simply▁you니습,를 사용하면 됩니다. 간단히 사용할 수 있습니다..stack

NavigationView {
     VStack {
         Color.cyan
      }
     .navigationBarHidden(true)
}
.navigationViewStyle(.stack)  // Here

다음 코드를 표시합니다.

        .navigationBarBackButtonHidden(true)
        .navigationBarHidden(true)

그러나 NavigationLink를 통해 NextView로 이동하는 동안 다음과 같은 수식어를 추가해야 합니다.

        NavigationLink(
            destination: NextView()
                .navigationBarTitle("")
                .navigationBarHidden(true)
        ) {
            Text("NEXT VIEW")
        }
                    

다음과 같이 기본 View 프로토콜을 확장할 수 있습니다.

extension View {
    func hideNavigationBar() -> some View {
        self
            .navigationBarTitle("", displayMode: .inline)
            .navigationBarHidden(true)
    }
}

그럼 그냥 전화하세요. 예:

ZStack {
    *YOUR CONTENT*
}
.hideNavigationBar()

기존의 Navigation View를 푸시하고 있었기 때문입니다.사실상 하나가 다른 하나 안에 있습니다.Navigation View에서 오는 경우에는 이미 Navigation View 내부에 있으므로 다음 내부에 Navigation View를 작성할 필요가 없습니다.

이 문제에 대한 나의 해결책은 @Genki와 @Frankenstein이 제안한 것과 같았습니다.

두 개의 수식어를 내부 목록(NavigationView가 아님)에 적용하여 공백을 제거했습니다.

.navigationBarTitle("", displayMode: .automatic)
.navigationBarHidden(true) 

에서 외부탐 적서니다용됩보를 했습니다..navigationBarTitle("TITLE")제목을 설정합니다.

이렇게 Vstack의 괄호 끝에 .navigationBarHidden(true)을 추가하려고 합니다.

NavigationView { Vstack(){"some Code"}.navigationBarHidden(true)}

그리고 네비게이션 바는 사라지지만 만약 내가 .navigationBarHidden(true)을 이와 같은 네비게이션 바의 곱슬곱슬한 괄호 끝에 추가한다면.

    NavigationView { Vstack(){"some Code"}}.navigationBarHidden(true)

탐색 모음이 사라지지 않습니다.

같은 문제를 드디어 풀었습니다.사라지기 는 이 를 이완전사면이수다추합를니다에 .NavigationView 모두NavigationsLinks내부:

.navigationBarHidden(true)
.navigationBarTitleDisplayMode(.inline)

만약 당신이 그것을 또한 하지 않는다면.NavigationLinks작동하지 않습니다.

@gray campbell의 대답과 비슷하지만 조금 더 간단합니다.

struct YourView: View {

    @State private var isNavigationBarHidden = true

    var body: some View {
        NavigationView {
            VStack {
                Text("This is the master view")
                NavigationLink("Details", destination: Text("These are the details"))
            }
                .navigationBarHidden(isNavigationBarHidden)
                .navigationBarTitle("Master")
                .onAppear {
                    self.isNavigationBarHidden = true
                }
                .onDisappear {
                    self.isNavigationBarHidden = false
                }
        }
    }
}

이동하는 보기의 뒤로 단추 옆에 제목이 표시되므로 제목을 설정해야 합니다.

는 설을시습다니했도정을 . .navigationBarTitle("", displayMode: .inline) .navigationBarHidden(true)하지만 효과가 없었습니다.문제는 제가 그것을 설정하고 있었다는 것입니다.

NavigationView{...}.navigationBarTitle("", displayMode: .inline)
        .navigationBarHidden(true)

그러나 Nagigation Bar를 제거하려면 Nagigation Bar의 내부 뷰로 설정해야 합니다.

NavigationView{
InnerView{}.navigationBarTitle("", displayMode: .inline)
        .navigationBarHidden(true)
}

이것이 도움이 되기를 바랍니다. 실제로 보기 위해서, 당신은 이 오픈 소스 앱(WIP) https://github.com/deepaksingh4/KidsBookApp 을 들여다 볼 수 있습니다.

사용자가 로그인하면 TabView가 표시되어야 하는 앱에서 작업할 때도 비슷한 문제가 있었습니다.

@graycampbell이 그의 의견에서 제안했듯이, TabView는 NavigationView에 포함되지 않아야 합니다. 그렇지 않으면 사용 중에도 "빈 공간"이 나타납니다..navigationBarHidden(true)

제가 사용한 것입니다.ZStack탐색 보기를 숨깁니다.이 예는 로이예간다같음습다니과는한단참고같다니습▁use,▁note▁i▁that고▁for 사용합니다.@State그리고.@BindingUI 가시성을 관리하지만 환경 개체와 같은 더 복잡한 개체를 사용할 수도 있습니다.

struct ContentView: View {

    @State var isHidden = false

    var body: some View {
        
        ZStack {
            if isHidden {
                DetailView(isHidden: self.$isHidden)
            } else {
                NavigationView {
                    Button("Log in"){
                        self.isHidden.toggle()
                    }
                    .navigationBarTitle("Login Page")
                }
            }
        }
    }
}

로그인 버튼을 누르면 초기 페이지가 사라지고 Detail View가 로드됩니다.로그아웃 단추를 누르면 로그인 페이지가 다시 나타납니다.

struct DetailView: View {
    
    @Binding var isHidden: Bool
    
    var body: some View {
        TabView{
            NavigationView {
                Button("Log out"){
                    self.isHidden.toggle()
                }
                .navigationBarTitle("Home")
            }
            .tabItem {
                Image(systemName: "star")
                Text("One")
            }
        }
    }
}

한동안 고민했지만 결국 제게 효과가 있었던 건...

ZStack {
    ...
}
.edgesIgnoringSafeArea(.all) //or .edgesIgnoringSafeArea(.top)
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)

1번 화면에서 2번 화면으로 이동해야 합니다.위와 같은 NavigationView에 이 기능을 사용하면 Navigationbar는 숨겨지지만 화면 1에 공간(높이가 있는 공간의 양)이 남아 있습니다.

마지막으로 NavigationView 내부의 모든 보기에서 이 코드를 사용하고 탐색에 관심이 없는 자체 솔루션이 있습니다.제목. 이런 식으로.

화면 1:

NavigationView {
    SomeView {
        NavigationLink {
        // go to screen2
        }
    }.navigationBarHidden(true)
}

화면 2:

NavigationView {
// some Views
}.navigationBarHidden(true)

저도 같은 문제가 있었고 다음 코드가 가장 잘 작동하는 것으로 나타났습니다.

   .navigationTitle("")
   .navigationBarBackButtonHidden(true)

이것은 제가 찾은 가장 간단하고 안정적인 접근법입니다.전체 도구 모음을 숨겨 탐색 제목과 뒤로 단추를 모두 숨길 수 있습니다.원하는 보기에 표시하도록 선택할 수도 있습니다.다음을 사용하여 숨길 수 있습니다..toolbar(.hidden)그리고 그것을 눈에 보이게 하기 위해 사용합니다..toolbar(.visible)수식어

iOS 16+

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                ForEach(0..<10) { i in
                    NavigationLink {
                        Text("Detail for Row \(i)")
                    } label: {
                        Text("Row \(i)")
                    }
                }
            }
            
            .toolbar(.hidden)
        }
    }
}

만약 당신이 iOS 16 아래를 목표로 한다면, 당신은 그것을 대체할 수 있습니다.NavigationStack와 함께NavigationView.

속성(탐색 제목, 도구 모음 등)을 탐색 보기 외부에 배치합니다.이와 같은 경우:

NavigationView {
}
.navigationTitle("Detail News")
.toolbarColorScheme(.dark, for: .navigationBar)
.toolbarBackground(Color.gray, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.accentColor(.white)

@Vatsal Manot가 제공한 아이디어를 정말 좋아했습니다. 이를 위한 수식어를 만들기 위해서입니다.
를 제거하기isHidden수식어 이름 자체가 탐색 모음을 숨기기 때문에 유용하지 않다고 생각하기 때문에 그의 답변에서 속성.

// Hide navigation bar.
public struct NavigationBarHider: ViewModifier {

    public func body(content: Content) -> some View {
        content
            .navigationBarTitle("")
            .navigationBarHidden(true)
    }
}

extension View {
    public func hideNavigationBar() -> some View {
        modifier(NavigationBarHider())
    }
}

제가 여기서 조금 늦었다는 것은 알지만, 여기서 가장 중요한 답변을 사용하여 이 문제를 해결했습니다.Swift를 사용하여 중첩된 NavigationView에서 공간을 제거하는 방법UI

해당 페이지의 내용이 변경될 경우 아래 답변을 설명하겠습니다.

중첩된 하위 항목이 얼마나 아래로 내려가든지 상관없이 탐색이 필요한 보기의 최상위 수준에서만 탐색 보기 래퍼를 사용하십시오.이들은 모두 NavigationView 속성을 가지고 있으며, 하위 뷰 내에서 언제든지 NavigationLink를 호출할 수 있습니다.하위 뷰 주변에 추가 NavigationView 래퍼가 많이 있어서 삭제하면 추가 공백이 제거되고 모든 탐색 링크의 기능은 유지됩니다.

다음을 입력해 보십시오.NavigationView富士山의 GeometryReader.

GeometryReader {
    NavigationView {
        Text("Hello World!")
    }
}

나는 이상한 행동을 경험했습니다.NavigationView루트 뷰였습니다.

언급URL : https://stackoverflow.com/questions/57517803/how-to-remove-the-default-navigation-bar-space-in-swiftui-navigationview

반응형