SwiftUI 在 NavigationView 中添加个人警报视图,后退按钮不适用于 Xcode 12 iOS14
Posted
技术标签:
【中文标题】SwiftUI 在 NavigationView 中添加个人警报视图,后退按钮不适用于 Xcode 12 iOS14【英文标题】:SwiftUI adding personal alert view in NavigationView, the back button doesn't work with Xcode 12 iOS14 【发布时间】:2020-10-03 15:49:08 【问题描述】:我有一个扩展名 (.alertLinearProgressBar),例如 .alert 视图,用于显示解压缩进度。 在 ios 14 运行良好之前,现在如果我发出这个警报,导航返回按钮不再起作用(如果我向右拖动,它正在工作并返回列表,所以我猜问题是与返回按钮冲突栏,只有那个按钮不起作用,顶栏中的其他按钮都起作用)。
有人知道这个问题吗?
import SwiftUI
var chatData = ["1","2","3","4"]
struct ContentView: View
@State private var selection = 0
@State private var isShowingAlert = false
var body: some View
TabView (selection: $selection)
NavigationView
ZStack (alignment: .bottom)
MasterView()
.navigationBarTitle(Text("Chat"))
.navigationBarItems(
leading: EditButton(),
trailing: Button(
action:
//
)
Image(systemName: "plus.circle")
.contentShape(Rectangle())
)
.background(Color.clear)
//IF I comment this line below, the navigation is working well
.alertLinearProgressBar(isShowing: self.$isShowingAlert, progressValue: .constant(0.5), barHeight: 8, loadingText: .constant(""), titleText: .constant(NSLocalizedString("unzipping", comment: "")),isShowingActivityIndicator: .constant(true)).offset(x: 0, y: 1)
struct MasterView: View
var body: some View
ZStack
List
ForEach(chatData, id: \.self) chat in
NavigationLink(
destination:
//Test2()
DetailView(text: chat)
)
ChatRow(text: chat)//, progressValue: self.$progressValue)
struct ChatRow: View
var text: String
var body: some View
Text(text)
struct DetailView: View
var text: String
var body: some View
Text(text)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
struct AlertLinearProgressBar<Presenting>: View where Presenting: View
@Binding var isShowing: Bool
@Binding var progressValue:Float
@State var barHeight: Int
@Binding var loadingText: String
@Binding var titleText: String
@Binding var isShowingProgressBar: Bool
@Binding var isShowingActivityIndicator: Bool
let presenting: () -> Presenting
var body: some View
GeometryReader geometry in
self.presenting()
.blur(radius: self.isShowing ? 2 : 0).offset(y:1)
.disabled(self.isShowing)
ZStack
Rectangle()
.frame(width: geometry.size.width * 0.8,
height: self.titleText == "" ? 70:100)
.foregroundColor(Color.white)
.cornerRadius(15)
.shadow(radius: 20)
.overlay(
GeometryReader geometry in
VStack
if self.titleText != ""
Text(self.titleText)
.bold()
.offset(x: 0, y: 0)
.padding(EdgeInsets(top: 4, leading: 0, bottom: 0, trailing: 0))
HStack
Text("\(self.loadingText) " + "\(self.isShowingProgressBar ? self.progressValue.getPercentage(to: 1):"")")
.font(.caption)
ActivityIndicator(isAnimating: .constant(true), isShowing: self.$isShowingActivityIndicator, style: .medium)
//.font(.system(size: 13))
Spacer()
.frame(height:6)
ZStack(alignment: .leading)
Rectangle()
.frame(width: geometry.size.width, height: CGFloat(self.barHeight))
.opacity(0.3)
.foregroundColor(Color(UIColor.systemTeal))
.cornerRadius(5.0)
Rectangle()
.frame(width: min(CGFloat(self.progressValue)*geometry.size.width, geometry.size.width), height: CGFloat(self.barHeight))
.foregroundColor(Color.blue)
.animation(.linear)
.cornerRadius(5.0)
.opacity(self.isShowingProgressBar ? 1 : 0)
.padding(EdgeInsets(top: 0, leading: 15, bottom: 0, trailing: 15))
)
.padding()
.frame(width: self.isShowing ? geometry.size.width:0,
height: self.isShowing ? geometry.size.height:0)
.transition(.slide)
.opacity(self.isShowing ? 1 : 0)
extension Float
//number of decimal
func round(to places: Int) -> Float
let divisor = pow(10.0, Float(places))
return (self * divisor).rounded() / divisor
func getPercentage(to digits: Int) -> String
if self >= 1
return String(Int(self * 100)) + "%"
return String(format: "%.\(digits)f", self * 100) + "%"
extension View
func alertLinearProgressBar(isShowing: Binding<Bool>,
progressValue: Binding<Float>,
barHeight: Int, loadingText: Binding<String>, titleText: Binding<String>=Binding.constant(""), isShowingProgressBar: Binding<Bool>=Binding.constant(true), isShowingActivityIndicator:Binding<Bool>=Binding.constant(false)) -> some View
AlertLinearProgressBar(isShowing: isShowing, progressValue: progressValue, barHeight: barHeight, loadingText: loadingText, titleText: titleText, isShowingProgressBar: isShowingProgressBar, isShowingActivityIndicator:isShowingActivityIndicator, presenting: self)
struct ActivityIndicator: UIViewRepresentable
@Binding var isAnimating: Bool
@Binding var isShowing: Bool
let style: UIActivityIndicatorView.Style
var color:UIColor?
func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView
return UIActivityIndicatorView(style: style)
func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>)
isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
uiView.isHidden = isShowing ? false:true
if color != nil
uiView.color = color!
【问题讨论】:
【参考方案1】:即使不透明度设置为 0
,您的 AlertLinearProgressBar
看起来也会阻止 NavigationBar。
可以看到覆盖层隐藏时的位置在左上角并与导航栏重叠(尝试设置.opacity(self.isShowing ? 1 : 0.5)
)。
您可以做的是使用hidden
修饰符真正隐藏它。
这是使用if modifier 的可能解决方案:
struct AlertLinearProgressBar<Presenting>: View where Presenting: View
// ...
var body: some View
GeometryReader geometry in
ZStack
// ...
.frame(width: self.isShowing ? geometry.size.width : 0,
height: self.isShowing ? geometry.size.height : 0)
.transition(.slide)
.opacity(self.isShowing ? 1 : 0.5)
.if(!isShowing)
$0.hidden() // use `hidden` here
extension View
@ViewBuilder func `if`<T>(_ condition: Bool, transform: (Self) -> T) -> some View where T: View
if condition
transform(self)
else
self
或者,您可以有条件地显示视图:
struct AlertLinearProgressBar<Presenting>: View where Presenting: View
//...
var body: some View
GeometryReader geometry in
self.presenting()
.blur(radius: self.isShowing ? 2 : 0).offset(y: 1)
.disabled(self.isShowing)
if isShowing
// ...
【讨论】:
你明白了,不透明度为 0.5,警报在视图的左上角可见并且覆盖了按钮。谢谢大佬以上是关于SwiftUI 在 NavigationView 中添加个人警报视图,后退按钮不适用于 Xcode 12 iOS14的主要内容,如果未能解决你的问题,请参考以下文章
在 NavigationView 中清除 SwiftUI 列表未正确返回默认值
SwiftUI:检测 tvOS 上 NavigationView 中的选择更改
在 SwiftUI 中向 NavigationView 添加搜索栏
如何在 SwiftUI 中隐藏 NavigationView Bar