A NavigationStack with a singular enum for .navigationDestination() works fine.
Both NavigationLinks(value:) and directly manipulating the NavigationPath work fine for moving around views. Zero problems.
The issue is when we instead use a NavigationSplitView, I've only dabbled with two-column splits (sidebar and detail) so far.
Now, if the sidebar has its own NavigationStack, everything works nicely on an iPhone, but on an iPad, you can't push views onto the detail from the sidebar. (They're pushed on the sidebar)
You can solve this by keeping a NavigationStack ONLY on the detail. Sidebar links now properly push onto the detail, and the detail can move around views by itself.
However, if you mix NavigationLink(value:) with manually changing NavigationPath, it stops working with no error. If you only use links, you're good, if you only change the NavigationPath you're good. Mixing doesn't work. No error in the console either, the breakpoints hit .navigationDestination and the view is returned, but never piled up. (Further attempts do show the NavigationPath is being changed properly, but views aren't changing)
This problem didn't happen when just staying on NavigationStack without a NavigationSplitView.
Why mix? There's a few reasons to do so. NavigationLinks put the appropriate disclosure indicator (can't replicate its look 100% without it), while NavigationPaths let you trigger navigation without user input (.onChange, etc)
Any insights here? I'd put some code samples but there's a metric ton of options I've tested here.
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
Hey Everyone,
I can't see to ActiveLabel as it says there is no active module. Please help me.
Thanks,
Ben
import UIKit
import ActiveLabel
protocol TweetCellDelegate: AnyObject {
func handleProfileImageTapped(_ cell: TweetCell)
func handleReplyTapped(_ cell: TweetCell)
func handleLikeTapped(_ cell: TweetCell)
}
class TweetCell: UICollectionViewCell {
Where from and how does an NSRulerView get its magnification from? I am not using the automatic magnification by NSScrollView but using my own mechanism. How do I relay the zoom factor to NSRulerView?
With iPadOS 18, the UITabBar now defaults to the floating style. I successfully reverted the tab bar to its traditional style by overriding the UITabBarController's horizontalSizeClass property:
self.tabBarController?.traitOverrides.horizontalSizeClass = .unspecified
When I launch the app on my Mac using Apple Silicon, TWO tab bars appear:
One appears at the bottom of the screen, like a traditional tab bar.
The second tab bar is still embedded in the app toolbar in its floating style.
Is this a bug? How do you ensure that overriding the horizontalSizeClass will remove/hide the floating tab bar when running an app on Apple Silicon? TIA!
(Demonstrated on a test project)
Has anyone gotten custom buttons to work on top of tvOS Map()? I've tried many variations of
FocusState
focusSection
.defaultFocus()
and as soon as the map appears at startup the buttons never get focus again. They are on a ZStack over the map. I could post code but truthfully nothing works for me. I'm wondering if anyone has successfully put focusable buttons on top of the map view.
WKWebView cannot load and display HTTP image resources
Topic:
UI Frameworks
SubTopic:
UIKit
Xcode 16 iOS18 WKWebView里包含http图片时无法显示
Topic:
UI Frameworks
SubTopic:
UIKit
We are using the contactAccessPicker modifier connected to a Button to allow the user to change the selection of contacts that he allows for use in our app. In the two places where the iOS UI screen refers to our app:
"manage which contacts can access." on top,
and below in the explanatory text, again ,
the value of is taken probably from the app's PRODUCT_NAME. Instead, we need it to be either CFBundleName or CFDisplayBundleName.
In our case they are different (PRODUCT_NAME is legacy, reasons of rebranding, which is a very common reason in apps).
Is there a specific reason why iOS is using PRODUCT_NAME (or something similar) in the contactAccessPicker UI screen instead of the user facing CFBundleName or CFDisplayBundleName? or is this a bug?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I’m having a weird UIKit problem. I have a bunch of views in a UIScrollView and I add a UIContextMenuInteraction to all of them when the view is first loaded. Because they're in a scroll view, only some of the views are initially visible.
The interaction works great for any of the views that are initially on-screen, but if I scroll to reveal new subviews, the context menu interaction has no effect for those.
I used Xcode's View Debugger to confirm that my interaction is still saved in the view's interactions property, even for views that were initially off-screen and were then scrolled in.
What could be happening here?
I want to use Objective C language to implement a button, click the button to achieve the function of Menu Bar - Full Screen Tile - Left of Screen. What should I do? I couldn't find the relevant API.
Topic:
UI Frameworks
SubTopic:
AppKit
We are developing an MacOS app from our iOS app using MacCatalyst.
If I press long on the app icon on the Dock, a list of recent files appears.
If I tap one one of these files nothing happens. I would expect the scene delegate function:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)
would be called but it is not. Can somebody maybe explain what I am missing here?
The list of recent files also appears in the Menu under File > Open recent files. There I can tap on a file and it it is opened correctly using the scene delegate method mentioned above.
The files can also be opened with the app using the Finder, so the associated file types with the app are correct.
I've been trying to add a header to the tabSection of the tabview in tvos 18+ .
init(
@TabContentBuilder<SelectionValue> content: () -> Content,
@ViewBuilder header: () -> Header
) where Header : View, Footer == EmptyView
Here the ehader clearly conforms to View but i cant quite fit the label with uiimage as the icon into this. This Label when i add it to any other view, the image is in the specified 50 x 50 size but inside header it functions weirdly to be of a huge size. but also to note, if i simply hav an icon here, it is correct. So what is the problem here.. can someone help me? im supposed to add the user profile and name in the header. I dont think there's any other way
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.
I used the Multipeer Connectivity Framework to allow players of my game app to see the highest score along with their own score as the game progresses. It works fine running in 3 or 4 simulators in Xcode. However, I was just told by two Apple support reps that bluetooth connectivity is not allowed between two Apple devices, other than for watches, AirPods, headphones, etc.
My question is: can two iPhones or iPads connect for peer-to-peer play? Can they play offline? If the answer is yes to either or both of those questions, how do I get that to happen since I get an error message when trying to connect two iPhones via bluetooth even though they can see each other in the Other Devices list?
If the answer is no, then why does Apple provide a Multipeer Connectivity Framework and simulate that type of device to device connection with the Xcode simulators?
Topic:
UI Frameworks
SubTopic:
SwiftUI
At this line of code (SketchTextSelectionManager.swift:378), sometimes there will be crashes based on crashlytics reports. In the reports, it seems like this only happens for RTL text range.
let selection = pdfPage.selection(
from: CGPoint(x: fromStart.x + 1, y: fromStart.y - 1),
to: CGPoint(x: toEnd.x - 1, y: toEnd.y + 1)
)
This is directly calling into PDFKit's PDFPage#selection method: https://developer.apple.com/documentation/pdfkit/pdfpage/selection(from:to:)
Attached the full stacktrace:
Crashed: com.apple.root.user-initiated-qos.cooperative
0 CoreGraphics 0x30598c PageLayout::convertRTLTextRangeIndexToStringRangeIndex(long) const + 156
1 CoreGraphics 0x44c3f0 CGPDFSelectionCreateBetweenPointsWithOptions + 224
2 PDFKit 0x91d00 -[PDFPage selectionFromPoint:toPoint:type:] + 168
3 MyApp 0x841044 closure #1 in SketchTextSelectionManager.handleUserTouchMoved(_:) + 378 (SketchTextSelectionManager.swift:378)
4 MyApp 0x840cb0 SketchTextSelectionManager.handleUserTouchMoved(_:) + 205 (CurrentNoteManager.swift:205)
5 libswift_Concurrency.dylib 0x60f5c swift::runJobInEstablishedExecutorContext(swift::Job*) + 252
6 libswift_Concurrency.dylib 0x63a28 (anonymous namespace)::ProcessOutOfLineJob::process(swift::Job*) + 480
7 libswift_Concurrency.dylib 0x6101c swift::runJobInEstablishedExecutorContext(swift::Job*) + 444
8 libswift_Concurrency.dylib 0x62514 swift_job_runImpl(swift::Job*, swift::SerialExecutorRef) + 144
9 libdispatch.dylib 0x15ec0 _dispatch_root_queue_drain + 392
10 libdispatch.dylib 0x166c4 _dispatch_worker_thread2 + 156
11 libsystem_pthread.dylib 0x3644 _pthread_wqthread + 228
12 libsystem_pthread.dylib 0x1474 start_wqthread + 8
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
I'm attempting to write a macOS version of https://stackoverflow.com/a/74935849/2178159.
From my understanding, I should be able to set the menu property of an NSResponder and it will automatically show on right click.
I've tried a couple things:
A: set menu on an NSHostingController's view - when I do this and right or ctrl click, nothing happens.
B: set menu on NSHostingController directly - when I do this I get a crash Abstract method -[NSResponder setMenu:] called from class _TtGC7SwiftUI19NSHostingControllerGVS_21_ViewModifier_...__. Subclasses must override
C: manually call NSMenu.popup in a custom subclasses of NSHostingController or NSView's rightMouseDown method - nothing happens.
extension View {
func contextMenu(menu: NSMenu) -> some View {
modifier(ContextMenuViewModifier(menu: menu))
}
}
struct ContextMenuViewModifier: ViewModifier {
let menu: NSMenu
func body(content: Content) -> some View {
Interaction_UI(
view: { content },
menu: menu
)
.fixedSize()
}
}
private struct Interaction_UI<Content: View>: NSViewRepresentable {
typealias NSViewType = NSView
@ViewBuilder var view: Content
let menu: NSMenu
func makeNSView(context: Context) -> NSView {
let v = NSHostingController(rootView: view)
// option A - no effect
v.view.menu = menu
// option B - crash
v.menu = menu
return v.view
}
func updateNSView(_ nsView: NSViewType, context: Context) {
// part of option A
nsView.menu = menu
}
}
I have a SwiftUI project which has the following hierarchy:
IOSSceneDelegate (App target) - depends on EntryPoint and Presentation static libs.
Presentation (Static library) - Depends on EntryPoint static lib. Contains UI related logic and updates the UI after querying the data layer.
EntryPoint (Static library) - Contains the entry point, AppDelegate (for its lifecycle aspects) etc.
I've only listed the relevant targets here.
SceneDelegate was initially present in EntryPoint library, because the AppDelegate references it when a scene is created.
public func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Set the SceneDelegate dynamically
let sceneConfig: UISceneConfiguration = UISceneConfiguration(name: "mainWindow", sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = SceneDelegate.self
return sceneConfig
}
The intent is to move the SceneDelegate to the Presentation library.
When moved, the EntryPoint library fails to compile because it's referencing the SceneDelegate (as shown above).
To remove this reference, I tried to set up the SceneDelegate in the old way - In the info.plist file, mention a SceneConfiguration and set the SceneDelegate in Presentation.
// In the Info.plist file
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>Presentation.SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
// In the AppDelegate
public func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Refer to a static UISceneconfiguration listed in the info.plist file
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
As shown above, the Presentation.SceneDelegate is referred in the Info.plist file and the reference is removed from the AppDelegate (in EntryPoint library).
The app target compiles, but when I run it, the SceneDelegate is not invoked. None of the methods from the SceneDelegate (scene(_:willConnectTo:options:), sceneDidDisconnect(_:), sceneDidEnterBackground(_:) etc.) are invoked. I only get the AppDelegate logs.
It seems like the Configuration is ignored because it was incorrect. Any thoughts? Is it possible to move the SceneDelegate in this situation?
Hi,
A class initialized as the initial value of an @State property is not released until the whole View disappears. Every subsequent instance deinitializes properly.
Am I missing something, or is this a known issue?
struct ContentView: View {
// 1 - init first SimpleClass instance
@State var simpleClass: SimpleClass? = SimpleClass(name: "First")
var body: some View {
VStack {
Text("Hello, world!")
}
.task {
try? await Task.sleep(for: .seconds(2))
// 2 - init second SimpleClass instance and set as new @State
// "First" should deinit
simpleClass = SimpleClass(name: "Second")
// 3 - "Second" deinit just fine
simpleClass = nil
}
}
}
class SimpleClass {
let name: String
init(name: String) {
print("init: \(name)")
self.name = name
}
deinit {
print("deinit: \(name)")
}
}
output:
init: First
init: Second
deinit: Second
Thanks
I currently face an Issue where the SafeAreaInsets on the iPhone 16 Pro Max is not respected on LaunchScreens.
Lets say you have an ImageView whose leading, trailing and top are equal to the SafeAreaLayoutGuides leading, trailing and top.
Then you have a SwiftUI View such as the following representing the same layout in code:
GeometryReader { reader in
ZStack {
VStack(spacing: 0) {
Spacer(minLength: 0)
.frame(height: reader.safeAreaInsets.top)
Image(decorative: "splashLogo")
Spacer(minLength: 0)
}
.frame(width: reader.size.width)
}
.edgesIgnoringSafeArea(.all)
}
Both the storyboard preview as well as the SwiftUI preview show identical results in Xcode. Launching the app on the device however briefly shows the image below the Dynamic Island cutout until the app is launched to the SwiftUI view. Noticed this only happening on the iPhone 16 Pro Max.
Topic:
UI Frameworks
SubTopic:
General