Let's say you have a protocol that can work with both classes and structs but you want to have a uniform UI to make edits.
What is the recommended way to have one view that will take both?
App
import SwiftUI
@main
struct ObservationTesterApp: App {
var body: some Scene {
WindowGroup {
ContentView(existence: Existence())
}
}
}
Types
import Foundation
protocol Dateable {
var timestamp:Date { get set }
}
struct Arrival:Dateable {
var timestamp:Date
}
@Observable
class Existence:Dateable {
var timestamp:Date
init(timestamp: Date) {
self.timestamp = timestamp
}
}
extension Existence {
convenience init() {
self.init(timestamp: Date())
}
}
ContentView, etc
//
// ContentView.swift
// ObservationTester
//
//
import SwiftUI
struct EditDateableView<TimedThing:Dateable>:View {
@Binding var timed:TimedThing
//note that this currently JUST a date picker
//but it's possible the protocol would have more
var body:some View {
DatePicker("Time To Change", selection: $timed.timestamp)
}
}
#Preview {
@Previewable @State var tt = Arrival(timestamp: Date())
EditDateableView<Arrival>(timed: $tt)
}
struct ContentView: View {
@State var arrival = Arrival(timestamp: Date())
@Bindable var existence:Existence
var body: some View {
//this work around also not allowed. "self is immutable"
// let existBinding = Binding<Existence>(get: { existence }, set: { existence = $0 })
VStack {
EditDateableView(timed: $arrival)
//a Binding cant take a Bindable
//EditDateableView<Existence>(timed: $existence)
}
.padding()
}
}
#Preview {
ContentView(existence: Existence())
}
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 think it can be dismissed with dismiss() onInAppPurchaseCompletion action handler but I have no reason to handle it, and if it's not handled it will show error alerts for you (see documentation).
How can I dismiss it and still benefit from default onInAppPurchaseCompletion action?
Thanks,
Subject: SwiftUI Gesture Conflict in iOS 18: Simultaneous Recognition of Drag and Tap Gestures
Description:
In SwiftUI on iOS 18 and above, we've identified an issue with gesture handling that affects user experience. When implementing .simultaneousGesture(DragGesture()), the system incorrectly recognizes and processes both drag and tap gestures concurrently, resulting in unintended behavior.
Technical Details:
Environment: SwiftUI, iOS 18+
Issue: Simultaneous recognition of horizontal drag gestures and vertical scroll/tap gestures
Current Behavior: Both vertical and horizontal scrolling occur simultaneously when using .simultaneousGesture(DragGesture())
Expected Behavior: Gestures should be properly disambiguated to prevent concurrent scrolling in multiple directions
Impact:
This behavior significantly impacts user experience, particularly in custom carousel implementations and other UI components that rely on precise gesture handling. The simultaneous recognition of both gestures creates a confusing and unpredictable interaction pattern.
Steps to Reproduce:
Create a SwiftUI view with horizontal scrolling (e.g., custom carousel)
Implement .simultaneousGesture(DragGesture())
Add tap gesture recognition to child views
Run on iOS 18
Attempt to scroll horizontally
Observed Result:
Both horizontal dragging and vertical scrolling/tapping are recognized and processed simultaneously, creating an inconsistent user experience.
Expected Result:
The system should properly disambiguate between horizontal drag gestures and vertical scroll/tap gestures, allowing only one type of gesture to be recognized at a time based on the user's intent.
Please let me know if you need any additional information or reproduction steps.
When attempting to replicate the tvOS Settings menu layout, where the screen is divided horizontally into two sections, placing a NavigationStack or a Form view on either side of the screen causes focusable views (such as Button, TextField, Toggle, etc.) to be visually clipped when they receive focus and apply the default scaling animation.
Specifically:
If the Form or NavigationStack is placed on the right side, the left edge of the focused view gets clipped.
If placed on the left side, the right edge of the focused view gets clipped.
This issue affects any focusable child view inside the Form or NavigationStack when focus scaling is triggered.
Example code:
struct TVAppMenuMainView: View {
var body: some View {
VStack {
Text("Settings Menu")
.font(.title)
HStack {
VStack {
Text("Left Pane")
}
.frame(width: UIScreen.main.bounds.width * 0.4) // represents only 40% of the screen
.frame(maxHeight: .infinity)
.padding(.bottom)
Divider()
NavigationStack {
Form { // All the buttons will get cut on the left side when each button is focused
Button("First Button"){}
Button("Second Button"){}
Button("Third Button"){}
Button("Forth Button"){}
}
}
}
.frame(maxHeight: .infinity)
.frame(maxWidth: .infinity)
}
.background(.ultraThickMaterial)
}
}
How it looks:
What I have tried:
.clipped modifiers
.ignoresSafeArea
Modifying the size manually
Using just a ScrollView with VStack works as intended, but as soon as NavigationStack or Form are added, the buttons get clipped.
This was tested on the latest 18.5 tvOS BETA
为什么App 上传testFlight之后。无法通过NFC的方式唤醒 APP Clips。是必须要上架商店之后才能支持么?
The behavior of the Button in ScrollView differs depending on how the View is displayed modally.
When the View is displayed as a .fullScreenCover, if the button is touched and scrolled without releasing the finger, the touch event is canceled and the action of the Button is not called.
On the other hand, if the View is displayed as a .sheet, the touch event is not canceled even if the view is scrolled without lifting the finger, and the action is called when the finger is released.
In order to prevent accidental interaction, I feel that the behavior of .fullScreenCover is better, as it cancels the event immediately when scrolling. Can I change the behavior of .sheet?
Demo movie is here:
https://x.com/kenmaz/status/1896498312737611891
Sample code
import SwiftUI
@main
struct SampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State private var showSheet = false
@State private var showFullScreen = false
var body: some View {
VStack(spacing: 16) {
Button("Sheet") {
showSheet.toggle()
}
Button("Full screen") {
showFullScreen.toggle()
}
}
.sheet(isPresented: $showSheet) {
SecondView()
}
.fullScreenCover(isPresented: $showFullScreen) {
SecondView()
}
.font(.title)
}
}
struct SecondView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
ScrollView {
Button("Dismiss") {
dismiss()
}
.buttonStyle(MyButtonStyle())
.padding(.top, 128)
.font(.title)
}
}
}
private struct MyButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.foregroundStyle(.red)
.background(configuration.isPressed ? .gray : .clear)
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Im student, hobbyst on developing.
i have a problem inserting a custom slidee PNG to control volume of an áudio file in an app. The slidee built in Swift, runs ok. When i try to use a custom png it show in the Gui but when move its button right it disappear beyond the maximum but when i move ir left the minimamente is at middle of the slider scale
Topic:
UI Frameworks
SubTopic:
SwiftUI
on iOS you can choose to scale to view to have the app resize the screen easily in the developer environment. Scale to view is however not easily done on MacOS using NS to solve on MacOS now. Is it possible for the Apple developer team to make this easier for the Developer, as I understand it is for iOS applications?
Hi,
Is there any way of changing the contentInset (UIKit variant) of a List in SwiftUI?
I do not see any APIs for doing so, the closest I gotten is to use safeAreaInset . While visually that works the UX is broken as you can no longer "scroll" from the gap made by the .safeAreaInset(edge:alignment:spacing:content:)
I have subbmited a feedback suggestion: FB16866956
In order to make referencing keys for localized strings a little more reliable, our application references generated constants for localized string keys:
This eliminates the potential for developers to misspell a key when referencing a localized strings. And because these constants are automatically generated by the exact same process that provides localized strings for the application, each and every constant is guaranteed to have a localized string associated with it.
I’m currently attempting to implement something similar for the localized strings referenced by our new App Intents. Our initial release of App Intent functionality is simply using string literals to reference localized strings:
However, I am running into several issues when trying to reference the string keys as a constant. The closest I managed to get was defining the constant as either a LocalizationValue or as a StaticString and referencing the constant while initializing the LocalizedStringResource. With this approach, I see no errors from Xcode until I try and compile. What’s more is that the wording of the error being thrown is quite peculiar:
As you can see with the sample code above, I am clearly calling LocalizedStringResource’s initializer directly as Indicated by the error.
Is what I’m trying to do even possible with App Intents? From my research, it does look like iOS app localization is moving more towards using string literals for localized strings. Like with String Catalog’s ability to automatically generate entries from strings referenced in UI without the need for a key. However, we’d prefer to use constants if possible for the reasons listed above.
Hi, I'm working on RealityView and I have two entities in RCP. In order to set views for both entities, I have to create two separate attachments for each entity. What I want to achieve is that when I hover (by eye) on one entity's attachment, it would trigger the hover effect of the other entity's attachment. I try to use the hoverEffectGroup, but it would only activate the hover effect in a subview, instead a complete separate view. I refer to the following WWDC instruction for the hover effect.
https://developer.apple.com/videos/play/wwdc2024/10152/
@Observable seems not to work well with generic typed throw.
The following code using @Observable with non-generic typed throw builds good:
@Observable
class ThrowsLoadingViewModel<R, E: Error> {
private(set) var isLoading = true
private(set) var error: E? = nil
private(set) var data: R? = nil
private var task: () throws(Error) -> R
init(task: @escaping () throws(E) -> R) {
self.task = task
}
func load() {
do throws(Error) {
self.data = try task()
} catch {
// self.error = error
}
self.isLoading = false
}
}
But if I change Line 7 and 14 to generic, it'll breaks the build with a "Command SwiftCompile failed with a nonzero exit code" message :
@Observable
class ThrowsLoadingViewModel<R, E: Error> {
private(set) var isLoading = true
private(set) var error: E? = nil
private(set) var data: R? = nil
private var task: () throws(E) -> R
init(task: @escaping () throws(E) -> R) {
self.task = task
}
func load() {
do throws(E) {
self.data = try task()
} catch {
// self.error = error
}
self.isLoading = false
}
}
A the same time, if I remove @Observable, the generic typed throw works again:
class ThrowsLoadingViewModel<R, E: Error> {
private(set) var isLoading = true
private(set) var error: E? = nil
private(set) var data: R? = nil
private var task: () throws(E) -> R
init(task: @escaping () throws(E) -> R) {
self.task = task
}
func load() {
do throws(E) {
self.data = try task()
} catch {
// self.error = error
}
self.isLoading = false
}
}
Currently the possible solution seems to fall back to use ObservableObject...
Hello,
I was wondering if someone could clear-up my thinking here.
e.g. consider the code below...
It has a rootView with a navlink to a childView which in turn has navlinks to GrandchildViews.
The root view uses basic navLInks NavigationLink{View} label: {View}
The child view uses type-based navLinks navigationLink(value:) {View} and .navigationDestination(for:) {View}
I would expect the basic navlinks to work in the root view and the type-based ones to work in the child view. However it appears that both are active when one taps on a link in the child view.
e.g. User actions:
Start -> RootView is only view on the stack -> (tap on ‘Child View’) -> ChildView is top of the stack -> tap on ‘Alice’ -> a second ChildView is top of the stack with a GrandchildView underneath….
Why does this happen, why are the basic links also applied to the childView's links?
Thanks.
struct Thing: Identifiable, Hashable {
let id = UUID()
let name: String
}
struct RootView: View {
var body: some View {
NavigationStack {
List {
NavigationLink {
ChildView()
} label: {
Label("Child View", systemImage: "figure.and.child.holdinghands")
}
NavigationLink {
Text("Hello")
} label: {
Label("Another navLink item in the list", systemImage: "circle")
}
}
.padding()
}
}
}
struct ChildView: View {
private var things = [
Thing(name: "Alice"),
Thing(name: "Bob"),
Thing(name: "Charlie"),
]
var body: some View {
Text("This is the child view")
List {
ForEach(things) { thing in
NavigationLink(value: thing) {
Text(thing.name)
}
}
}
.navigationTitle("Child View")
.navigationDestination(for: Thing.self) { thing in
GrandchildView(thing: thing)
}
}
}
struct GrandchildView: View {
let thing: Thing
var body: some View {
Text("This is the GrandchildView: \(thing.name)")
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
My app is designed to share and import images with apps such as the File app. I created a program after looking at various information, but the app from which the images are shared does not work, and the screen cannot be moved to the main screen of my app. The program is as follows. How should I modify it?
import UIKit
import MobileCoreServices
import UniformTypeIdentifiers
class ShareViewController: UIViewController {
let suiteName: String = "group.com.valida.pettyGeneral"
let keyString: String = "share-general"
override func viewDidLoad() {
var nameArray: [String] = [String]()
let sharedDefaults: UserDefaults = UserDefaults(suiteName: self.suiteName)!
guard let inputItem = self.extensionContext?.inputItems.first as? NSExtensionItem, let attachments = inputItem.attachments else {
return
}
let identifier = UTType.image.identifier
let imgAttachments = attachments.filter { $0.hasItemConformingToTypeIdentifier(identifier) }
let dispatchGroup = DispatchGroup()
for (no, itemProvider) in imgAttachments.enumerated() {
dispatchGroup.enter()
itemProvider.loadItem(forTypeIdentifier: identifier, options: nil) { [self] item, error in
do {
if let error = error {
throw error
} else if let url = item as? URL {
let data = try Data(contentsOf: url)
let fileManager = FileManager.default
let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: suiteName)
if let url = url?.appendingPathComponent(String(no)) {
try! data.write(to: url)
}
nameArray.append(String(no))
}
do { dispatchGroup.leave() }
} catch {
print("Error")
do { dispatchGroup.leave() }
}
}
}
dispatchGroup.notify(queue: .main) { [self] in
// 全ての画像を保存
sharedDefaults.set(nameArray, forKey: self.keyString)
sharedDefaults.synchronize()
// メニュー画面に移動する
openUrl(url: URL(string: "container-general://"))
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
}
//#selector(openURL(_:))はこの関数がないと作れない
@objc func open(_ url: URL) {}
func openUrl(url: URL?) {
let selector = #selector(open(_ : ))
var responder = (self as UIResponder).next
while let r = responder, !r.responds(to: selector) {
responder = r.next
}
_ = responder?.perform(selector, with: url)
}
func openContainerApp() {
let url = URL(string: "container-general://") // カスタムスキームを作って指定する
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
let selector = sel_registerName("openURL:")
application.perform(selector, with: url)
break
}
responder = responder?.next
}
}
}
In keyboard shortcuts this buttons at the bottom are overlappin.
Any one
else?
Topic:
UI Frameworks
SubTopic:
General
When my CPMapButton is selected/focused, I would like to be able to provide a focusedImage to correctly show the button when the blue focus is shown. Currently I have:
What do I need to do to create an image that works more like the panning interface buttons?
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.
Hi Apple Developer Team,
In my tvOS app built with SwiftUI, I have a tab-based interface with several sections. The first tab (index 0) is the Home tab. Other tabs include Contact, WiFi, Welcome, etc.
I want to handle the remote's Menu / Back button (.onExitCommand) so that:
If the user is on any tab other than Home (tabs 1, 2, 3, etc.), pressing the Menu button takes them back to the Home tab.
If the user is already on the Home tab, then pressing the TV/Home button (not Menu) behaves as expected — suspending or exiting the app (handled by the system, no code involved).
Here's a simplified version of what I implemented:
.onExitCommand {
if selectedTab != 0 {
selectedTab = 0
focusedTab = 0
} else {
// Let system handle the exit when user presses the TV/Home button
}
}
This behavior ensures users don’t accidentally exit the app when they're browsing other tabs, and provides a consistent navigation experience.
Question:
Is this an acceptable and App Store-compliant use of .onExitCommand on tvOS?
I'm not calling exit(0) or trying to force-terminate the app — just using .onExitCommand for in-app navigation purposes.
Any official guidance or best practices would be greatly appreciated!
Thanks,
Prashant
Hi all,
We're working on an iOS application and would like to improve our ability to diagnose failures - especially in scenarios where the app crashes before it can present any UI to the user.
A few specific questions:
In case of an exception or crash, is there a way to log the issue so the user (or our support team) can understand the cause of the failure?
If the app crashes abruptly (e.g., due to a runtime exception or crash during launch), is there a recommended way to persist error information before the process terminates?
Are there Apple-supported mechanisms (like crash reporting tools or APIs) we can integrate that would help us capture such issues?
What’s the best practice for enabling support teams to assist users based on crash reports - especially for crashes that happen before any user interaction?
Our goal is to make sure users aren't left in the dark if the app fails to start, and to allow us to deliver timely updates or support based on the cause of the crash.
Thanks in advance for your guidance!
Hello I'm currently building a feature within an ios app using SwiftUI and Mapkit to record the gps cordinates of a user as they move and render the track on the map. the idea is not really to have a "track" but to have a visual representation of the area the user sees while they are moving around. I need this width/breadth to be relative to the map and not the screen, such that when I zoom in and out of the map, the size will adjust automatically.