首页 > 解决方案 > 使用 SwiftUI 将 TextField 添加到 NavigationBar

问题描述

在过去的几个小时里,我一直在玩弄 Xcode 11 和 SwiftUI,试图在 NavigationBar 中实现一个 TextField。通常,我构建的第一个“Hello, World”类型的应用程序是一个简单的 Web 浏览器:TextField 和 WKWebView。

但是,我在尝试在固定的.inlineNavigationBar 中实现 TextField 时遇到了异常困难的情况。此外,我似乎无法在网上任何地方找到一个教程或一段代码。我浏览了谷歌的页面和页面,以及 GitHub 上的项目,但没有运气。

唯一具体提到这个主题的结果是 Reddit 线程和论坛讨论帖子——所有这些都提出了相同的问题:“有没有人能够成功地在 NavigationBar 中实现 TextField?” 还没有人回应解决方案。

这是我当前的ContentView.swift - 我已经删除了所有实现 TextField 的编程尝试,因为它要么崩溃要么抛出错误:

import SwiftUI
import WebKit

let address = "https://developer.apple.com"

struct ContentView: View {
    var body: some View {

        NavigationView {
            VStack {
                WebView(request: URLRequest(url: URL(string: address)!))
                    .edgesIgnoringSafeArea(.bottom)
                    .edgesIgnoringSafeArea(.leading)
                    .edgesIgnoringSafeArea(.trailing)
            }

            .navigationBarTitle("TextField Placeholder", displayMode: NavigationBarItem.TitleDisplayMode.inline)

        }
    }
}

struct WebView: UIViewRepresentable {
    let request: URLRequest

    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }
}

标签: swiftxcodeswiftui

解决方案


我不知道这是否正是您想要实现的目标,我认为这可能是一个很好的解决方案:

import SwiftUI
import WebKit

let address = "https://developer.apple.com"

struct ContentView: View {
    @State private var text = ""

    var body: some View {
        NavigationView {
            GeometryReader { geometry in
                VStack {
                    WebView(request: URLRequest(url: URL(string: address)!))
                        .edgesIgnoringSafeArea(.bottom)
                        .edgesIgnoringSafeArea(.leading)
                        .edgesIgnoringSafeArea(.trailing)
                }
                .navigationBarItems(leading:
                    HStack {
                        TextField("Type something here...", text: self.$text)
                            .background(Color.yellow)
                    }
                    .padding()
                    .frame(width: geometry.size.width)
                    .background(Color.green)
                )
            }
        }
    }
}

struct WebView: UIViewRepresentable {
    let request: URLRequest

    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

复制粘贴上面的代码,如果我可以尝试用其他方法改进我的解决方案,请告诉我。我为几个绿色和黄色的视图着色只是为了调试。


推荐阅读