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
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
Hi everyone,
I've come across an issue on iOS that seems to affect many apps. Here's what happens:
A user logs in with correct credentials and proceeds to the OTP verification screen as part of multi factor authentication.
iOS presents the system password save prompt ("Would you like to save this password?").
Without selecting an option on this prompt, the user backgrounds the app (e.g., to check their email for the OTP).
Upon returning to the app, the keyboard becomes completely inaccessible on the OTP screen or any other screen.
From my testing, this behavior appears to be an OS-level bug, as it occurs consistently across various apps. Has anyone else encountered this? Any known workarounds or updates from Apple on this behavior would be greatly appreciated!
Thanks!
Topic:
UI Frameworks
SubTopic:
UIKit
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 am working on a SwiftUI project where I need to dynamically update the UI by adding or removing components based on some event. The challenge is handling complex UI structures efficiently while ensuring smooth animations and state management.
Example Scenario:
I have a screen displaying a list of items.
When a user taps an item, additional details (like a subview or expanded section) should appear dynamically.
If the user taps again, the additional content should disappear.
The UI should animate these changes smoothly without causing unnecessary re-renders.
My Current Approach:
I have tried using @State and if conditions to toggle views, like this:
struct ContentView: View {
@State private var showDetails = false
var body: some View {
VStack {
Button("Toggle Details") {
showDetails.toggle()
}
if showDetails {
Text("Additional Information")
.transition(.slide) // Using animation
}
}
.animation(.easeInOut, value: showDetails)
}
}
However, in complex UI scenarios where multiple components need to be shown/hidden dynamically, this approach is not maintainable and could cause performance issues. I need help with the below questions.
Questions:
State Management: Should I use @State, @Binding, or @ObservedObject for handling dynamic UI updates efficiently?
Best Practices: What are the best practices for structuring SwiftUI views to handle dynamic updates without excessive re-renders?
Performance Optimization: How can I prevent unnecessary recomputations when updating only specific UI sections?
Animations & Transitions: What is the best way to apply animations smoothly while toggling visibility of multiple components?
Advanced Approaches: Are there better techniques using @EnvironmentObject, ViewBuilder, or even GeometryReader for dynamically adjusting UI layouts?
Any insights, code examples, or resources would be greatly appreciated.
We have SwiftUI AttributedString with links. But these links are inaccessible via automation scripts.
The text is visible to the automation scripts as XCUIElementTypeStaticText and there is no provision to access the links within.
Is there any workaround available for this case ?
Topic:
UI Frameworks
SubTopic:
SwiftUI
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
The pitch slider is not supported on tvOS yet it displays when using the Map() view. Does anyone know how to hide it? It's really getting in the way of my UI.
Topic:
UI Frameworks
SubTopic:
SwiftUI
macOS: 15.0
macFUSE: 4.8.3
I am using rclone + macFUSE and mount my netdisk where it has created three subdirectories in its root directory: /user, /share, and /group.
When I save a file to /[root]/user using NSSavePanel and name it test.txt, I expect the file to be saved as:
/[root]/user/test.txt
However, occasionally, the delegate method:
- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError {
}
returns an incorrect path:
/[root]/test.txt
This issue only occurs when selecting /user. The same operation works correctly for /share and /group.
Is there any logs I could provide to help solving this issue?
Many thanks!
Is it the default behavior that the standard back swipe (interactivePopGestureRecognizer) does not work when running a designed for iPhone app on an iPad?
To my knowledge, all apps behave this way.
Are there any workarounds?
As you can see in the screenshot, the verification popups that appear when making a StoreKit purchase cut off the buttons. When typing the code into the input field, the window will also flicker and stutter with random view refreshes. Is this something I can configure/change? It's not a very pleasant experience for making an in app purchase.
The SwiftUI Playground code below demonstrates that a .jpeg image can be read and written to the iOS file system. While, a.png image can only be read; the writing request appears to be ignored. Can anyone please tell me how to code to save a .png image using SwiftUI to the iOS file system.
Code:
import SwiftUI
import UniformTypeIdentifiers
/*
(Copied from Playground 'Help' menu popup.)
UIImage Summary
An object that manages image data in your app.
You use image objects to represent image data of all kinds, and the UIImage class is capable of managing data for all image formats supported by the underlying platform. Image objects are immutable, so you always create them from existing image data, such as an image file on disk or programmatically created image data. An image object may contain a single image or a sequence of images for use in an animation.
You can use image objects in several different ways:
Assign an image to a UIImageView object to display the image in your interface.
Use an image to customize system controls such as buttons, sliders, and segmented controls.
Draw an image directly into a view or other graphics context.
Pass an image to other APIs that might require image data.
Although image objects support all platform-native image formats, it’s recommended that you use PNG or JPEG files for most images in your app. Image objects are optimized for reading and displaying both formats, and those formats offer better performance than most other image formats. Because the PNG format is lossless, it’s especially recommended for the images you use in your app’s interface.
Declaration
class UIImage : NSObject
UIImage Class Reference
*/
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ImageFileDoc: FileDocument {
static var readableContentTypes = [UTType.jpeg, UTType.png]
static var writableContentTypes = [UTType.jpeg, UTType.png]
var someUIImage: UIImage = UIImage()
init(initialImage: UIImage = UIImage()) {
self.someUIImage = initialImage
}
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents,
let some = UIImage(data: data)
else {
throw CocoaError(.fileReadCorruptFile)
}
self.someUIImage = some
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
switch configuration.contentType {
case UTType.png:
if let data = self.someUIImage.pngData() {
return .init(regularFileWithContents: data)
}
case UTType.jpeg:
if let data = self.someUIImage.jpegData(compressionQuality: 1.0) {
return .init(regularFileWithContents: data)
}
default:
break
}
throw CocoaError(.fileWriteUnknown)
}
}
struct ContentView: View {
@State private var showingExporterPNG = false
@State private var showingExporterJPG = false
@State private var showingImporter = false
@State var message = "Hello, World!"
@State var document: ImageFileDoc = ImageFileDoc()
@State var documentExtension = ""
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text(message)
Button("export") {
if documentExtension == "png" {
message += ", showingExporterPNG is true."
showingExporterPNG = true
}
if documentExtension == "jpeg" {
message += ", showingExporterJPG is true."
showingExporterJPG = true
}
}
.padding(20)
.border(.white, width: 2.0)
.disabled(documentExtension == "")
Button("import") {
showingImporter = true
}
.padding(20)
.border(.white, width: 2.0)
Image(uiImage: document.someUIImage)
.resizable()
.padding()
.frame(width: 300, height: 300)
}
// exporter .png
.fileExporter(isPresented: $showingExporterPNG, document: document, contentType: UTType.png) { result in
switch result {
case .success(let url):
message += ", .\(documentExtension) Saved to \(url.lastPathComponent)"
case .failure(let error):
message += ", Some error saving file: " + error.localizedDescription
}
}
// exporter .jpeg
.fileExporter(isPresented: $showingExporterJPG, document: document, contentType: UTType.jpeg) { result in
switch result {
case .success(let url):
message += ", .\(documentExtension) Saved to \(url.lastPathComponent)"
case .failure(let error):
message += ", Some error saving file: " + error.localizedDescription
}
}
// importer
.fileImporter(isPresented: $showingImporter, allowedContentTypes: [.png, .jpeg]) { result in
switch result {
case .failure(let error):
message += ", Some error reading file: " + error.localizedDescription
case .success(let url):
let gotAccess = url.startAccessingSecurityScopedResource()
if !gotAccess {
message += ", Unable to Access \(url.lastPathComponent)"
return
}
documentExtension = url.pathExtension
guard let fileContents = try? Data(contentsOf: url)
else {
message += ",\n\nUnable to read file: \(url.lastPathComponent)\n\n"
url.stopAccessingSecurityScopedResource()
return
}
url.stopAccessingSecurityScopedResource()
message += ", Read file: \(url.lastPathComponent)"
message += ", path extension is '\(documentExtension)'."
if let uiImage = UIImage(data: fileContents) {
self.document.someUIImage = uiImage
}else{
message += ", File Content is not an Image."
}
}
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags:
Files and Storage
Developer Tools
iPad
Swift Playground
May I inquire about the differences between the two ways of view under the hood in SwiftUI?
class MyViewModel: ObservableObject {
@Published var state: Any
init(state: Any) {
self.state = state
}
}
struct MyView: View {
@StateObject var viewModel: MyViewModel
var body: some View {
// ...
}
}
struct CustomView: View {
let navigationPath: NavigationPath
@StateObject var viewModel: MyViewModel
var body: some View {
Button("Go to My View") {
navigationPath.append(makeMyView())
}
}
}
// Option 1: A viewModel is initialized outside view's initialization
func makeMyView(state: Any) -> some View {
let viewModel = MyViewModel(state: state)
MyView(viewModel: viewModel)
}
// Option 2: A viewModel is initialized inside view's initialization
func makeMyView(state: Any) -> some View {
MyView(viewModel: MyViewModel(state: state))
}
For option 1, the view model will be initialized whenever custom view is re-rendered by changes whereas the view model is only initialized once when the view is re-rendered for option 2.
So what happens here?
Hi all,
I am trying to allow users of my app to select extra options when opening documents, and to remember those options when re-opening documents at launch.
So far best idea I have is:
Subclass NSDocumentController to provide an NSOpenPanel.accessoryView with the options
Create a URL bookmark for each opened file and keep a mapping of bookmarks to options
On launch and when the recent documents list changes, prune the stored mappings to match only the recent items
Has anyone done this before, or know of a better approach?
Thank you.
Topic:
UI Frameworks
SubTopic:
AppKit
Hi,
I see some apps like LinkedIn that doesn't support multi view or split views on iPad, but seems this feature is enabled by default to any new project in Xcode, how to disable it ?
Kind Regards
Topic:
UI Frameworks
SubTopic:
General
I have a UITextView being added at runtime to a UIImageView as the result of doing text recognition. It's set to be editable = NO and selectable = YES. When I set the text and select it, it asks the delegate for the menu to display via:
textView:editMenuForTextInRange:suggestedActions:
The suggested items contains many UIAction and UICommand objects that have private methods or do not have the destructive attribute set, yet they are destructive. Some of these are:
promptForReplace:
transliterateChinese:
_insertDrawing:
_showTextFormattingOptions:
I need to return a menu that has only non-destructive commands in it.
First, why isn't UITextView sending only non-destructive suggested commands when its editable is NO?
Second, how can I filter the array of suggested commands when it's impossible to know if they're destructive (as some are missing that attribute)?
In addition to that, even non-destructive commands are causing an unrecognized selector exception, such as the Speak command, which it is sending to my view controller instead of to the UITextView, which is the only thing that knows what the text is that it should speak.
Topic:
UI Frameworks
SubTopic:
UIKit
Hi everyone,
I believe this should be a simple and expected default behavior in a real-world app, but I’m unable to make it work:
1. I have a View (a screen/page in this case) that calls an endpoint using async/await.
2. If the endpoint hasn’t finished, but I navigate forward to a DetailView, I want the endpoint to continue fetching data (i.e., inside the @StateObject ViewModel that the View owns). This way, when I go back, the View will have refreshed with the fetched data once it completes.
3. If the endpoint hasn’t finished and I navigate back to the previous screen, I want it to be canceled, and the @StateObject ViewModel should be deinitialized.
I can achieve 1 and 3 using the .task modifier, since it automatically cancels the asynchronous task when the view disappears:
view
.task { await vm.getData() }
I can achieve 1 and 2 using a structured Task in the View (or in the ViewModel, its the same behavior), for example:
.onFirstAppearOnly {
Task { away vm.getData() }
}
onFirstAppearOnly is a custom modifier that I have for calling onAppear only once in view lifecycle. Just to clarify, dont think that part is important for the purpose of the example
But the question is: How can I achieve all three behaviors? Is this really such an unusual requirement?
My minimum deployment target is iOS 15, and I’m using NavigationView + NavigationLink. However, I have also tried using NavigationStack + NavigationPath and still couldn’t get it to work.
Any help would be much appreciated.
Thank you, folks!
There are two issues about SFSafariViewController.
After rotate from landscape to portrait,
The topAnchor is destroyed.
The specified bar tint color and control tint color are invalidated.(Returns to system color)
Regarding the second issue, I’ve found a temporary workaround.
Override the viewWillTransition(to:with:) and keep it empty. Don't call super.viewWillTransition(to:with:).
Since UIKit is not open source, I don’t know the exact cause, but I found something that could be the key to the issue. So, I reported it to Apple Feedback Assistant. You can check the details and the sample project in the GitHub repository below.
https://github.com/ueunli/SafariViewer
Looking for sample code 3d wireframe (with lines ) & polygons and should be able to rotate (set camera angles)
I tried sample code seems to be complicated & getting a BLANK screen
import SwiftUI
import SceneKit
struct SceneKitTest2: View {
var body: some View {
VStack{
Text("SceneKitTest2")
SceneView(scene: SCNScene(named:"Earth_1_12756.scn"), options: [.autoenablesDefaultLighting,.allowsCameraControl])
.frame(width:UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height/2)
Spacer(minLength: 0)
}
}
}
Getting this error in iPhone Portrait Mode with notch.
Currrently using AVQueuePlayer to play more than 30 mp3 files one by one.
All constraint properties are correct but error occures only in Apple iPhone Portrait Mode with notch series. But same code works on same iPhone in Landscape mode.
**But I get this error: **
LoudnessManager.mm:709 unable to open stream for LoudnessManager plist
Type: Error | Timestamp: 2025-02-07 | Process: | Library: AudioToolbox | Subsystem: com.apple.coreaudio | Category: aqme | TID: 0x42754
LoudnessManager.mm:709 unable to open stream for LoudnessManager plist
LoudnessManager.mm:709 unable to open stream for LoudnessManager plist
Timestamp: 2025-02-07 | Library: AudioToolbox | Subsystem: com.apple.coreaudio | Category: aqme
As the title says, I am not sure how to properly build an inverted ScrollView where I can safely insert items above my data ("prepend") without everything jumping around.
My current code is essentially this:
@State private var scrollPosition = ScrollPosition(idType: Message.ID.self)
private func onMessageDidScrollIntoView(_ id: Message.ID) {
let indexOfVisibleMessage = /* ... */
if indexOfVisibleMessage < 10 {
fetchOlderMessages()
// ^ this updates my ViewModel `messages`
}
}
var body: some View {
ScrollView {
LazyVStack {
ForEach(messages) { message in
MessageCell(message)
}
}.scrollTargetLayout()
}
.defaultScrollAnchor(.bottom)
.scrollPosition($scrollPosition)
.onChange(of: scrollPosition) { oldValue, newValue in
guard let visibleMessageId = scrollPosition.viewID(type: Message.ID.self) else { return }
onMessageDidScrollIntoView(visibleMessageId)
}
}
..so if the user scrolls up to the oldest 10 messages, I start loading more and insert them at the top.
The problem with this is that the ScrollView now jumps when new messages are inserted. This is because the ScrollView maintains it's Y position, but the content size changes since we are adding new items "above".
I tried to play around with a few suggestions I found on StackOverflow, namely;
Inverting the ScrollView (.scaleEffect(y: -1) on the ScrollView and then again on the MessageCell to counter it): This somehow jumped the x position of the ScrollView and completely breaks .contextMenu.
Playing around with .onScrollGeometryChange to update scrollPosition.scrollTo(y:) when it's contentSize changes: This just didn't work and stopped the user scroll gesture/interaction.
Setting scrollPosition to the Message.ID I want to keep stable before doing an update: This didn't do anything.
But nothing actually worked for the reasons described above.
How do you actually build these UIs in SwiftUI? I think an inverted ScrollView is quite a common UI, and obviously data has to be loaded lazily.