Движение во всех направлениях при использовании Scrollview (.horizontal)IOS

Программируем под IOS
Ответить
Anonymous
 Движение во всех направлениях при использовании Scrollview (.horizontal)

Сообщение Anonymous »

Я реализую горизонтальный Scrollview в Swiftui, чтобы пользователи прокручивали список дней (dayPickerView). В холсте Xcode все работает так же, как и ожидалось, а прокрутка строго горизонтальна. Однако при запуске приложения на реальном устройстве прокручиваемая область может быть слегка перемещена во всех направлениях (вверх, вниз и даже по диагонали). < /P>
Это неожиданное поведение иногда даже запускает жест, показывающий проблему. Пробое:

[*] оберток Scrollview в GeometryReader для обнаружения смещений.

Добавить. .contentshape (rectangle ()) для ограничения взаимодействий.var body: some View {
ZStack {
Color("Background")
.ignoresSafeArea()

VStack(spacing: 0) {
customHeader

// Content in white card with rounded corners
ZStack {
RoundedRectangle(cornerRadius: 40)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 0)

ScrollView {
VStack(spacing: 20) {
viewModePicker

if viewModel.isLoading {
loadingView
} else if isDataEmpty {
emptyStateView
} else {
statisticsView

chartView

if hasDataToShow {
recordsListView
}
}

// Add bottom padding for better scrolling experience
Spacer()
.frame(height: 20)
}
.padding(.bottom)
}
.padding(.horizontal, 2) // Small horizontal padding for scroll view
}
.padding(.horizontal, 0)
.padding(.top, 10)
.padding(.bottom, 5)
.edgesIgnoringSafeArea(.bottom)
}
}
.navigationBarHidden(true)
.sheet(isPresented: $showingAddRecord) {
NavigationView {
AddSleepRecordView(childId: childId)
}
}
.onChange(of: showingAddRecord) { oldValue, newValue in
if !newValue { // Если форма была закрыта
refreshData()
}
}
.alert("Помилка", isPresented: $showingAlert) {
Button("OK", role: .cancel) {
viewModel.errorMessage = nil
}
} message: {
if let error = viewModel.errorMessage {
Text(error)
}
}
.onChange(of: viewModel.errorMessage) { _, newValue in
showingAlert = newValue != nil
}
.onAppear {
let currentTime = Date().timeIntervalSince1970
let shouldRefresh = currentTime - lastUpdateTime > 300 // 5 минут

if shouldRefresh {
refreshData()
} else {
Task { @MainActor in
await viewModel.fetchData(forceRefresh: false)
}
}

// Подписываемся на уведомление о добавлении/обновлении/удалении записи
NotificationCenter.default.addObserver(
forName: .newSleepRecordAdded,
object: nil,
queue: .main
) { _ in
self.refreshData()
}
}
.onDisappear {
// Отписываемся при исчезновении представления
NotificationCenter.default.removeObserver(self, name: .newSleepRecordAdded, object: nil)
}
.refreshable {
// Сбрасываем кэш для режима, который сейчас не отображается
if viewModel.viewMode == .daily {
viewModel.weeklyData = [] // Сбрасываем недельные данные
} else {
viewModel.dailyData = [] // Сбрасываем дневные данные
}

await viewModel.fetchData(forceRefresh: true)
await MainActor.run {
lastUpdateTime = Date().timeIntervalSince1970
}
}
}

// Custom header component
private var customHeader: some View {
VStack(spacing: 0) {
HStack(spacing: 16) {
// Back button
IconButtonCircle(systemName: "chevron.left", style: .primary, size: .medium, buttonSize: 40) {
presentationMode.wrappedValue.dismiss()
}

Spacer()

// Add record button
TextIconButtonLeft("Додати запис", systemName: "plus.circle.fill", style: .primary, size: .small) {
showingAddRecord = true
}
.frame(maxWidth: 200)
}
.padding(.horizontal)
.padding(.vertical, 12)

// Only show day selector in daily mode
if viewModel.viewMode == .daily {
dayPickerView
.padding(.top, 20)
.padding(.bottom, 20)
}
}
.background(Color("Background"))
}

// Day picker component with horizontal scrolling
private var dayPickerView: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
// Show today's day first, followed by the 6 previous days
// Form an array with negative offsets (0 - today, -1 - yesterday, etc.)
ForEach(0..

Подробнее здесь: https://stackoverflow.com/questions/794 ... horizontal
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»