SwiftUI通过触碰边界来隐藏视图



我试图实现弹出警报,这基本上是视图,出现在另一个视图,我怎么能驳回这个警报视图在顶部,当我点击白框外?屏幕

我调用这个警报的逻辑:我有我的主视图,在那里我有facebook的signIn按钮,它应该调用这个警报视图,我的警报视图只是另一个swiftui视图,它有UIViewRepresentable对象里面让超链接在我的文本。主要观点:

//
//  WelcomeView.swift
//  
//
//  
//
import SwiftUI
import FacebookLogin
import SDWebImageSwiftUI
import NavigationStack
import AVKit
struct WelcomeView: View {
@State var showTermsAndConditionsAlert: Bool = false
ZStack { // 1 outer
ZStack { // 2 inner
VStack() {
ZStack(alignment: .top) {
// my video player here
HStack {
// some other ui elements
}
VStack {
// logo
}
}
}                         
HStack(alignment: .bottom) {
VStack {
Button(action: {
appLog.debug("Continue with Facebook")
showTermsAndConditionsAlert = true
}) {
AuthButtonView(imageIdentifier: "ic_facebook", buttonTitle: "welcome_page_sign_up_btn_fb".localized)
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(5)
}
// email button sign up
}

// email button sign in
}) {
}

// push views
}
.ignoresSafeArea()
}

}
.padding(.bottom, Theme.pageBottomPadding)

if showTermsAndConditionsAlert {
TermsConditionsAlertView() {
self.showTermsAndConditionsAlert = false
self.viewModel.facebookLogin()
}
}
}
.onTapGesture(perform: {
// TODO: close dialog only when it is opened and press outside of dialog bound
self.showTermsAndConditionsAlert = false
})
}
.navigationBarTitle("", displayMode: .automatic)
.onAppear {
self.player.isMuted = true
self.player.play()
}
.onDisappear {
self.player.pause()
}
.onReceive(viewModel.$state.dropFirst(), perform: { state in
// switch state 
}
})
}
}

ALERT VIEW: HyperLinkTextView - uirepresatable uiview

//
//  TermsConditionsAlertView.swift
//  
//
//  
//
import SwiftUI
import NavigationStack
struct TermsConditionsAlertView: View {

var callback: (() -> ())?

var body: some View {
ZStack {
Color.black.opacity(0.8).edgesIgnoringSafeArea(.all)

VStack(alignment: .leading, spacing: 0) {
// Text here

HyperLinkTextView(text: "terms_conditions_alert_view_description".localized,
links: [Hyperlink(word: "terms_conditions".localized, url: NSURL(string: Constants.termsURL)!),
Hyperlink(word: "privacy_policy".localized, url: NSURL(string: Constants.privacyPolicyURL)!)])


Button(action: {
appLog.debug("Agree and sign up pressed")
callback?()
}) {
// button struct
}
}
}
}
}

HYPERLINK UI VIEW:

//
//  HyperLinkTextView.swift
//  
//
//  
//
import SwiftUI
struct Hyperlink {
var word: String
var url: NSURL
}
struct HyperLinkTextView: UIViewRepresentable {

private var text: String
private var links: [Hyperlink]

init(text: String, links: [Hyperlink]) {
self.text = text
self.links = links
}

func makeUIView(context: Self.Context) -> UITextView {
let attributedString = NSMutableAttributedString(string: text)
links.forEach { hyperlink in
let linkAttributes = [NSAttributedString.Key.link: hyperlink.url]

var nsRange = NSMakeRange(0, 0)
if let range = text.range(of: hyperlink.word) {
nsRange = NSRange(range, in: text)
}

attributedString.setAttributes(linkAttributes, range: nsRange)
attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSNumber(value: 1), range: nsRange)
}
let textView = UITextView()
textView.isEditable = false
textView.delegate = context.coordinator
textView.attributedText = attributedString
textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue]
textView.isUserInteractionEnabled = true

return textView
}

func updateUIView(_ uiView: UITextView, context: Context) {
uiView.font = UIFont(name: "ArialMT", size: 18)
}

func makeCoordinator() -> Coordinator {
Coordinator()
}

public class Coordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate {

weak var textView: UITextView?

public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction, replacementText text: String) -> Bool {
return true
}
}
}

创建一个包含半透明视图的ZStack全屏视图,并将警报放在其顶部。向半透明视图添加一个轻击手势,以取消整个视图。

最新更新