从 SwiftUI 的导航栏中删除后退按钮文本

Jor*_*rdy 9 navigation ios swift swiftui

我最近开始在 SwiftUI 中工作,得出的结论是使用导航还不是很好。我想要实现的是以下内容。我终于在不使应用程序崩溃的情况下摆脱了半透明背景,但现在我遇到了下一个问题。如何摆脱导航栏内的“返回”文本?

在此处输入图片说明

我通过在SceneDelegate.swift文件中设置默认外观来实现上述视图。

let newNavAppearance = UINavigationBarAppearance()
newNavAppearance.configureWithTransparentBackground()
newNavAppearance.setBackIndicatorImage(UIImage(named: "backButton"), transitionMaskImage: UIImage(named: "backButton"))
newNavAppearance.titleTextAttributes = [
    .font: UIFont(name: GTWalsheim.bold.name, size: 18)!,
    .backgroundColor: UIColor.white

]

UINavigationBar.appearance().standardAppearance = newNavAppearance
Run Code Online (Sandbox Code Playgroud)

我可以实现这一目标的一种可能方法是覆盖导航栏项目,但是这有一个缺点(用于 NavigationView 的 SwiftUI 自定义后退按钮文本),正如此问题的创建者已经说过的那样,覆盖导航栏后后退手势停止工作项目。有了这个,我也想知道如何设置后退按钮的前景颜色。它现在具有默认的蓝色,但是我想用另一种颜色覆盖它。

Pit*_*oas 12

其实真的很简单。以下解决方案是我制作的最快和最干净的解决方案。

例如,将它放在 SceneDelegate 的底部。

extension UINavigationController {
    // Remove back button text 
    open override func viewWillLayoutSubviews() {
        navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

这将从应用程序中的每个 NavigationView (UINavigationController) 中删除后退按钮文本。

  • 这应该是公认的答案。 (3认同)

Rol*_*tte 11

我找到了一种简单的方法来仅使用 SwiftUI 删除后退按钮文本,并保留原始 V 形。

当用户想要通过向右滑动返回时,添加了一个拖动手势来模仿经典的导航后退按钮。

import SwiftUI

struct ContentView: View {

  @Environment(\.presentationMode) var presentation

  var body: some View {
    ZStack {
      // Your main view code here with a ZStack to have the
      // gesture on all the view.
    }
    .navigationBarBackButtonHidden(true)
    .navigationBarItems(
      leading: Button(action: { presentation.wrappedValue.dismiss() }) {
        Image(systemName: "chevron.left")
          .foregroundColor(.blue)
          .imageScale(.large) })
    .contentShape(Rectangle()) // Start of the gesture to dismiss the navigation
    .gesture(
      DragGesture(coordinateSpace: .local)
        .onEnded { value in
          if value.translation.width > .zero
              && value.translation.height > -30
              && value.translation.height < 30 {
            presentation.wrappedValue.dismiss()
          }
        }
    )
  }
}
Run Code Online (Sandbox Code Playgroud)


bla*_*lau 9

依靠@Pitchbloas 提供的解决方案,此方法只涉及将backButtonDisplayMode属性设置为.minimal

extension UINavigationController {

  open override func viewWillLayoutSubviews() {
    navigationBar.topItem?.backButtonDisplayMode = .minimal
  }

}
Run Code Online (Sandbox Code Playgroud)

  • 发现这是一个很好的解决方案,但应该在设置按钮显示模式之前调用“super.viewWillLayoutSubviews()” (2认同)
  • 这将改变应用程序中每个后退按钮的行为。如果这就是您想要的,这是一个很棒且简单的解决方案,否则看看其他答案...... (2认同)

Fre*_*ame 6

如果你想:

  • 在全球范围内进行
  • 保留标准后退按钮(以及自定义行为,例如长按即可返回几个屏幕的功能)
  • 避免引入任何第三方框架

您可以通过外观将后退按钮文本颜色设置为透明颜色来做到这一点:

let navigationBarAppearance = UINavigationBarAppearance()

let backButtonAppearance = UIBarButtonItemAppearance(style: .plain)
backButtonAppearance.focused.titleTextAttributes = [.foregroundColor: UIColor.clear]
backButtonAppearance.disabled.titleTextAttributes = [.foregroundColor: UIColor.clear]
backButtonAppearance.highlighted.titleTextAttributes = [.foregroundColor: UIColor.clear]
backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]

navigationBarAppearance.backButtonAppearance = backButtonAppearance

//Not sure you'll need both of these, but feel free to adjust to your needs.
UINavigationBar.appearance().standardAppearance = navigationBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance

Run Code Online (Sandbox Code Playgroud)

您可以在应用程序启动时执行一次,然后就可以忘记它。

一个潜在的缺点(取决于您的喜好)是,当您移动到另一个窗口时,当前窗口的标题会向左滑动,因此到透明颜色的过渡会以动画方式进行。

您还可以尝试不同的文本属性。

演示


yil*_*soy 6

你可以使用 .toolbarRole(.editor)


Jor*_*rdy 4

所以我实际上最终得到了以下实际有效的解决方案。我正在像这样覆盖导航栏项目

.navigationBarItems(leading:
    Image("backButton")
        .foregroundColor(.blue)
        .onTapGesture {
            self.presentationMode.wrappedValue.dismiss()
    }
)
Run Code Online (Sandbox Code Playgroud)

唯一的问题是后退手势不起作用,因此通过实际扩展来解决这个问题UINavigationController

extension UINavigationController: UIGestureRecognizerDelegate {
    override open func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }
}
Run Code Online (Sandbox Code Playgroud)

现在它看起来正是我想要的方式,解决方案有点 hacky...但它现在有效,希望 SwiftUI 会成熟一点,这样就可以更容易地完成。