Я смущенно провел последние 2 недели, пытаясь решить эту проблему.
Я пытаюсь сделать следующее:
- Привязать мой слайд-вид к нижней части экрана
- Отключить перетаскивание вверхи только разрешить перетаскивать карту вниз, чтобы закрыть
Что я пробовал:
Я пытался связываться с размером карты с помощьюустановка его высоты на высоту экрана. Вы можете видеть эту строку закомментированной. После этого я перебрал смещение карты и установил ее так, чтобы она выглядела так, как будто карта на самом деле меньше половины своего размера, около 300 в высоту. Проблема в том, что когда я медленно скользлю вверх, я вижу пустое пространство, которое скрыто за экраном. Это не тот эффект, которого я хочу.
Следующее, что я попытался сделать, это изменить высоту карты до желаемой высоты. Затем отрегулируйте смещение таким образом, чтобы карта находилась там, где я хочу. Однако, я чувствую, что ручная настройка не будет надежной на разных экранах. Поэтому я пытаюсь найти правильную математику, необходимую для того, чтобы она всегда находилась в самом низу экрана, когда она всплывает.
Наконец, я хочу просто сделать так, чтобы пользователи могли только перетаскиватьи не вверх.
Буду очень признателен за помощь здесь. Я потратил много времени на сообщения и чтение, изучая новые вещи, но я не могу решить свою конкретную проблему.
Вот моя карточка-слайдер
import SwiftUI
struct SigninView<Content: View> : View {
@GestureState private var dragState = DragState.inactive
@State var position = CardPosition.top
var content: () -> Content
var body: some View {
let drag = DragGesture()
.updating($dragState) { drag, state, transaction in
state = .dragging(translation: drag.translation)
}
.onEnded(onDragEnded)
return Group {
// Handle()
self.content()
}
.frame(height: 333) //UIScreen.main.bounds.height)
.background(Color.purple)
.cornerRadius(10.0)
.shadow(color: Color(.sRGBLinear, white: 0, opacity: 0.13), radius: 10.0)
.offset(y: self.position.rawValue + self.dragState.translation.height)
.animation(self.dragState.isDragging ? nil : .interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
.gesture(drag)
}
private func onDragEnded(drag: DragGesture.Value) {
let verticalDirection = drag.predictedEndLocation.y - drag.location.y
let cardTopEdgeLocation = self.position.rawValue + drag.translation.height
let positionAbove: CardPosition
let positionBelow: CardPosition
let closestPosition: CardPosition
if cardTopEdgeLocation <= CardPosition.middle.rawValue {
positionAbove = .top
positionBelow = .middle
} else {
positionAbove = .middle
positionBelow = .bottom
}
if (cardTopEdgeLocation - positionAbove.rawValue) < (positionBelow.rawValue - cardTopEdgeLocation) {
closestPosition = positionAbove
} else {
closestPosition = positionBelow
}
if verticalDirection > 0 {
self.position = positionBelow
} else if verticalDirection < 0 {
self.position = positionAbove
} else {
self.position = closestPosition
}
}
}
enum CardPosition: CGFloat {
case top = 100
case middle = 790
case bottom = 850
}
enum DragState {
case inactive
case dragging(translation: CGSize)
var translation: CGSize {
switch self {
case .inactive:
return .zero
case .dragging(let translation):
return translation
}
}
var isDragging: Bool {
switch self {
case .inactive:
return false
case .dragging:
return true
}
}
}
Вотмоя страница ContentView, где я ее тестирую:
import SwiftUI
struct ContentView: View {
@State var show:Bool = false
var body: some View {
SigninView {
VStack {
Text("TESTING")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.blue)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}