Выбор SwiftUI TabView (.page/PageTabViewStyle) может рассинхронизироваться, когда пользователь прерывает программную смеIOS

Программируем под IOS
Ответить
Anonymous
 Выбор SwiftUI TabView (.page/PageTabViewStyle) может рассинхронизироваться, когда пользователь прерывает программную сме

Сообщение Anonymous »

SwiftUI TabView со стилем .page, по-видимому, позволяет пользователю прерывать переход между страницами в реальном времени, оставляя пользовательский интерфейс в противоречивом состоянии.
Ожидается: видимая страница всегда соответствует связанному выбору.

Замечено: если пользователь касается или перетаскивает пейджер во время программного изменения страницы, обновляется связанный выбор, но видимая страница может оставаться предыдущей. После этого последующие изменения страниц могут «перескакивать» (например, две страницы одновременно), поскольку визуальная страница и выделение расходятся.
Вот GIF, показывающий проблему:
Изображение

В GIF я начинаю с выделения = 5 и отображается страница «Страница 5». Я нажимаю Предыдущий, а затем взаимодействую с пейджером в середине перехода. Видимая страница остается «Страницей 5», но модель обновилась (

Код: Выделить всё

selection = 4). Повторное нажатие [b]Предыдущая[/b] приводит к анимации двух страниц до «Страницы 3», что указывает на то, что внутреннее состояние пейджера теперь не синхронизировано с привязкой.
[b]Этапы воспроизведения:[/b]
[list]
[*]Запустите минимально воспроизводимый пример ниже.
[*]Нажмите [b]Предыдущая[/b] или [b]Далее[/b], чтобы изменить выбор
.
[*]Пока переход страницы еще продолжается, быстро коснитесь или перетащите пейджер.
[*]Обратите внимание, что выбор меняется, но видимая страница иногда не меняется.
[/list]
Минимальный воспроизводимый пример

Код: Выделить всё

struct Page: View {
let index: Int

var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 24)
.fill(Color(white: 0.92))
.padding(24)

Text("Page \(index)")
.font(.system(size: 48, weight: .bold, design: .rounded))
}
}
}

struct PagerDesyncReproView: View {
@State private var selection: Int = 0
private let pageCount = 6

var body: some View {
VStack(spacing: 0) {
HStack(spacing: 12) {
Button("Prev") {
guard selection > 0 else { return }
selection -= 1
}
.buttonStyle(.bordered)

Button("Next") {
guard selection < pageCount - 1 else { return }
selection += 1
}
.buttonStyle(.borderedProminent)

Spacer()

Text("selection = \(selection)")
.font(.system(.caption, design: .monospaced))
.foregroundStyle(.secondary)
}
.padding(.horizontal)

TabView(selection: $selection) {
ForEach(0..
                    Page(index: i)
.tag(i)
}
}
.animation(.default, value: selection)
.transition(.slide)
.tabViewStyle(.page(indexDisplayMode: .always))
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
Существует ли поддерживаемый способ предотвратить эту десинхронизацию (например, отключить взаимодействие до завершения перехода страницы) или обнаружить отмену/завершение перехода страницы, чтобы привязку можно было поддерживать согласованной?


Подробнее здесь: https://stackoverflow.com/questions/798 ... nc-when-us
Ответить

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

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

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

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

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