Hello,
I seem to be unable to change TabView's background color (not the bar, but the background of the entire TabView), no matter what I try.
What I am looking for:
To make the TabView's background clear.
My code:
TabView(selection: $activeScreen) {
Screen1()
.tabItem {
Label("Menu", systemImage: "list.dash")
}
}
Screen1 is defined as:
struct Screen1: View {
var body: some View {
VStack {
Text("Hello")
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
What I have tried, based on suggestions online:
Changing UITabBarAppearance in init(), and .onAppear()
TabView().background(.clear)
In all cases, the TabView's background remains either white or black, depending on the device's theme. I can change the background behind it by placing it in a ZStack, but that is not what I am looking for, I want the background itself to be clear.
The only way that TabView will honor .background(.clear) is if I add the following:
.tabViewStyle(.page)
.indexViewStyle(.page(backgroundDisplayMode: .always))
But this changes the style of the TabView, which is not the desired behavior.
Any help would be greatly appreciated, thank you!
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Posts under SwiftUI tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I am working on a sticker app and I am building a custom sticker app in SwiftUI. I have created a custom UIViewRepresentable to allow a MSStickerView to be displayed in SwiftUI. I have local *.gif files in my project and I am loading them into the MSStickerView successfully, however when they are loaded in my iMessage sticker extension the stickers are not animating by default. When I tap on the MSStickerView the gif begins to animate, I'm not sure what else I can do to get this working properly in my app. Some sample code below:
public struct CustomStickerView: UIViewRepresentable {
var sticker: CustomSticker
public init(sticker: CustomSticker) {
self.sticker = sticker
}
public func makeUIView(context: Context) -> MSStickerView {
let v = MSStickerView()
if sticker.fileType == .gif {
v.startAnimating()
}
return v
}
public func updateUIView(_ uiView: MSStickerView, context: Context) {
uiView.sticker = sticker.sticker
}
}
// CustomSticker
public var sticker: MSSticker? {
guard let imagePath = Bundle.main.path(forResource: name, ofType: ".\(fileType.rawValue)") else {
print("Failed to get sticker - \(name).\(fileType.rawValue)")
return nil
}
let path = URL(fileURLWithPath: imagePath)
return try? MSSticker(contentsOfFileURL: path, localizedDescription: name)
}
How do I scroll to a row and select it when it is part of collapsed rows in Table
ScrollViewReader { scrollViewProxy in
Table([node], children: \.children, selection: $selectedNodeID) {
TableColumn("Key") { Text($0.key) }
TableColumn("Value") { Text($0.val) }
}
.onChange(of: selectedNodeID) { _, newValue in
withAnimation {
scrollViewProxy.scrollTo(newValue)
}
}
}
The code above works well for the rows that are expanded or at the root level. However, for the rows that are not yet expanded the code above does nothing. How can I update the code so that it scrolls to a row that has not materialized yet.
Info:
This is a macOS app
I am on macOS 15.1.1 with Xcode 16.1 and the minimum target of the app is macOS 15
// Füge OrderRow hinzu
struct OrderRow: View {
let order: Order
var body: some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("Tisch \(order.tableNumber)")
.font(.headline)
Spacer()
Text(order.status.rawValue)
.font(.caption)
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(order.status.color.opacity(0.2))
.foregroundColor(order.status.color)
.cornerRadius(8)
}
Text(order.timestamp, style: .time)
.font(.caption)
.foregroundColor(.gray)
ForEach(order.items) { item in
Text("\(item.quantity)x \(item.item.name)")
.font(.subheadline)
}
HStack {
Spacer()
Text(String(format: "%.2f €", order.totalAmount))
.bold()
}
}
.padding()
.background(Color.white)
.cornerRadius(12)
.shadow(radius: 2)
}
}
struct MenuItemRow: View {
let item: MenuItem
var body: some View {
HStack {
Text(item.name)
.font(.headline)
Spacer()
Text(String(format: "%.2f €", item.price))
.font(.subheadline)
}
.padding()
}
}
struct MenuItemsView: View {
@Binding var selectedItems: [OrderItem]
@Environment(.dismiss) private var dismiss
func filteredItems(for category: MenuCategory) -> [MenuItem] {
return sampleMenuItems.filter { $0.category == category }
}
func addItemToOrder(_ item: MenuItem) {
if let index = selectedItems.firstIndex(where: { $0.item.id == item.id }) {
selectedItems[index].quantity += 1
} else {
selectedItems.append(OrderItem(item: item, quantity: 1))
}
}
var body: some View {
NavigationView {
List {
ForEach(MenuCategory) { category in
Section(header: Text(category.rawValue)) {
let filteredItems = sampleMenuItems.filter
ForEach(filteredItems) { item in
}
MenuItemRow(item: sampleMenuItems.filter) {
addItemToOrder
}
}
}
}
}
.navigationTitle("Menü")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Fertig") {
dismiss()
}
}
}
}
}
}
// Sample Menü-Items
let sampleMenuItems: [MenuItem] = [
MenuItem(name: "Cola", description: "0,33l", price: 3.50, category: .drinks, image: "cola"),
MenuItem(name: "Sprite", description: "0,33l", price: 3.50, category: .drinks, image: "sprite"),
MenuItem(name: "Bier", description: "0,5l", price: 4.00, category: .drinks, image: "beer"),
MenuItem(name: "Nachos", description: "mit Käsesauce", price: 5.50, category: .snacks, image: "nachos"),
MenuItem(name: "Pommes", description: "mit Ketchup", price: 4.50, category: .food, image: "fries"),
MenuItem(name: "********", description: "alkoholfrei", price: 6.50, category: .specials, image: "********")
]
struct NewEventView: View {
var body: some View {
Text("New Event")
}
}
struct EventManagementView: View {
var body: some View {
Text("Event Management")
}
}
struct OrderRow: View {
var order: String
var body: some View {
Text("Order: (order)")
}
}
#Preview {
ContentView()
}
First post here!
Is there a way to reduce the number of haptic feedback for double tap on primary button?
Context: Double tap is awesome. Two haptic actuations are given to the gesture to let the user know that the gesture is "received" then a third haptic feedback is given shortly after to signal the primary button is tapped. Is there a way to disable the third haptic feedback. In other words make primary action "silent"?
I have tested a number of apps that supports double tap, it seems to me that the triple tap is a system level default, and it cannot be changed.
Any help would be greatly appreciated.
I have the following lines of code where I show a bunch of checkboxes, each of which can toggle between on and off with a tap.
import SwiftUI
struct ContentView: View {
@State private var viewModel = ContentViewModel()
var body: some View {
VStack(alignment: .leading) {
List {
ForEach(viewModel.models, id: \.id) { model in
CheckButtonView(id: model.id, text: model.name, isOn: model.isOn) { id, bool in
updateDate(id: id, bool: bool)
}
}
}
}
}
func updateDate(id: String, bool: Bool) {
for i in 0..<viewModel.models.count {
let oldModel = viewModel.models[i]
if oldModel.id == id {
let newModel = Content(id: oldModel.id, name: oldModel.name, isOn: bool)
viewModel.models.remove(at: i)
viewModel.models.insert(newModel, at: i)
break
}
}
var count = 0
for i in 0..<viewModel.models.count {
let model = viewModel.models[i]
if model.isOn {
count += 1
}
}
}
}
struct CheckButtonView: View {
let id: String
let text: String
@State var isOn: Bool
var callBack: (String, Bool) -> Void
var body: some View {
HStack {
Button {
isOn.toggle()
callBack(id, isOn)
} label: {
Image(systemName: isOn ? "checkmark.square.fill" : "square")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 18)
.tint(!isOn ? .black : .blue)
}
Text(text)
.font(.subheadline)
Spacer()
}
.frame(maxWidth: .infinity)
}
}
struct Content {
let id: String
let name: String
let isOn: Bool
}
class ContentViewModel: ObservableObject {
@Published var models = [Content]()
@Published var canChange = true
init() {
models = [
Content(id: UUID().uuidString, name: "Jim", isOn: false),
Content(id: UUID().uuidString, name: "Jenny", isOn: false),
Content(id: UUID().uuidString, name: "Nancy", isOn: false),
Content(id: UUID().uuidString, name: "Natalie", isOn: false)
]
}
}
According to the picture above, I have two checkboxes that are turned on. Now, what I want to do is let the user turn on as many as two checkboxes only. Can someone think of a good way of doing that? Thanks.
I'd like to use ScrollViewReader, but on a list of static text that has formatting such as font colors and bold text. Essentially, my list has a bunch of:
Text("some text ") + Text(" and more text").fontWeight(.bold).foregroundStyle(boldColor)
Switching to AttributedString would be a pain, and I'm not so sure ScrollViewReader is working correctly. It seems like there are a lot of bugs reports about it. Plus, do we really need a separate string format, just to have proper formatting? Really?
Is there another version I'm missing? One that can scroll to anchor points that I could set?
How can I make this appear inside the NavigationSplitView toolbar?
It doubles up with the close button and takes up space...
App Main view
import SwiftUI
@main
struct WritingApp: App
{
var body: some Scene
{
DocumentGroup(newDocument: WritingAppDocument())
{ file in
StoryView(document: file.$document)
}
}
}
Story view
import SwiftUI
struct StoryView: View
{
@Binding var document: WritingAppDocument
@State private var isShowingSheet = false
@FocusState private var isFocused: Bool
var body: some View
{
NavigationSplitView
{
Text("Sidebar")
}
detail:
{
HStack
{
Text("Detail View")
}
.toolbar
{
ToolbarItem
{
Button("Book", systemImage: "book")
{
}
}
ToolbarItem
{
Button("Circle", systemImage: "circle")
{
}
}
}
}
}
}
I've been struggling with a problem for the past couple of weeks, and I can't seem to figure out the cause. I'm developing an app that allows users to easily switch languages on macOS. The app is ready, and I submitted it for review, but the problem is that Apple has been unable to approve it for the past two weeks due to an issue.
Upon launching the app, an empty window/container appears, but I cannot reproduce this issue on my own Macs (M1, M2, M3). On my machines, the app works perfectly and launches without the empty window appearing.
Does anyone know how I can identify and resolve this issue? I’ve attached a screenshot of the empty window that needs to be removed from the code, as well as a snippet of the code that might be responsible for it.
I would greatly appreciate any advice or suggestions on how to fix this, as I’m unable to reproduce the error on my end.
Thanks in advance for your help!
@main
struct LanguageSwitcherApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
var body: some Scene {
Settings {
EmptyView()
}
.commands {
CommandGroup(after: .appInfo) {
Button("Show Language Switcher") {
appDelegate.showLanguageSwitcher()
}
}
}
}
}
class AppDelegate: NSObject, NSApplicationDelegate {
private var statusItem: NSStatusItem?
private var languageSwitcherPanel: LanguageSwitchPanel?
func applicationDidFinishLaunching(_ notification: Notification) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem?.button {
button.image = NSImage(named: "icon_top")
button.action = #selector(showMenu)
button.target = self
}
showLanguageSwitcher()
}
@objc private func showMenu() {
let menu = NSMenu()
menu.addItem(NSMenuItem(title: "Close Type Switch", action: #selector(closeApp), keyEquivalent: "q"))
statusItem?.menu = menu
statusItem?.button?.performClick(nil)
statusItem?.menu = nil
}
func showLanguageSwitcher() {
guard languageSwitcherPanel == nil else { return }
let panel = LanguageSwitchPanel()
let hostingController = NSHostingController(rootView: LanguageSwitchView())
panel.contentView = hostingController.view
panel.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
languageSwitcherPanel = panel
}
@objc private func closeApp() {
NSApp.terminate(nil)
}
}
Screenshot: https://ibb.co/hynrgyw
I tried testing the app on my MacBook models (M1, M2, M3) and all of them functioned as expected, launching the app without any additional windows appearing. I also checked the code for any unintended window launches or containers and could not find any issues.
I expected the app to launch without any extra empty windows or containers, but when Apple tested it, they encountered an issue with an empty window appearing upon launch.
Hi,
I am a new SwiftUI app developer and developing my first application. In the process of designing not very GUI rich app, I noticed my app crashed whenever I switched orientation (testing on multiple iPhone devices).
After going through all kind of logs and errors, performance enhancements nothing worked.
Then I started rolling back all GUI related features 1 by 1 and tested (I am sure there are better approaches, but excuse me I am novice in app development :) ).
Even though it's time consuming, I could pin point the cause of the fatal error and app crash, it's due to multiple .shadow modifiers I used on NavigationLink inside a ForEach look (to be precise I used it like following,
.shadow(radius: 15)
.shadow(radius: 20)
.shadow(radius: 20)
.shadow(radius: 20)
.shadow(radius: 20)
Note, there are only 7 items in List and it uses the Hero View (like app store's Today section) for child views.
Once I got rid of shadow modifies or used only 1 app works fine and doesn't crash.
Lesson learnt...
P.S.
It's so ironic that so performance tuned devices couldn't handle this basic GUI stuff.
Hello everyone! I've encountered an issue related to SwiftUI and StoreKit. Please take a look at the SwiftUI code snippet below:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
List {
NavigationLink {
Page1()
} label: {
Text("Go to Page 1")
}
}
}
}
}
struct Page1: View {
@Environment(\.dismiss) private var dismiss
@State private var string: String = ""
var body: some View {
List {
NavigationLink {
List {
Page2(string: $string)
.simpleValue(4)
}
} label: {
Text("Tap this button will freeze the app")
}
}
.navigationTitle("Page 1")
}
}
struct Page2: View {
@Binding var string: String?
init(string: Binding<String>) {
self._string = Binding(string)
}
var body: some View {
Text("Page 2")
}
}
extension EnvironmentValues {
@Entry var simpleValue: Int = 3
}
extension View {
func simpleValue(_ value: Int) -> some View {
self.environment(\.simpleValue, value)
}
}
This view runs normally until the following symbol is referenced anywhere in the project:
import StoreKit
extension View {
func notEvenUsed() -> some View {
self.manageSubscriptionsSheet(isPresented: .constant(false))
}
}
It seems that once the project links the View.manageSubscriptionsSheet(isPresented:) method, regardless of whether it's actually used, it causes the above SwiftUI view to freeze.
Steps to Reproduce:
Clone the repository: https://github.com/gongzhang/StrangeFreeze
Open it in Xcode 16 and run on iOS 17-18.1
Navigate to the second page and tap the button, causing the app to freeze.
Remove manageSubscriptionsSheet(...), then everything will work fine
How to reproduce: create blank Xcode project run on physical iPhone(mine 14 pro) not simulator, updated iOS18.1.1 most up to date, on Xcode 16.1 make a text field enter any value in it in console:
Can't find or decode reasons
Failed to get or decode unavailable reasons
This is happening in my other projects as well and I don't know a fix for it is this just an Xcode bug random log noise? It makes clicking the text field lag sometimes on initial tap.
I am trying to get my head around how to implement a MapKit view using UIViewRepresentable (I want the map to rotate to align with heading, which Map() can't handle yet to my knowledge). I am also playing with making my LocationManager an Actor and setting up a listener. But when combined with UIViewRepresentable this seems to create a rather convoluted data flow since the @State var of the vm needs to then be passed and bound in the UIViewRepresentable. And the listener having this for await location in await lm.$lastLocation.values seems at least like a code smell. That double await just feels wrong. But I am also new to Swift so perhaps what I have here actually is a good approach?
struct MapScreen: View {
@State private var vm = ViewModel()
var body: some View {
VStack {
MapView(vm: $vm)
}
.task {
vm.startWalk()
}
}
}
extension MapScreen {
@Observable
final class ViewModel {
private var lm = LocationManager()
private var listenerTask: Task<Void, Never>?
var course: Double = 0.0
var location: CLLocation?
func startWalk() {
Task {
await lm.startLocationUpdates()
}
listenerTask = Task {
for await location in await lm.$lastLocation.values {
await MainActor.run {
if let location {
withAnimation {
self.location = location
self.course = location.course
}
}
}
}
}
Logger.map.info("started Walk")
}
}
struct MapView: UIViewRepresentable {
@Binding var vm: ViewModel
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeUIView(context: Context) -> MKMapView {
let view = MKMapView()
view.delegate = context.coordinator
view.preferredConfiguration = MKHybridMapConfiguration()
return view
}
func updateUIView(_ view: MKMapView, context: Context) {
context.coordinator.parent = self
if let coordinate = vm.location?.coordinate {
if view.centerCoordinate != coordinate {
view.centerCoordinate = coordinate
}
}
}
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(parent: MapView) {
self.parent = parent
}
}
}
actor LocationManager{
private let clManager = CLLocationManager()
private(set) var isAuthorized: Bool = false
private var backgroundActivity: CLBackgroundActivitySession?
private var updateTask: Task<Void, Never>?
@Published var lastLocation: CLLocation?
func startLocationUpdates() {
updateTask = Task {
do {
backgroundActivity = CLBackgroundActivitySession()
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
if let location = update.location {
lastLocation = location
}
}
} catch {
Logger.location.error("\(error.localizedDescription)")
}
}
}
func stopLocationUpdates() {
updateTask?.cancel()
updateTask = nil
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch clManager.authorizationStatus {
case .authorizedAlways, .authorizedWhenInUse:
isAuthorized = true
// clManager.requestLocation() // ??
case .notDetermined:
isAuthorized = false
clManager.requestWhenInUseAuthorization()
case .denied:
isAuthorized = false
Logger.location.error("Access Denied")
case .restricted:
Logger.location.error("Access Restricted")
@unknown default:
let statusString = clManager.authorizationStatus.rawValue
Logger.location.warning("Unknown Access status not handled: \(statusString)")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
Logger.location.error("\(error.localizedDescription)")
}
}
Hi guys,
I'm trying to add accessibility labels to a static text and custom SwiftUI views. Example:
MyView {
...
}
//.accessibilityElement()
.accessibilityElement(children: .combine)
//.accessibilityRemoveTraits(.isStaticText)
//.accessibilityAddTraits(.isButton)
.accessibilityLabel("ACCESSIBILITY LABEL")
.accessibilityHint("ACCESSIBILITY HINT")
When using 'voiceover' or 'hover text' accessibility features, focus moves only between active elements and not on static elements.
When I add .focusable() it works, but I don't want to make those elements focusable when all accessibility features are off.
I suppose I could do something like this:
.focusable(UIApplication.shared.accessibility.voiceOver.isOn || UIApplication.shared.accessibility.hoverText.isOn)
Note: this is just pseudocode, because I don't remember exactly how to detect current accessibility settings.
However using focusable() with conditions on hundreds of static texts in an app seems to be overkill. Also the accessibility focus is needed on some control containers where we already have a little more complex handling of focus with conditions in focusable(...) on parent and child elements, so extending it for accesssiblity seems to be too complicated.
Is there a simple way to tell accessiblity that an element is focusable specifically for 'hover text' and for 'voiceover'?
Example what I want to accomplish for TV content:
VStack
{
HStack {
Text(Terminator)
if parentalLock {
Image(named: .lock)
{
}
.accessibilityLabel(for: hover, "Terminator - parental lock")
Text("Sci-Fi * 8pm - 10pm * Remaining 40 min. * Live")
.accessibilityLabel(for: hover, "Sci-Fi, 8 to 10pm, Remaining 40 min. Broadcasting Live")
}
.accessibilityLabel(for: voiceover, "Terminator, Sci-Fi, 8 to 10pm, Remaining 40 min. Broadcasting Live, parental lock")```
I saw all Accessibility WWDC videos 2016, 2022, 2024 and googling it for several hours, but I coudln't find any solution for static texts and custom views. From those videos it appears .accessibilityLabel() should be enough, but it clearly works only on actvie elements and does not work for other SwiftUI views on tvOS without focusable().
Can this be done without using focusable() with conditions for detection which accessibility feature is on?
The problem with focusable would be that for accessibility I may need to read a text for parent view, but focus needs to be placed on a child element. I remember problems when focusable() is set on parent view that child was not focusable or something like that - simply put: complications in focus logic.
Thanks.
struct ModelContainerSetup {
static let shared = ModelContainerSetup()
private static let containerIdentifier = "iCloud.Journal"
func setupModelContainer() -> ModelContainer {
let schema = Schema([User.self])
let modelConfiguration = ModelConfiguration(
schema: schema,
isStoredInMemoryOnly: false,
cloudKitDatabase: .private(Self.containerIdentifier)
)
do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}
**Expected Behavior:
**
When CloudKit storage is full, the app should continue functioning with local storage
Data should persist locally even if cloud sync fails
Sync should resume when storage becomes available
**Actual Behavior:
**
ModelContainer initialization fails completely
Local data also stops getting saved
**Environment:
**
iOS 17.0+
SwiftData
Private CloudKit database
Ideal Behaviour:
When iCloud fails, the data should still be saved locally. I do not want to have two different containers so that I can maintain data consistency.
Hi, would anyone be so kind and try to guide me, which technologies, Kits, APIs, approaches etc. are useful for creating a horizontal window with map (preferrably MapKit) on visionOS using SwiftUI?
I was hoping to achieve scenario: User can walk around and interact with horizontal map window and also interact with (3D) pins on the map. Similar thing was done by SAP in their "SAP Analytics Cloud" app (second image from top).
Since I am complete beginner in this area, I was looking for a clean, simple solution. I need to know, if AR/RealityKit is necessary or is this achievable only using native SwiftUI? I tried using just Map() with .rotation3DEffect() which actually makes the map horizontal, but gestures on the map are out of sync and I really dont know, if this approach is valid or complete rubbish.
Any feedback appreciated.
Why assigning function.formula = formula does not change function.formula to formula in one go? It's always late one change behind.
struct CustomFunction has defined
.formula as @MainActor.
I feel stupid.
There is a part of code:
struct CustomFormulaView: View {
@Binding var function: CustomFunction
@State var testFormula: String = ""
@EnvironmentObject var manager: Manager
....
.onChange(of: testFormula) {
debugPrint("change of test formula: \(testFormula)")
switch function.checkFormula(testFormula, on: manager.finalSize) {
case .success(let formula):
debugPrint("before Change: \(function.formula)")
function.formula = formula // Nothing happens
debugPrint("Test formula changed: \(testFormula)")
debugPrint("set to success: \(formula)")
debugPrint("what inside function? \(function.formula)")
Task {
//Generate Image
testImage = await function.image(
size: testImageSize),
simulate: manager.finalSize)
debugPrint("test image updated for: \(function.formula)")
}
....
and it produces this output when changed from 0.5 to 1.0
Debug: change of test formula: 1.0
Debug: before Change: 0.5
Debug: Test formula changed: 1.0
Debug: set to success: 1.0
Debug: what inside function? 0.5
Debug: test image updated for: 0.5
0.5 is an old value, function.formula should be 1.0
WT??
Hi,
This issue started with iOS 18, in iOS 17 it worked correctly. I think there was a change in SectionedFetchRequest so maybe I missed it but it did work in iOS 17.
I have a List that uses SectionedFetchRequest to show entries from CoreData. The setup is like this:
struct ManageBooksView: View {
@SectionedFetchRequest<Int16, MyBooks>(
sectionIdentifier: \.groupType,
sortDescriptors: [SortDescriptor(\.groupType), SortDescriptor(\.name)]
)
private var books: SectionedFetchResults<Int16, MyBooks>
var body: some View {
NavigationStack {
List {
ForEach(books) { section in
Section(header: Text(section.id)) {
ForEach(section) { book in
NavigationLink {
EditView(book: book)
} label: {
Text(book.name)
}
}
}
}
}
.listStyle(.insetGrouped)
}
}
}
struct EditView: View {
private var book: MyBooks
init(book: MyBooks) {
print("Init hit")
self.book = book
}
}
Test 1: So now when I change name of the Book entity inside the EditView and do save on the view context and go back, the custom EditView is correctly hit again.
Test 2: If I do the same changes on a different attribute of the Book entity the custom init of EditView is not hit and it is stuck with the initial result from SectionedFetchResults.
I also noticed that if I remove SortDescriptor(\.name) from the sortDescriptors and do Test 1, it not longer works even for name, so it looks like the only "observed" change is on the attributes inside sortDescriptors.
Any suggestions will be helpful, thank you.
Hello,
I am using Xcode 16.1 (16B40) on MacOS Sequoia 15.1.0 using a Macbook pro M1 Max
I am developing an app for iOS 17 and 18 using SwiftUI
I created UITests to take the screenshots for the appStore on the simulator
The tests run well and all of them are succeded
The problem appears when I try to get the screenshot files from the xcresult files after the test. There is not any screenshot inside it.
I found a data folder and a Info.plist file. In the data folder there are a lot of files with this pattern data.03zD4C6IGFFthK14NwA8mNvcwFHT16g6Tl40Tl1YmBC1bNh6d0YIcnWKyUaQPDXoa8fYo6C3Xcv8xvMtE3_NEXA== and other files with this pattern refs.03zD4C6IGFFthK14NwA8mNvcwFHT16g6Tl40Tl1YmBC1bNh6d0YIcnWKyUaQPDXoa8fYo6C3Xcv8xvMtE3_NEXA==
Ok, I tryed to use fastlane to automatize the screenshots but the problem is still present. The xcresult files have not any png file.
I had no problems doing this action (getting screenshots from a xcresult file) in previous versions of MacOS and Xcode in my current machine.
I just updated my machine to MacOS Sequoia 15.1.1 and the problem is still present
Honestly I don't know how to fix this situation.
With Xcode 15 I had not any problem with that but I am not sure if Xcode 16.0 was runing without problems because I didn't need to use this functionality in those months
Here is my code for a UITest:
import XCTest
final class ScreenshotsUITests: XCTestCase {
let app = XCUIApplication()
let device = "iPhone16"
override func setUpWithError() throws {
continueAfterFailure = true
}
override func tearDownWithError() throws {}
@MainActor
func testEnglishScreens() throws {
let lang = "en"
app.launchArguments.append("UITestMode")
app.launchArguments += ["-AppleLanguages", "(en)"]
app.launchArguments += ["-AppleLocale", "en_US"]
app.launch()
executeTestsForMenus(lang: lang, backLabel: "Back")
executeTestForMatch(lang: lang)
}
@MainActor
func testSpanishScreens() throws {
let lang = "es"
app.launchArguments.append("UITestMode")
app.launchArguments += ["-AppleLanguages", "(es)"]
app.launchArguments += ["-AppleLocale", "es_ES"]
app.launch()
executeTestsForMenus(lang: lang, backLabel: "Atrás")
executeTestForMatch(lang: lang)
}
private func executeTestForMatch(lang: String) {
let startButton = app.buttons["start-button"]
startButton.tap()
let key4 = app.buttons["key-4"]
XCTAssertTrue(key4.waitForExistence(timeout: 30), "Key 4 in match screen is not found")
key4.tap()
let key2 = app.buttons["key-2"]
XCTAssertTrue(key2.exists, "Key 2 in match screen is not found")
key2.tap()
makeScreenShot("playing", lang: lang)
let closeButton = app.buttons["close-button"]
XCTAssertTrue(closeButton.exists, "Close button in match screen is not found")
closeButton.tap()
}
private func executeTestsForMenus(lang: String, backLabel: String) {
let mainHeader = app.staticTexts["Math match"]
XCTAssertTrue(mainHeader.exists, "Header in main screen is not found")
makeScreenShot("mainMenu", lang: lang)
let settingsButton = app.buttons["settings-button"]
XCTAssertTrue(settingsButton.exists, "Settings button in main screen is not found")
settingsButton.tap()
makeScreenShot("Settings", lang: lang)
let backButton = app.buttons[backLabel]
XCTAssertTrue(backButton.exists, "Back button in match screen is not found")
backButton.tap()
let helpButton = app.buttons["help-button"]
XCTAssertTrue(helpButton.exists, "Help button in main screen is not found")
helpButton.tap()
makeScreenShot("Help", lang: lang)
backButton.tap()
let scoreButton = app.buttons["score-button"]
XCTAssertTrue(scoreButton.exists, "Scores button in main screen is not found")
scoreButton.tap()
makeScreenShot("Scores", lang: lang)
backButton.tap()
let playButton = app.buttons["play-button"]
XCTAssertTrue(playButton.exists, "Play button in main screen is not found")
playButton.tap()
makeScreenShot("matchBuilder", lang: lang)
let startButton = app.buttons["start-button"]
XCTAssertTrue(startButton.exists, "Start button in match builder screen is not found")
}
private func makeScreenShot(_ name: String, lang: String) {
takeScreenshot(app, named: "\(lang)-\(name)-\(device)")
}
}
import XCTest
extension XCTestCase {
func takeScreenshot(_ app: XCUIApplication, named name: String, fullScreen: Bool = false) {
let screenshot: XCUIScreenshot
if fullScreen {
screenshot = app.windows.firstMatch.screenshot()
} else {
screenshot = XCUIScreen.main.screenshot()
}
let screenshotAttachment = XCTAttachment(
uniformTypeIdentifier: "public.png",
name: "screenshot-\(name).png",
payload: screenshot.pngRepresentation,
userInfo: nil)
screenshotAttachment.lifetime = .keepAlways
add(screenshotAttachment)
}
}
and here is the content of my testplan file:
{
"configurations" : [
{
"id" : "35BC7C0B-9A5A-4027-9F30-36958C4C1AAF",
"name" : "Test Scheme Action",
"options" : {
"preferredScreenCaptureFormat" : "screenshot",
"testExecutionOrdering" : "random",
"uiTestingScreenshotsLifetime" : "keepAlways",
"userAttachmentLifetime" : "keepAlways"
}
}
],
"defaultOptions" : {
"targetForVariableExpansion" : {
"containerPath" : "container:myAppProject.xcodeproj",
"identifier" : "B27D1B022CA00314001A259B",
"name" : "MyAppProject"
}
},
"testTargets" : [
{
"parallelizable" : true,
"target" : {
"containerPath" : "container:MyAppProject.xcodeproj",
"identifier" : "B27D1B122CA00315001A259B",
"name" : "MyAppProjectTests"
}
},
{
"parallelizable" : true,
"target" : {
"containerPath" : "container:MyAppProject.xcodeproj",
"identifier" : "B27D1B1C2CA00315001A259B",
"name" : "MyAppProjectUITests"
}
}
],
"version" : 1
}
I made tests with old projects in my machine and those projects have the same problem with screenshot files in the xcresult bundles
I don't know if the problem is in my machine, my Xcode, MacOS or other ting. I don't know how to fix this problem
Please, can anyone help me?
Thanks in advance
We have been trying to migrate screens that were developed using UITool Kit to SwiftUI. In the process we have some screens that have SwiftUI embedded inside the UITool kit view. Our developers have defined accessibility ids for all elements in these views and these are inspectable using the native iOS xcode inspector. However when i try inspecting it with the appium inspector i get an empty list with no elements in the hierarchy tree. Attaching a screenshot of the element when inspecting through the native xcode accessibility inspector,
Attaching a screenshot of the same screen when inspected through the appium inspector,
Also tried printing the XCTest UI dump using appium method,
`driver().executeScript("mobile:source", Map.ofEntries(Map.entry("format","description")))
The UI tree i get is the same that i get when inspecting through the appium inspector.
Requesting support from the Apple team based on this ticket, [https://github.com/appium/appium/issues/20759)