I am currently implementing multiple scenes in my React Native / Swift application (one scene for the phone and one scene for CarPlay). I am facing an issue where one scene renders completely white (on the iPhone) but I can see in the console that the code is running (for example if I add a console.log to the App.tsx I can see that console log happen in XCode).
There are no errors when building the app in XCode, and testing with the simulator CarPlay appears to render the correct output, but there is no component being rendered on the simulated phone screen (just white).
AppDelegate.swift
import CarPlay
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import UIKit
@main
class AppDelegate: RCTAppDelegate {
var rootView: UIView?;
static var shared: AppDelegate { return UIApplication.shared.delegate as! AppDelegate }
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
self.moduleName = "appName"
self.dependencyProvider = RCTAppDependencyProvider()
self.initialProps = [:]
self.rootView = self.createRootView(
with: RCTBridge(
delegate: self,
launchOptions: launchOptions
),
moduleName: self.moduleName!,
initProps: self.initialProps!
);
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
if (connectingSceneSession.role == UISceneSession.Role.carTemplateApplication) {
let scene = UISceneConfiguration(name: "CarPlay", sessionRole: connectingSceneSession.role)
scene.delegateClass = CarSceneDelegate.self
return scene
}
let scene = UISceneConfiguration(name: "Phone", sessionRole: connectingSceneSession.role)
scene.delegateClass = PhoneSceneDelegate.self
return scene
}
override func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}
override func sourceURL(for bridge: RCTBridge) -> URL? {
self.bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
PhoneSceneDelegate.swift
import Foundation
import UIKit
import SwiftUI
class PhoneSceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?;
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if session.role != .windowApplication {
return
}
guard let appDelegate = (UIApplication.shared.delegate as? AppDelegate) else {
return
}
guard let windowScene = (scene as? UIWindowScene) else {
return
}
let rootViewController = UIViewController()
rootViewController.view = appDelegate.rootView;
let window = UIWindow(windowScene: windowScene)
window.rootViewController = rootViewController
self.window = window
window.makeKeyAndVisible()
}
}
App.tsx
import React, {useEffect, useState} from 'react';
import type {PropsWithChildren} from 'react';
import {CarPlay, ListTemplate} from 'react-native-carplay';
import {
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
type SectionProps = PropsWithChildren<{
title: string;
}>;
function Section({children, title}: SectionProps): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
}
function App(): any { // React.JSX.Element
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [carPlayConnected, setCarPlayConnected] = useState(CarPlay.connected);
useEffect(() => {
function onConnect() {
setCarPlayConnected(true);
CarPlay.setRootTemplate(new ListTemplate(/** This renders fine on the CarPlay side */));
}
function onDisconnect() {
setCarPlayConnected(false);
}
CarPlay.registerOnConnect(onConnect);
CarPlay.registerOnDisconnect(onDisconnect);
return () => {
CarPlay.unregisterOnConnect(onConnect);
CarPlay.unregisterOnDisconnect(onDisconnect);
};
});
if (carPlayConnected) {
console.log('car play connected');
} else {
console.log('car play not connected');
}
const safePadding = '5%';
// This doesn't render on the phone?
return (
<View style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
style={backgroundStyle}>
<View style={{paddingRight: safePadding}}>
<Header/>
</View>
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
paddingHorizontal: safePadding,
paddingBottom: safePadding,
}}>
<Section title="Step One">
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
screen and then come back to see your edits.
</Section>
<Section title="See Your Changes">
<ReloadInstructions />
</Section>
<Section title="Debug">
<DebugInstructions />
</Section>
<Section title="Learn More">
Read the docs to discover what to do next:
</Section>
<LearnMoreLinks />
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;
I have been attempting to get this working now for some 20+ hours with no luck with searching for answers elsewhere. I am very new to building apps with React Native and Swift so could do with some support.
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm testing using Group Activities and having no trouble iOS<->iOS or starting an activity on macOS and joining via iOS. However, when I start an activity and then try to join it from another macOS client, the starting side joins the session just fine, but the receiving side acts like I don't have the required app, even when it is already running.
I see the active SharePlay icon in the menu bar, and the Current Activity is shown, but instead of an "Open" button there is a "MyApp Required" string and a "View" button that goes to the App Store. (Where the app is not available yet, as expected, since I'm still working on it.) There is no GroupSession started on that Mac yet, obviously.
I'm looking for any hints to help debug what is going on. How does Group Activities find the app for the activity on macOS and how can I figure out why it isn't finding mine?
Thanks!
Hello Apple Developer Community,
I’m experiencing an issue with my iOS app, "WaterReminder," where it builds successfully in Xcode 16.2 but crashes immediately upon launch in the iPhone 16 Pro Simulator running iOS 18.3.1. The crash is accompanied by a "Thread 1: signal SIGABRT" error, and the Xcode console logs indicate a dyld error related to XCTest.framework/XCTest not being loaded. I’ve tried several troubleshooting steps, but the issue persists, and I’d appreciate any guidance or insights from the community.
Here are the details:
Environment:
Xcode Version: 16.2
Simulator: iPhone 16 Pro, iOS 18.3.1
App: WaterReminder (written in SwiftUI 6)
Build Configuration: Debug
Issue Description:
The app builds without errors, but when I run it in the iPhone 16 Pro Simulator, it shows a white screen and crashes with a SIGABRT signal. The Xcode debugger highlights the issue in the main function or app delegate, and the console logs show the following error:
dyld[7358]: Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: <549B4D71-6B6A-314B-86BE-95035926310E> /Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/WaterReminder.debug.dylib
Reason: tried: '/Users/faytek/Library/Developer/Xcode/DerivedData/WaterReminder-cahqrulxghamvyclxaozotzrbsiz/Build/Products/Debug-iphonesimulator/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_22D8075/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.3.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/XCTest.framework/XCTest' (no such file)
What I’ve Tried:
◦ Verified that FBSnapshotTestCase is correctly added to the "Embed Frameworks" build phase.
◦ Confirmed that the Framework Search Paths in build settings point to the correct location.
◦ Ensured that all required frameworks are available in the dependencies folder.
◦ Cleaned the build folder (Shift + Option + Command + K) and rebuilt the project.
◦ Checked the target configuration to ensure XCTest.framework isn’t incorrectly linked to the main app target (it’s only in test targets).
◦ Updated Xcode and the iOS Simulator to the latest versions.
◦ Reset the simulator content and settings.
Despite these steps, the app continues to crash with the same dyld error and SIGABRT signal. I suspect there might be an issue with how XCTest.framework is being referenced or loaded in the simulator, possibly related to using SwiftUI 6, but I’m unsure how to resolve it.
Could anyone provide advice on why XCTest.framework is being referenced in my main app (since it’s not intentionally linked there) or suggest additional troubleshooting steps? I’d also appreciate any known issues or workarounds specific to Xcode 16.2, iOS 18.3.1, and SwiftUI 6.
Thank you in advance for your help!
Best regards,
Faycel
I am trying to support dragging out a 'file' object from my app into Finder, on macOS. I have my object conform to Transferable and the files are saved on disk locally, so I just want to pass it the URL. This works fine when dragging out to other apps, like Notes or Mail, but not in Finder. I setup a ProxyRepresentation as well, as suggested by another thread, but it doesn't seem to help. Is there any other setup I need to do in the Xcode project file for it to work, or is there something else that I'm missing?
@available(iOSApplicationExtension 17.0, macOSApplicationExtension 14.0, *)
extension FileAttachments: Transferable {
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: UTType.content) { content in
SentTransferredFile(content.fullFileURL(), allowAccessingOriginalFile: false)
}
.exportingCondition { file in
if let fileUTI = UTType(filenameExtension: file.fullFileURL().pathExtension), let fileURL = file.fullFileURL() {
print("FileAttachments: FileRepresentation exportingCondition fileUTI: \(fileUTI) for file: \(fileURL)")
return fileUTI.conforms(to: UTType.content)
}
return false
}
.suggestedFileName{$0.fileRenamedName}
ProxyRepresentation { file in
if let fileURL = file.fullFileURL() {
print("FileAttachments: ProxyRepresentation returning file")
return fileURL
}
return file.fullFileURL()!
}
}
}
I’m encountering an issue with SwiftUI navigation in iOS 18, where navigating to a DetailView causes unexpected duplication of navigation behavior when @Environment(.dismiss) is used.
Code Example: Here’s a simplified version of the code:
struct ContentView: View {
var body: some View {
NavigationStack {
NavigationLink("Go to Detail View", destination: DetailView())
.padding()
}
}
}
struct DetailView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
VStack {
let _ = print("DetailView") // This print statement is triggered twice in iOS 18
}
}
}
Issue:
In iOS 18, when @Environment(.dismiss) is used in DetailView, the print("DetailView") statement is triggered twice.
The same code works correctly in iOS 17 and earlier, where the print statement is only triggered once, as expected.
However, when I remove @Environment(.dismiss) from DetailView, the code works as intended in iOS 18, with the print statement being triggered only once and no duplication of navigation behavior.
Alternative Approach with .navigationDestination(for:): I also tested using .navigationDestination(for:) to handle navigation:
struct ContentView: View {
var body: some View {
NavigationStack {
NavigationLink("Go to Detail View", destination: DetailView())
.padding()
}
}
}
struct DetailView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
VStack {
let _ = print("DetailView") // This print statement is triggered twice in iOS 18
}
}
}
Even with this alternative approach, the issue persists in iOS 18, where the print statement is triggered twice.
What I've Tried:
I’ve confirmed that removing @Environment(.dismiss) solves the issue, and the print statement is triggered only once, and the navigation works as expected in iOS 18 without duplication.
The issue only occurs when @Environment(.dismiss) is in use, which seems to be tied to the navigation stack behavior. The code works correctly in iOS 17 and below, where the print statement is only called once.
Expected Behavior:
I expect the print("DetailView") statement to be called once when navigating to DetailView, and that the navigation happens only once without duplication. The presence of @Environment(.dismiss) should not cause the navigation to be triggered multiple times.
Questions:
Is this a known issue with iOS 18 and SwiftUI navigation? Specifically, is there a new behavior that interacts differently with @Environment(.dismiss)?
Has anyone else encountered this problem, and if so, what’s the recommended way to handle it in iOS 18?
Is there a workaround to ensure that the navigation doesn’t trigger more than once when using @Environment(.dismiss) in iOS 18?
Any help or insights would be greatly appreciated!
I want SensorKit data for research purposes in my current application. I have applied for and received permission from Apple to access SensorKit data.
During implementation, I encountered an issue in which no data was being retrieved despite granting all the necessary permissions.
I am using did CompleteFetch & didFetchResult delegate methods for retrieving data from Sensorkit. CompleteFetch method calls but where I can find different event data like Device usage, Ambient Light, etc? & didFetchResult method does not call.
Methods I am using:
1. func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest)
2. func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool
Could anyone please assist me in resolving this issue? Any guidance or troubleshooting steps would be greatly appreciated.
I'm not quite sure where the problem is, but I will describe what I am doing to recreate the issue, and am happy to provide whatever information I can to be more useful.
I am changing the ActivationPolicy for my app in order to make it unobtrusive when in the background (e.g. hiding it from the dock and using only a menu bar status item). When the user activates the app with a hotkey, it changes from NSApplicationActivationPolicyAccessory back to NSApplicationActivationPolicyRegular. This allows normal usage (dock icon, menu bar, etc.)
This works fine, except in a rare situation which I finally just tracked down. If there is a window open in the app and I use the hotkey to convert back to an accessory, and then disconnect and reconnect the display on which the app was previously displayed, when I convert the app back to "regular mode", the menu bar has disappeared (and I am left with an empty space at the top of the screen). I can also trigger this bug by having the display in question briefly mirror the other display (effectively "orphaning" the hidden app), and then restoring the original side-by-side configuration before activating the app again.
The app otherwise works, but the menu bar is missing. Switching back and forth with other apps does not fix the problem. Quitting and restarting the app resolves the issue. As does disabling the accessory only mode and forcing the app to always remain in "regular mode" with a dock icon (there is a preference for this in my app). Once fixed, I can then re-enable the "accessory mode" and all is well until the bug is triggered again.
The bug would normally occur quite sporadically, presumably requiring a particular combination of changing Spaces or displays, or having the computer go to sleep while this app was in accessory mode. Thus far, the above is the only way I have found that can replicate this issue on demand.
If I close all windows before hiding the app, then it works fine when I revert to "regular mode". It only happens if there is a window open at the time.
Using applicationDidChangeScreenParameters: on my AppDelegate indicates that there is a change in screen, and logging window.screen.frame for each open window in [NSApp orderedWindows] shows that the size changes from e.g. 1920x1080 to 0x0 and back while the display is disconnected or mirrored.
There is also an error in the console in Xcode when this happens -- invalid display identifier <some UUID>.
I have tried various options for window collectionBehavior, as well as various settings for Spaces (which I normally use). None of these changes has fixed the behavior thus far.
I use [NSApp hide:self]; from my AppDelegate to hide the app, and [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateAllWindows];[NSApp unhide:self]; to bring it back to the front.
I welcome any ideas for things to chase down, or requests for more specific information that would be useful.
Thank you!
Fletcher
I recently noticed an inconsistency in how languages are represented in Apple’s new Translation API compared to Foundation’s Locale system.
Observation from the Translation API
When retrieving the list of supported languages using:
let availableLanguages = try await LanguageAvailability().supportedLanguages
The results are:
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(uk), script: nil, region: Optional(UA)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(zh), script: nil, region: Optional(TW)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(ko), script: nil, region: Optional(KR)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(en), script: nil, region: Optional(GB)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(de), script: nil, region: Optional(DE)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(zh), script: nil, region: Optional(CN)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(ja), script: nil, region: Optional(JP)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(id), script: nil, region: Optional(ID)))
Language(components: Foundation.Locale.Language.Components(languageCode: Optional(nl), script: nil, region: Optional(NL)))
....
Key points:
• The script component is always nil.
• Region codes (CN, TW, etc.) determine the script for languages like Chinese (Simplified or Traditional).
• Other languages (e.g., en-GB, en-US, pt-BR) also rely on region-based identification.
Observation from Foundation Locale (Locale.current.language)
When retrieving the user’s system language setting:
systemLanguageObj = Locale.current.language
I get a different format where the script component is present, but the region may vary based on user settings. This means that mapping between script and region is not consistent between the two APIs, requiring manual handling.
My key questions:
1. Is my current approach correct, or is there a better way to get user language settings that match Translation API identifiers?
2. If no alternative exists, could the Translation API align its language identification method with Foundation Locale to reduce ambiguity?
Any insights or suggestions would be greatly appreciated!
Embedding a NavigationStack inside the detail view of a NavigationSplitView is described by the Apple documentation: https://developer.apple.com/documentation/swiftui/navigationsplitview
However, I would like to do the opposite: embedding a NavigationSplitView inside a NavigationStack. I have found no hint in the documentation about why this shouldn't be possible, but it does not appear to be working consistently.
There are many use cases where you might want to do this. E.g. you have an eBook reader that starts with a list of books (e.g. a Grid inside a NavigationStack), and when you open a book, you end up in a NavigationSplitView showing the chapter hierarchy in a sidebar. Here, you wouldn't want to have the list of books as a second sidebar, but would want an option to go back to the list of books at any time.
The following trivial example correctly displays a NavigationSplitView on iPadOS, but results in an empty view on iOS:
NavigationStack {
NavigationSplitView {
List {
Text("Element1")
Text("Element2")
}
} detail: {
Text("Detail")
}
}
Is there a workaround?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I have an app that run Monte Carlo simulations. I run thousands of simulations in the app and a simulation runs can take on the order of 30 seconds to a minute to complete. I would like to have a progress view that tracks the number of simulation runs. How can I implement this in swiftui?
I'm getting the following error Error Domain=com.google.GIDSignIn Code=-4. How do I find out what I'm missing with my setup of Google Cloud?
Topic:
UI Frameworks
SubTopic:
SwiftUI
When I build UITabBarController on (iPad + iOS18), selectedImage on each tabBarItems don't appear. (SwiftUI TabView can change iconImages by state change, so no problem on SwiftUI. But I need to use UITabBarController)
How Could I solve this problem and show the selectedImages?
sample project which produce the problem: github
If you add the .scaleEffect() modifier to a parent view inside of which there are children with contextMenu()-s, the context menu preview unfortunately keeps the original, unscaled size of the child view. This results in a very weird, glitchy user experience.
Unfortunately, providing a custom preview that is scaled up also does not help, since even though it is the right size, it gets cropped to the unscaled size of the child view.
Adding scaleEffect() to each child element individually (BEFORE the contextMenu() modifier!) does make the problem disappear. However, I would like to avoid this, since my use case is zooming into a complex graph with context menus on its nodes, and having to recalculate the position of each node manually seems to perform much worse than delegating that work to scaleEffect().
Tested on iOS 18.2 (device + emulator)
Is there a workaround?
Here is a minimal working example that demonstrates the problem:
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Rectangle()
.frame(width: 100, height: 100)
.contextMenu {
Button("Test") {}
Button("Test") {}
}
Rectangle()
.frame(width: 100, height: 100)
.contextMenu {
Button("Test") {}
Button("Test") {}
}
}
.scaleEffect(1.5)
}
}
Screenshot (problem: The two squares are the same size. However, the long-tapped upper square got shrunk down before the context menu got displayed.)
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hello, I've managed to get rid of these spaces in different ways. Using scrollview, giving negative insets, rewriting modifiers from scratch with plain style etc. But I couldn't solve this with a simple solution. I've read comments from many people experiencing similar problems online. It seems like there isn't a simple modifier to remove these spaces when we use sidebar as the list style in SwiftUI, or I couldn't find the simple solution.
I wonder what's the simplest and correct way to reset these spaces?
let numbers = Array(1...5)
@State private var selected: Int?
var body: some View {
List(numbers, id: \.self, selection: $selected) { number in
HStack {
Text("Test")
Spacer()
}
.frame(maxWidth: .infinity, alignment: .leading)
}
.listStyle(.sidebar)
}
}
In SwiftUI I want to create a list with LazyVstack and each row item in the LazyVstack is a LazyHstack of horizontally scrollable list of images with some description with line limit of 3 and width of every item is fixed to 100 but height of every item is variable as per description text content.
But in any of the rows if the first item has image description of 1 line and the remaining items in the same row has image description of 3 lines then the LazyHStack is truncating all the image descriptions in the same row to one line making all the items in that row of same height.
Why LazyHStack is not supporting items of varying height ?
Expected behaviour should be that height of every LazyHStack should automatically adjust as per item content height. But it seems SwiftUI is not supporting LazyHstack with items of varying height.
Will SwiftUI ever support this feature?
Topic:
UI Frameworks
SubTopic:
SwiftUI
This is a very strange behavior when pushing vc that I have never seen since I started coding. The pushed ViewController is transparent and only navBarTitle is shown. After the push, you can't control anything unless you go back to the home screen.
STEPS TO REPRODUCE
Long press currency change button below.(currencyWrapper)
Call selectCountry and this bug happens.
SourceCode
let currencyWrapper = UIView()
private func configureCurrencyCard(){
//The strange behavior shows up after long pressing this
currencyWrapper.backgroundColor = .white
currencyWrapper.addTarget(self, action: #selector(changeCurrency))
currencyWrapper.setWidth(currencyChangeIcon.follow(by: 16, x: true))
currencyWrapper.setCenterX(w1/2)
currencyWrapper.setHeight(currencyLabel.follow(by: 12, x: false))
currencyWrapper.roundToCircle(true)
view.addSubview(currencyWrapper)
}
private func selectCountry(country: Country){
let vc = CountryViewController(country: country)
vc.hidesBottomBarWhenPushed = true
navigationController?.pushViewController(vc, animated: true)
}
This pertains to iPad apps and UITabbarController in UIKit.
Our internal app for employees utilizes UITabbarController displayed at the bottom of the screen. Users prefer to maintain consistency with it being at the bottom. It becomes challenging to argue against this when users point out the iPhone version displaying it "correctly" at the bottom. My response is to trust Apple's design team to keep it at the top.
One workaround is to develop the app using the previous Xcode version, version 15 (via Xcode Cloud), targeting padOS17. This ensures the tab bar is shown at the bottom of the screen. However, this approach has its drawbacks: Apple may not support it in the future, leading to missed secure updates for the app, among other issues.
Exploring the UITabbarController mode appears to be the solution I am seeking. To quote the documentation "on iPad, If the tabs array contains one or more UITabGroup items, the system displays the content as either a tab bar or a sidebar, depending on the context. Otherwise, it only displays the content only as a tab bar.". The part "displays the content only as a tab bar." made think this is BAU:
class ViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.mode = .tabBar
}
}
Unfortunately, this does not resolve the issue.
Is there an API method that can force the tabbar to its previous bottom position?
The app uses multiple windows. When we split a window to launch another instance, the tab bar appears at the bottom. This behavior seems tied to the form factor—or potentially to how many items are in the tab bar.
We could build a custom tab bar to override this, but that goes against my “don’t reinvent the wheel” principle.
Any comments we welcome and thank you for reading this (to the end)
Theo
I'm trying to create a form which reads and writes data to a dictionary. when I type something in a field whole form seems to update. Is there anyway to only update the field I'm typing? Android compose have something called SnapshotStateMap which allows smart re-rendering.
Topic:
UI Frameworks
SubTopic:
SwiftUI
I must admit my knowledge of swift is limited, and I cannot wrap my head around this problem.
I've defined this protocol, so I can use different auth providers in my app.
protocol AuthRepository {
associatedtype AuthData
associatedtype AuthResponseData
associatedtype RegistrationData
associatedtype RegistrationResponseData
func login(with data: AuthData) async throws -> AuthResponseData?
func register(with data: RegistrationData) async throws -> RegistrationResponseData?
}
and an implementation for my server
struct MyServerAuthData {
let email: String
let password: String
}
struct MyServerAuthResponseData {
let token: String
}
struct MyServerRegistrationData {
let email: String
let password: String
let name: String
}
actor AuthRepositoryImpl: AuthRepository {
func login(with data: MyServerAuthData) async throws -> MyServerAuthResponseData? {
...
}
func register(with data: MyServerRegistrationData) async throws -> Void? {
...
}
}
To use across the app, I've created this ViewModel
@MainActor
final class AuthViewModel<T: AuthRepository>: ObservableObject {
private let repository: T
init(repository: T) {
self.repository = repository
}
func login(data: T.AuthData) async throws -> T.AuthResponseData? {
try await repository.login(with: data)
}
func register(with data: T.RegistrationData) async throws {
try await repository.register(with: data)
}
}
defined in the app as
@main
struct MyApp: App {
@StateObject var authViewModel = AuthViewModel(repository: AuthRepositoryImpl())
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(self.authViewModel)
}
}
}
and consumed as
@EnvironmentObject private var authViewModel: AuthViewModel<AuthRepositoryImpl>
But with this code, the whole concept of having a generic implementation for the auth repository is useless, because changing the AuthRepostory will need to search and replace AuthViewModel<AuthRepositoryImpl> across all the app.
I've experienced this directly creating a MockAuthImpl to use with #Preview, and the preview crashed because it defines AuthViewModel(repository: MockAuthImpl()) but the view expects AuthViewModel.
There is a better way to do that?
I would like to provide a way to choose an app icon as a reward for using the referral feature of the app.
I found that setting the image via NSApp.applicationIconImage works, but only when the app is running, and the app icon is reset on the next launch.
I also found NSDockTile plugin APIs, and that seems to be the way, but it won't be allowed on the Mac App Store.
Is there really no way to do it legit way and pass the Mac App Store review?
Seems to be another really strange limitation imposed.