SwiftUI IOS 26 — значок метки меню панели инструментов периодически исчезает примерно на 1 секунду, когда выбор в средстIOS

Программируем под IOS
Ответить
Anonymous
 SwiftUI IOS 26 — значок метки меню панели инструментов периодически исчезает примерно на 1 секунду, когда выбор в средст

Сообщение Anonymous »

У меня есть меню на панели инструментов, метка которого меняет .symbolVariant и .foregroundStyle на основе встроенного выбора. При переходе из состояния по умолчанию (нет варианта, основной цвет) в активное состояние (.fill, синий), значок иногда исчезает примерно на секунду, прежде чем снова появиться с правильным стилем.
Это происходит только в этом направлении, при возврате к состоянию по умолчанию никогда не мерцает. It's intermittent but easy to reproduce by toggling a few times.
I've tried .contentTransition(.identity), .symbolEffectsRemoved(), deferring the state update via Task, and restructuring the toolbar, none of it helped.
Minimal target is IOS 18 and it only happens on IOS 26+.
Буду признателен за разъяснения.

Gif-репродукция
Минимальная репродукция ниже:


import SwiftUI

// MARK: - Filter Enum

enum ItemFilter: String, CaseIterable, Identifiable {
case all
case onlySystem
case onlyCustom

var id: Self { self }

var title: String {
switch self {
case .all: "All"
case .onlySystem: "Only system"
case .onlyCustom: "Only custom"
}
}

var icon: String {
switch self {
case .all: "square.grid.2x2.fill"
case .onlySystem: "gearshape.fill"
case .onlyCustom: "person.fill"
}
}
}

// MARK: - Sample Data

struct SampleItem: Identifiable, Equatable {
let id: String
let name: String
let isSystem: Bool
}

let systemItems: [SampleItem] = [
SampleItem(id: "s1", name: "Food & Groceries", isSystem: true),
SampleItem(id: "s2", name: "Transportation", isSystem: true),
SampleItem(id: "s3", name: "Entertainment", isSystem: true),
SampleItem(id: "s4", name: "Healthcare", isSystem: true),
SampleItem(id: "s5", name: "Utilities", isSystem: true),
SampleItem(id: "s6", name: "Education", isSystem: true),
]

let customItems: [SampleItem] = [
SampleItem(id: "c1", name: "Coffee", isSystem: false),
SampleItem(id: "c2", name: "Gym Membership", isSystem: false),
SampleItem(id: "c3", name: "Streaming Services", isSystem: false),
SampleItem(id: "c4", name: "Pet Supplies", isSystem: false),
]

// MARK: - ContentView

struct ContentView: View {
@State private var showSheet = false

var body: some View {
VStack(spacing: 20) {
Text("Toolbar Flicker Test")
.font(.title2.bold())

Button("Open Selection Sheet") {
showSheet = true
}
.buttonStyle(.borderedProminent)
}
.sheet(isPresented: $showSheet) {
SelectionSheet()
}
}
}

// MARK: - SelectionSheet

struct SelectionSheet: View {
@Environment(\.dismiss) private var dismiss

@State private var query = ""
@State private var selectedFilter: ItemFilter = .all
@State private var selection: SampleItem?

private let menuIcon = "line.3.horizontal.decrease.circle"

private var filteredSystemItems: [SampleItem] {
let base: [SampleItem]
switch selectedFilter {
case .all, .onlySystem: base = systemItems
case .onlyCustom: base = []
}
if query.isEmpty { return base }
return base.filter { $0.name.localizedStandardContains(query) }
}

private var filteredCustomItems: [SampleItem] {
let base: [SampleItem]
switch selectedFilter {
case .all, .onlyCustom: base = customItems
case .onlySystem: base = []
}
if query.isEmpty { return base }
return base.filter { $0.name.localizedStandardContains(query) }
}

var body: some View {
NavigationStack {
List {
if !filteredSystemItems.isEmpty {
Section("System") {
ForEach(filteredSystemItems) { item in
itemRow(item)
}
}
}

if !filteredCustomItems.isEmpty {
Section("Custom") {
ForEach(filteredCustomItems) { item in
itemRow(item)
}
}
}

if filteredSystemItems.isEmpty && filteredCustomItems.isEmpty {
ContentUnavailableView.search(text: query)
}
}
.navigationTitle("Categories")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
let filterBinding = Binding(
get: { selectedFilter },
set: { updatedFilter in
selectedFilter = updatedFilter
}
)

Menu {
Section {
Picker("Filter Items", selection: filterBinding) {
ForEach(ItemFilter.allCases) { filter in
Label(filter.title, systemImage: filter.icon)
.tag(filter)
}
}
.pickerStyle(.inline)
}
} label: {
Image(systemName: menuIcon)
.symbolVariant(selectedFilter == .all ? .none : .fill)
.foregroundStyle(selectedFilter == .all ? .primary : Color.blue)
}
}

ToolbarItem(placement: .topBarLeading) {
Button("Done") { dismiss() }
}
}
.searchable(
text: $query,
placement: .navigationBarDrawer(displayMode: .always),
prompt: "Search categories"
)
}
}

private func itemRow(_ item: SampleItem) -> some View {
Button {
selection = item
dismiss()
} label: {
HStack {
Circle()
.fill(item.isSystem ? Color.orange.opacity(0.15) : Color.blue.opacity(0.15))
.frame(width: 36, height: 36)
.overlay {
Image(systemName: item.isSystem ? "gearshape.fill" : "person.fill")
.font(.system(size: 14, weight: .semibold))
.foregroundStyle(item.isSystem ? .orange : .blue)
}

Text(item.name)
.foregroundStyle(.primary)

Spacer()

if selection?.id == item.id {
Image(systemName: "checkmark")
.foregroundStyle(.tint)
}
}
}
}
}

#Preview {
ContentView()
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... r-1-second
Ответить

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

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

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

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

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