In a macOS Swift app I'm trying to get mouse events to not coalesce. This used to work in an Obj-C app by calling [NSEvent setMouseCoalescingEnabled:NO]. setMouseCoalescingEnabled is not exposed in the Swift version of NSEvent. I built a bridge over to a .mm file that calls [NSEvent setMouseCoalescingEnabled:NO] and checked NSEvent.isMouseCoalescingEnabled in Swift after calling and it returns false saying that coalescing is disabled. The mouse is still skipping points (func mouseDragged(with theEvent: NSEvent)) when it is dragged across the window fast. I'm calling [NSEvent setMouseCoalescingEnabled:NO] in applicationDidFinishLaunching().
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.
Post
Replies
Boosts
Views
Activity
Given a sheet with [.medium] detents, that contains a native ColorPicker in SwiftUI:
struct SheetView: View {
@State var color: Color = .white
var body: some View {
ColorPicker(
"Color",
selection: $color,
supportsOpacity: false
)
.padding()
}
}
struct ContentView: View {
@State var isSheetOpen = false
var body: some View {
Button("Open Sheet") {
isSheetOpen = true
}
.sheet(isPresented: $isSheetOpen) {
SheetView()
.presentationDetents([.medium])
}
}
}
When I tap the ColorPicker's color indicator button, it presents the color picker sheet with a layout glitch.
During the color picker presentation animation, the original sheet (SheetView) is rapidly pushed up and back down.
It is a wild guess but I think it has to do something with keyboard avoidance.
Unfortunately, this makes it impossible to use the picker in my app....
Currently I came across an issue in mac catalyst project. All the buttons in my project are not visible, they are in their actual positions and also clickable and performing their tasks as assigned but they are not visible.
When Iam doing:
crossButton.setImage(UIImage(named: "CrossComMac"), for: .normal)
Button does not contain image
While in the below code, image is visible but Iam not able to resize it.
crossButton.imageView?.image = UIImage(named: "CrossComMac")
Also title of the button is not visible too.
Anything related to button in my mac catalyst project is not visible.
Main issue:
Button's image is visible in Xcode running project
Button's image is not visible in build project...(funny thing right)
I have a use case in which there is a zoomable and pannable parent view, and a child view that needs to display a custom context menu on long press.
(The reason why I need to implement a custom context menu is this: https://developer.apple.com/forums/thread/773810)
It seems, however, that this setup produces a bug in SwiftUI. The problem is that the onChanged of the drag gesture is only invoked right before its onEnded, hence you cannot smoothly animate the drag:
struct ContentView: View {
var body: some View {
ZStack {
Rectangle()
.foregroundStyle(.green)
.frame(width: 200, height: 200)
.onLongPressGesture {
print("long press")
}
}
.gesture(MagnifyGesture().onEnded { value in
print("magnify end")
})
.gesture(DragGesture()
.onChanged { value in
print("drag change")
}
.onEnded { value in
print("drag end")
})
}
}
Changing the DragGesture to a .highPriorityGesture() makes the drag's onChange execute at the correct time but results in the LongPressGesture only triggering when the user lifts up his/her finger (which was originally not the case).
So it seems that the two gestures are in a sort of conflict with each other.
Is there a workaround?
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
In UIKit, it's quite common for table views to have one (or sometimes more) rows whose editing style is "insert", which show up a button with a plus symbol on a green background to the left of the cell content, and tapping this button adds whatever is in the cell content (usually a text field) to the list.
What's the procedure for creating a list row like this in Swift UI when in edit mode?
can't see what the problem is .. Im getting the error:
Type '()' cannot conform to 'View'
struct CalendarView: View {
@StateObject private var viewModel = CalendarViewModel()
@State private var selectedDate: CalendarDate?
@State private var showModal = false
var body: some View {
VStack {
Text("Calendar App")
.font(.largeTitle)
.padding()
GridStack(rows: 5, columns: 7) { row, col in
let index = row * 7 + col
if index < viewModel.calendarDates.count {
let calendarDate = viewModel.calendarDates[index]
Text("\(Calendar.current.component(.day, from: calendarDate.date))")
.frame(width: 40, height: 40)
.background(calendarDate.isSelected ? Color.blue : Color.clear)
.cornerRadius(10)
.foregroundColor(calendarDate.isSelected ? Color.white : Color.black)
.onLongPressGesture {
selectedDate = calendarDate
showModal = true
}
}
}
}
.background(Color.gray)
.sheet(isPresented: $showModal) {
if let date = selectedDate {
DateSelectionModal(selectedDate: date)
}
}
}
}
struct GridStack<Content: View>: View {
let rows: Int
let columns: Int
let content: (Int, Int) -> Content
var body: some View {
VStack {
ForEach(0..<rows) { row in
HStack {
ForEach(0..<columns) { column in
content(row, column)
}
}
}
}
}
}
#Preview {
CalendarView()
}
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.
I am on Xcode 16.2 and running a simulator for iOS 18.2. Previously, I was on Xcode 15.x and running iOS 17.4 sims. This problem did not occur for me on iOS 17.4. Sample code is as follows:
import SwiftUI
import PhotosUI
struct ContentView: View {
@StateObject var imagePicker2 = ImagePicker()
var body: some View {
ScrollView {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
.background(Color.orange)
.padding(.bottom, 75)
PhotosPicker(selection: $imagePicker2.imageSelection, matching: .images, photoLibrary: .shared()) {
Label("", systemImage: "photo")
}
.font(.system(size: 55))
.padding(.bottom, 55)
if let image = imagePicker2.image {
HStack {
image
.resizable()
.frame(width:75, height:75)
.scaledToFit()
.overlay(Rectangle().stroke(Color.teal, lineWidth: 2))
}
}
}
.padding()
}
}
}
import SwiftUI
import PhotosUI
@MainActor
class ImagePicker: ObservableObject {
@Published var unableToLoad: Bool = false
@Published var image: Image?
@Published var myUIImage: UIImage?
@Published var imageSelection: PhotosPickerItem? {
didSet {
unableToLoad = false
if let imageSelection {
//.. try to convert photosPickerItem imageSelection into a uiImage
Task {
try await setImage(from: imageSelection)
}
}
}
}
func setImage(from imageSelection: PhotosPickerItem?) async throws {
do {
if let data = try await imageSelection?.loadTransferable(type: Data.self) {
print("got image data")
if let uiImage = UIImage(data: data) {
print("converted to uiImage")
self.image = Image(uiImage: uiImage)
self.myUIImage = uiImage
}
}
} catch {
print(error.localizedDescription)
unableToLoad = true
}
}
}
The image loads on the UI but I get "[ERROR] Could not create a bookmark: NSError: Cocoa 4097 "connection to service named com.apple.FileProvider" in the log every time I choose a new photo. So far, I haven't had an actual crash but others have indicated that depending on what they're doing code-wise, that some have crashed. Is this an iOS 18.x bug? Thoughts?
I'm writing an app to help with astrophotography, and I need to perform a contrast stretch to the image, because it was taken with a specialized astrophotography camera in monochrome and most of the data is very dark.
Most astrophotography software (astropy, Pixinsight) has something called an autostretch, which is a form of contrast stretching. I would like to do the same thing in my iOS app, using the tools available to me in SwiftUI, UIImage, CIImage, and CGImage.
I am to the point that I have created a buffer .withUnsafeMutableBufferPointer that contains the image data as 16-bit unsigned integers (the format given to me by the camera). I then create a vImage_Buffer using:
var buffer = vImage_Buffer(data: outPtr.baseAddress, height: vImagePixelCount(imageHeight), width: vImagePixelCount(imageWidth), rowBytes: MemoryLayout<Float>.size * imageWidth)
... and now I would like to apply either an equalizeHistogram() or a contrastStretch() to the buffer. What do I need to do? Do I need to create a CGImageFormat, like this?
let cgiImageFormat = vImage_CGImageFormat(bitsPerComponent: 16, bitsPerPixel: 16, colorSpace: CGColorSpaceCreateDeviceGray(), bitmapInfo: bitmapInfo)!
Which function should I use to do the equalization or contrast stretch? There appears to be a vImageContrastStretch_PlanarF() function, but I'm not sure the input data will be in the proper format (is a monochrome CGImage 32-bit planar F?), and I certainly don't know how to setup the histogram_entries parameter for that function. It seems like the function could just scan the image itself, form the histogram, and then stretch it, right?
So a code example would help a lot!
Thanks in advance,
Robert
I work on an iOS app using SwiftUI and SwiftData. I added a computed property to one of my models - Parent - that uses relationship - array of Child models - data and I started getting strange problems. Let me start with models:
@Model
final class Parent {
var name: String
@Relationship(deleteRule: .cascade, inverse: \Child.parent)
var children: [Child]? = []
var streak: Int {
// Yes, I know that's not optimal solution for such counter ;)
guard let children = children?.sorted(using: SortDescriptor(\.date, order: .reverse)) else { return 0 }
var date = Date.now
let calendar = Calendar.current
for (index, child) in children.enumerated() {
if !calendar.isDate(child.date, inSameDayAs: date) {
return index
}
date = calendar.date(byAdding: .day, value: -1, to: date) ?? .now
}
return children.count
}
init(name: String) {
self.name = name
}
}
@Model
final class Child {
var date: Date
@Relationship(deleteRule: .nullify)
var parent: Parent?
init(date: Date, parent: Parent) {
self.date = date
self.parent = parent
}
}
At first everything works as expected. The problem arises once I try to remove one of child from the parent instance. I remove the value from context and save changes without any problems, at least not ones that can be caught by do { } catch. But instead of refreshing UI I get an signal SIGABRT somewhere inside SwiftData internals that points to the line where I'm trying (inside View body) get a child from a Query:
struct LastSevenDaysButtons: View {
@Environment(\.modelContext)
private var modelContext
@Query
private var children: [Child]
private let dates: [Date]
private let parent: Parent
init(for parent: Parent) {
self.parent = parent
var lastSevenDays = [Date]()
let calendar = Calendar.current
let firstDate = calendar.date(byAdding: .day, value: -6, to: calendar.startOfDay(for: .now)) ?? .now
var date = firstDate
while date <= .now {
lastSevenDays.append(date)
date = calendar.date(byAdding: .day, value: 1, to: date) ?? .now
}
dates = lastSevenDays
let parentId = parent.persistentModelID
_children = Query(
filter: #Predicate {
$0.parent?.persistentModelID == parentId && $0.date >= firstDate
},
sort: [SortDescriptor(\Child.date, order: .reverse)],
animation: .default
)
}
var body: some View {
VStack {
HStack(alignment: .top) {
ForEach(dates, id: \.self) { date in
// Here is the last point on stack from my code that I see
let child = children.first { $0.date == date }
Button {
if let child {
modelContext.delete(child)
} else {
modelContext.insert(Child(date: date, parent: parent))
}
do {
try modelContext.save()
} catch {
print("Can't save changes for \(parent.name) on \(date.formatted(date: .abbreviated, time: .omitted)): \(error.localizedDescription)")
}
} label: {
Text("\(date.formatted(date: .abbreviated, time: .omitted))")
.foregroundStyle(child == nil ? .red : .blue)
}
}
}
}
}
}
The LastSevenDaysButtons View is kind of deep in a View hierarchy:
RootView -> ParentList -> ParentListItem -> LastSevenDaysButtons
However once I move insides of ParentList to RootView application works just fine, although I see and warning: === AttributeGraph: cycle detected through attribute 6912 ===.
What could be that I do wrong in here? I believe it must something I'm missing here, but after 2 days of debug, trial and errors, I can't think clearly anymore.
Here is the minimal repro I managed to create: Signal SIGABRT on accessing values from SwiftData query
Hi
I am developing an app for counting money. One view is for entering the intended destinations specified by a donor. Each destination has a row with a TextField that has an OnChange to keep it all numeric. The model that holds the data is a class called AllocationItems, which I recently changed from having the protocol ObservableObject to having the macro @Observable.
It mostly works the same, except that before with each key stroke the total would be updated, but now with the macro it only gets updated when I exit the current TextField by clicking on another TextField
How do I get it to update the total with each keystroke?
The code that shows the total is this:
Text(allocations.totalAllocated.fmtCurrency)
where allocations is an instance of AllocationItems
with this definition:
var totalAllocated: NSDecimalNumber { items.reduce(.zero) { $0 + $1.amountValue } }
I hope someone knows why this has changed and can suggest a simple fix.
I tried to create a Text View using attributedString. I want to set the line height using paragraphStyle and return the Text, but paragraphStyle is not being applied. Why is that?
extension Text {
init?(_ content: String, font: StyleType, color: Color = .ppBlack) {
var attributedString = AttributedString(content)
attributedString.font = Font.custom(font.fontWeight, fixedSize: font.fontSize)
attributedString.foregroundColor = color
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = 16
paragraphStyle.maximumLineHeight = 16
paragraphStyle.lineSpacing = 0
attributedString.mergeAttributes(.init([.paragraphStyle: paragraphStyle]))
self = Text(attributedString)
}
}
In Xcode 16.0 and 16.1, it was clear how @Entry macro works from the generated code. If you explicitly specify the type, then defaultValue is a computed property, if you do not specify the type, then a stored property.
In Xcode 16.2, @__EntryDefaultValue has been added to the generated code, which Xcode does not want to expand. Visually, it seems that a stored property is generated, but the behavior shows that as a result we have a computed property, and for both options: with an explicit type and without an explicit type.
So the question is: what does this @__EntryDefaultValue macro generate and is the result a bug? Or was it a bug in previous versions of Xcode?
Our app presents an NSOpenPanel with an accessory view implemented in SwiftUI and presented via NSHostingView. TextFields and pickers are working OK, but Buttons and Toggles (checkboxes) aren’t, although Toggles styled with .switch are functioning as expected. Specifically:
Toggles styled with .checkbox fail with no feedback. Overriding NSHostingView mouseDown() shows that the mouse event is completely ignored by the Toggle
Buttons “see” the mouseDown event (the button highlights when pressed, and the event doesn’t fall through to the hosting view), but the button action isn’t triggered until the dialog is dismissed
Any idea on how to get these controls functional?
Hi everyone! I'm thrilled to share that I'm conducting a field research as part of my final university project, focused on iOS architecture.
The goal is to dive deeper into the best practices, challenges, and trends in the iOS development world. To make this research truly impactful, I need your help!
If you're an iOS developer, I’d love it if you could take a few minutes to answer a short survey. Your insights and experiences will be invaluable for my research, and I greatly appreciate your
support!
Here is the link:
https://docs.google.com/forms/d/e/1FAIpQLSdf9cacfA7my1hnlazyl7uJraa2oTsQ7dJBWvFtZ_4vbYenRA/viewform?usp=send_form
Thank you so much in advance for helping me out—feel free to share this post with others who might also be interested. Let’s build something amazing together! 💡✨
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?
When I created a search box on the homepage, I was able to enter text in the input field while previewing in Xcode. However, after clicking "Build" and running the app, I couldn't type anything into the input field in the demo interface. Additionally, I received the following error message:
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.
How can I fix this issue?
Here is my ContentView.swift code:
import SwiftUI
struct ContentView: View {
@State private var searchText: String = ""
@State private var isSearching: Bool = false
var body: some View {
NavigationStack {
GeometryReader { geometry in
VStack {
Spacer()
.frame(height: geometry.size.height.isNaN ? 0 : geometry.size.height * 0.3)
VStack(spacing: 20) {
Text("NMFC CODES LOOKUP")
.font(.title2)
.bold()
TextField("Search...", text: $searchText)
.textFieldStyle(PlainTextFieldStyle())
.padding(10)
.frame(height: 40)
.frame(width: geometry.size.width.isNaN ? 0 : geometry.size.width * 0.9)
.background(Color.white)
.cornerRadius(8)
.overlay(
HStack {
Spacer()
if !searchText.isEmpty {
Button(action: {
searchText = ""
}) {
Image(systemName: "xmark.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
}
)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.gray.opacity(0.5), lineWidth: 1)
)
Button(action: {
isSearching = true
}) {
Text("Search")
.foregroundColor(.white)
.frame(width: geometry.size.width * 0.9, height: 40)
.background(Color.blue)
.cornerRadius(8)
}
.disabled(searchText.isEmpty)
Text("Created & Designed & Developed By Matt")
.font(.caption)
.foregroundColor(.gray)
.padding(.top, 10)
}
Spacer()
.frame(height: geometry.size.height * 0.7)
}
.frame(width: geometry.size.width)
}
.background(Color(red: 250/255, green: 245/255, blue: 240/255))
.navigationDestination(isPresented: $isSearching) {
SearchResultsView(searchQuery: searchText)
}
}
.background(Color(red: 250/255, green: 245/255, blue: 240/255))
.ignoresSafeArea()
}
}
#Preview {
ContentView()
}
Hello!
I'm trying to set a UiRefreshControl.tintColor:
.onAppear {
UIRefreshControl.appearance().tintColor = UIColor.systemBlue
}
But instead of
I get
The color in the second picture is a high contrast version of the first one. I can't understand why it works this way.
I also tried the following.
UIRefreshControl.appearance().tintColor = UIColor(red: 0, green: 0.478, blue: 1, alpha: 1) // doesn't work
UIRefreshControl.appearance().tintColor = UIColor(named: "RefreshControlColor") // doesn't work, here set "High contrast" on and indicated Universal.systemBlueColor
Perhaps I missed something?
Hello,
I implemented offerCodeRedemption recently on my app in my subscription/onboarding flow. When I did, it broke my camera functionality (elsewhere in the app; totally unrelated code).
I was able to fix the issue when implementing the old "AppStore.presentOfferCodeRedeemSheet" code with UIKit. I'm not sure why this is happening, but it seemed like a bug to me.