如何解决如何在SwiftUI顶部显示来电视图?
我试图模拟如何在所有顶部显示呼叫视图。但是我有一些不清楚的地方:
AppView.swift
import SwiftUI
struct AppView: View {
@Observedobject var callVM: Callviewmodel
init() {
self.callVM = Callviewmodel()
}
var body: some View {
vstack {
IncomingCallView(rootView: appView,isActive: self.$callVM.isIncomingCallActive)
TabView {
TabOne()
.tabItem {
Image(systemName: "list.dash")
Text("Menu")
}
TabTwo()
.tabItem {
Image(systemName: "square.and.pencil")
Text("Order")
}
}
}
.onAppear(perform: load)
}
var appView: some View {
Text("")
}
func load() {
self.callVM.getCall()
}
}
struct AppView_Previews: PreviewProvider {
static var previews: some View {
AppView()
}
}
Callviewmodel.swift
import Foundation
class Callviewmodel: ObservableObject {
@Published public var isIncomingCallActive = Bool()
init() {
self.isIncomingCallActive = false
}
func getCall() {
dispatchQueue.main.asyncAfter(deadline: .Now() + 5) {
self.isIncomingCallActive = true
}
}
}
IncomingCallView.swift
import SwiftUI
struct IncomingCallView<RootView: View>: View {
private let rootView: RootView
@Binding var isActive: Bool
init(rootView: RootView,isActive: Binding<Bool>) {
self.rootView = rootView
self._isActive = isActive
}
var body: some View {
rootView
.background(Activator(isActive: $isActive))
}
struct Activator: UIViewRepresentable {
@Binding var isActive: Bool
@State private var myWindow: UIWindow? = nil
func makeUIView(context: Context) -> UIView {
let view = UIView()
dispatchQueue.main.async {
self.myWindow = view.window
}
return view
}
func updateUIView(_ uiView: UIView,context: Context) {
guard let holder = myWindow?.rootViewController?.view else { return }
if isActive && context.coordinator.controller == nil {
context.coordinator.controller = UIHostingController(rootView: loadingView)
let view = context.coordinator.controller!.view
view?.backgroundColor = UIColor.black.withAlphaComponent(1)
view?.isUserInteractionEnabled = true
view?.translatesAutoresizingMaskIntoConstraints = false
holder.addSubview(view!)
holder.isUserInteractionEnabled = true
view?.leadingAnchor.constraint(equalTo: holder.leadingAnchor).isActive = true
view?.trailingAnchor.constraint(equalTo: holder.trailingAnchor).isActive = true
view?.topAnchor.constraint(equalTo: holder.topAnchor).isActive = true
view?.bottomAnchor.constraint(equalTo: holder.bottomAnchor).isActive = true
} else if !isActive {
context.coordinator.controller?.view.removeFromSuperview()
context.coordinator.controller = nil
holder.isUserInteractionEnabled = true
}
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
class Coordinator {
var controller: UIViewController? = nil
}
private var loadingView: some View {
HStack(spacing: 20) {
Button(action: {
print("acceptCall pressed")
// change UI for accepted call
}) {
Image("acceptCall")
.resizable()
.frame(width: 50,height: 50,alignment: .center)
.aspectRatio(contentMode: .fit)
}
Button(action: {
// close the view
print("rejectCall pressed")
self.isActive = false
}) {
Image("rejectCall")
.resizable()
.frame(width: 50,alignment: .center)
.aspectRatio(contentMode: .fit)
}
}
.frame(width: 300,height: 300)
.background(Color.primary.opacity(0.7))
.cornerRadius(10)
}
}
}
解决方法
swiftUI中的内容看起来像这样
struct AppView: View {
@StateObject var callVM = CallViewModel()
var body: some View {
ZStack {
TabView {
Text("TabOne")
.tabItem {
Image(systemName: "list.dash")
Text("Menu")
}
Text("TabTwo")
.tabItem {
Image(systemName: "square.and.pencil")
Text("Order")
}
}
if callVM.isIncomingCallActive {
ZStack {
Color.green
VStack {
Text("Incoming call...")
Button(action: { callVM.isIncomingCallActive = false }) {
Text("Cancel")
}
}
}.edgesIgnoringSafeArea(.all) // <= here
}
}
.onAppear {
self.callVM.getCall()
}
}
}
class CallViewModel: ObservableObject {
@Published public var isIncomingCallActive = false
func getCall() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.isIncomingCallActive = true
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。