如何解决SwiftUI-工作表中有一个不可滚动的固定继续按钮
如您所见,即使我试图将纸张拉下,继续按钮也不会向下移动。如何使我的工作表具有这种行为?在我的应用中,“继续”按钮移出屏幕。这是当床单被轻微拉下时我的应用程序的外观:
我还在下面附加了我的代码,它在横向和纵向上看起来都很美观。有没有办法在不破坏iPhone 7等较小设备的横向外观的情况下实现这一目标?
import SwiftUI
struct IntroView: View {
@State private var animationAmount: CGFloat = 1
@Environment(\.presentationMode) var presentationMode
@Environment(\.verticalSizeClass) var sizeClass
var body: some View {
VStack {
VStack {
Spacer()
if sizeClass == .compact {
HStack {
Text("Welcome to Demo").fontWeight(.heavy)
Text("App").foregroundColor(.orange).fontWeight(.heavy)
}
.padding(.bottom,10)
}
else {
Text("Welcome to").fontWeight(.heavy)
HStack {
Text("Demo").fontWeight(.heavy)
Text("App").foregroundColor(.orange).fontWeight(.heavy)
}
.padding(.bottom,30)
}
}//Intro VStack close
.font(.largeTitle)
.frame(maxWidth: .infinity,maxHeight: 180)
VStack (spacing: 30) {
HStack (spacing: 20) {
Image(systemName: "sparkle")
.foregroundColor(.yellow)
.font(.title2)
.scaleEffect(animationAmount)
.onAppear {
let baseAnimation = Animation.easeInOut(duration: 1)
let repeated = baseAnimation.repeatForever(autoreverses: true)
return withAnimation(repeated) {
self.animationAmount = 1.5
}
}
VStack (alignment: .leading) {
Text("All new design").fontWeight(.semibold)
Text("Easily view all your essentials here.")
.foregroundColor(.gray)
}
Spacer()
}//HStack 1
.padding([.leading,.trailing],10)
HStack (spacing: 20) {
Image(systemName: "pin")
.foregroundColor(.red)
.font(.title2)
.padding(.trailing,5)
.scaleEffect(animationAmount)
.onAppear {
let baseAnimation = Animation.easeInOut(duration: 1)
let repeated = baseAnimation.repeatForever(autoreverses: true)
return withAnimation(repeated) {
self.animationAmount = 1.5
}
}
VStack (alignment: .leading) {
Text("Pin favourites").fontWeight(.semibold)
Text("You can pin your favourite content on all devices")
.foregroundColor(.gray)
}
Spacer()
}//HStack 2
.padding([.leading,10)
.frame(maxWidth: .infinity,maxHeight: 100)
HStack (spacing: 20) {
Image(systemName: "moon.stars.fill")
.foregroundColor(.blue)
.font(.title2)
.scaleEffect(animationAmount)
.onAppear {
let baseAnimation = Animation.easeInOut(duration: 1)
let repeated = baseAnimation.repeatForever(autoreverses: true)
return withAnimation(repeated) {
self.animationAmount = 1.5
}
}
VStack (alignment: .leading) {
Text("Flexible").fontWeight(.semibold)
Text("Supports dark mode")
.foregroundColor(.gray)
}
Spacer()
}//HStack 3
.padding([.leading,10)
}//VStack for 3 criterias
.padding([.leading,20)
Spacer()
Button {
presentationMode.wrappedValue.dismiss()
UserDefaults.standard.set(true,forKey: "LaunchedBefore")
} label: {
Text("Continue")
.fontWeight(.medium)
.padding([.top,.bottom],15)
.padding([.leading,90)
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(15)
}
.frame(maxWidth: .infinity,maxHeight: 100)
}//Main VStack
}
}
struct IntroView_Previews: PreviewProvider {
static var previews: some View {
IntroView()
}
}
解决方法
这里是可能方法的演示(调整和效果超出范围-尝试使演示代码简短)。这个想法是用{em>上方按钮注入UIView
保持器,以使其在向下拖动过程中持续存在(因为发现显示任何动态偏移都会产生难看的不希望有的抖动效果)。
通过Xcode 12 / iOS 14测试
// ... your above code here
}//VStack for 3 criterias
.padding([.leading,.trailing],20)
Spacer()
// button moved from here into below background view !!
}.background(BottomView(presentation: presentationMode) {
Button {
presentationMode.wrappedValue.dismiss()
UserDefaults.standard.set(true,forKey: "LaunchedBefore")
} label: {
Text("Continue")
.fontWeight(.medium)
.padding([.top,.bottom],15)
.padding([.leading,90)
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(15)
}
})
//Main VStack
}
}
struct BottomView<Content: View>: UIViewRepresentable {
@Binding var presentationMode: PresentationMode
private var content: () -> Content
init(presentation: Binding<PresentationMode>,@ViewBuilder _ content: @escaping () -> Content) {
_presentationMode = presentation
self.content = content
}
func makeUIView(context: Context) -> UIView {
let view = UIView()
DispatchQueue.main.async {
if let window = view.window {
let holder = UIView()
context.coordinator.holder = holder
// simple demo background to make it visible
holder.layer.backgroundColor = UIColor.gray.withAlphaComponent(0.5).cgColor
holder.translatesAutoresizingMaskIntoConstraints = false
window.addSubview(holder)
holder.heightAnchor.constraint(equalToConstant: 140).isActive = true
holder.bottomAnchor.constraint(equalTo: window.bottomAnchor,constant: 0).isActive = true
holder.leadingAnchor.constraint(equalTo: window.leadingAnchor,constant: 0).isActive = true
holder.trailingAnchor.constraint(equalTo: window.trailingAnchor,constant: 0).isActive = true
if let contentView = UIHostingController(rootView: content()).view {
contentView.backgroundColor = UIColor.clear
contentView.translatesAutoresizingMaskIntoConstraints = false
holder.addSubview(contentView)
contentView.topAnchor.constraint(equalTo: holder.topAnchor,constant: 0).isActive = true
contentView.bottomAnchor.constraint(equalTo: holder.bottomAnchor,constant: 0).isActive = true
contentView.leadingAnchor.constraint(equalTo: holder.leadingAnchor,constant: 0).isActive = true
contentView.trailingAnchor.constraint(equalTo: holder.trailingAnchor,constant: 0).isActive = true
}
}
}
return view
}
func updateUIView(_ uiView: UIView,context: Context) {
if !presentationMode.isPresented {
context.coordinator.holder.removeFromSuperview()
}
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
class Coordinator {
var holder: UIView!
deinit {
holder.removeFromSuperview()
}
}
}
,
只需添加:
.sheet(isPresented: self.$visibleSheet) {
IntroView(visibleSheet: self.$visibleSheet)
.presentation(shouldDismissOnDrag: false)
}
https://stackoverflow.com/a/61239704/7974174:
extension View {
func presentation(shouldDismissOnDrag: Bool,onDismissalAttempt: (()->())? = nil) -> some View {
ModalView(view: self,shouldDismiss: shouldDismissOnDrag,onDismissalAttempt: onDismissalAttempt)
}
}
struct ModalView<T: View>: UIViewControllerRepresentable {
let view: T
let shouldDismiss: Bool
let onDismissalAttempt: (()->())?
func makeUIViewController(context: Context) -> UIHostingController<T> {
UIHostingController(rootView: view)
}
func updateUIViewController(_ uiViewController: UIHostingController<T>,context: Context) {
uiViewController.parent?.presentationController?.delegate = context.coordinator
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject,UIAdaptivePresentationControllerDelegate {
let modalView: ModalView
init(_ modalView: ModalView) {
self.modalView = modalView
}
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
modalView.shouldDismiss
}
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
modalView.onDismissalAttempt?()
}
}
}
它通过向下拖动工作表来禁用工作表关闭。如果您想使用按钮关闭工作表,请勿再使用presentationMode
。传递self.$visibleSheet
的绑定,然后从内部修改为false ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。