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

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

Сообщение Anonymous »

У меня есть меню на панели инструментов, метка которого меняет .symbolVariant и .foregroundStyle на основе встроенного выбора. При переходе из состояния по умолчанию (нет варианта, основной цвет) в активное состояние (.fill, синий), значок иногда исчезает примерно на секунду, прежде чем снова появиться с правильным стилем.
Это происходит только в этом направлении, при возврате к состоянию по умолчанию никогда не мерцает. Это происходит с перерывами, но его легко воспроизвести, переключив несколько раз.
Я пробовал .contentTransition(.identity), .symbolEffectsRemoved(), откладывал обновление состояния с помощью Task и реструктуризировал панель инструментов, ничего из этого не помогло.
Минимальная цель — iOS 18, и это происходит только на 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»