I have a PDF which contains geocoordinates. I'm extracting out that image with the following code (this is for an iOS application):
guard let cgDocument = CGPDFDocument(overlay.pdfUrl as CFURL) else { return }
guard let cgPage = cgDocument.page(at: 1) else { return }
var boundingRect = self.rect(for: overlay.boundingMapRect)
let pdfPageRect = cgPage.getBoxRect(.mediaBox)
let renderer = UIGraphicsImageRenderer(size: pdfPageRect.size)
var img = renderer.image { ctx in
UIColor.white.set()
ctx.fill(pdfPageRect)
ctx.cgContext.translateBy(x: 0.0, y: pdfPageRect.size.height)
ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
ctx.cgContext.drawPDFPage(cgPage)
}
Once I have that image, I then need to adjust it to fit the specific coordinate corners. For that, I'm doing the following using a perspectiveTransform:
let ciImg = CIImage(image: img)!
let perspectiveTransformFilter = CIFilter.perspectiveTransform()
perspectiveTransformFilter.inputImage = ciImg
perspectiveTransformFilter.topRight = cartesianForPoint(point: ur, extent: boundingRect)
perspectiveTransformFilter.topLeft = cartesianForPoint(point: ul, extent: boundingRect)
perspectiveTransformFilter.bottomRight = cartesianForPoint(point: lr, extent: boundingRect)
perspectiveTransformFilter.bottomLeft = cartesianForPoint(point: ll, extent: boundingRect)
let txImg = perspectiveTransformFilter.outputImage!
img = UIImage(ciImage: txImg)
The original image is 792 x 612 (a landscape PDF) but the boundingRect covering the coordinates is 25625 x 20030. Obviously when I try to draw the image into that bounding box the app runs out of memory (25625 x 20030 x 4 is around 2GB of memory).
What I'm struggling with is - how do I correctly scale this image to fit into the bounding box even though the bounding box is, oh, 10x the resolution of the actual device? There's some key CoreGraphics thing I'm sure I'm missing 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
Here is a simple view to demonstrate the issue
struct ContentView: View {
@State private var isPresented = false
var body: some View {
VStack {
Button("Test") { isPresented = true }
}
.alert("Test", isPresented: $isPresented, actions: {
Button("Delete All", role: .destructive) {}
}, message: {
Text("Are You Sure?")
})
.padding()
}
}```
Which results in

The destructive button is almost unreadable. WCAG score is 1.4, far below the minimum recommended 4.5.
I found [this post](https://stackoverflow.com/q/66448869) on SO going back to Big Sur, but not on this forum.
Any known workarounds (except for building my own dialogs, which I am trying to avoid)?
Using confirmationDialog instead of alert does not make a difference.
I have an iOS Widget that also can load on the Mac when the Use iPhone Widgets setting is turned on on the Mac in Desktop & Dock.
I want to use a different url scheme to open video clips from the widget if it is being clicked on iOS or the Mac.
I tried using ProcessInfo.processInfo.isiOSAppOnMac but it always thinks it is on iOS.
I also tried looking for the user document path to see if it was /var/mobile/ or /Users/. but it always thinks it is /var/mobile.
I assume this is as it is not really a catalyst app but a WidgetKit extension from the phone.
Is there anyway I can figure out when the widget is running on the mac?
Thanks!
How does one know the fitting width of a UIDatePicker in a selector hooked up with UIControlEventValueChanged? By fitting width, I mean the width of the grey background rounded box displayed with the date -- I need to get the width of that whenever the date is changed.
A specific image fails to load properly using UIImageView on iOS 16 and later systems, but loads normally on iOS 15 and earlier versions. Similarly, on Mac computers, this image cannot be opened on MacOS 13 and later, whereas it opens without issue on MacOS 12 and earlier. I am curious about the reasons behind this differing behavior on both iPhone and Mac.
In Swift 6, stricter concurrency rules can lead to challenges when making SwiftUI views conform to Equatable. Specifically, the == operator required for Equatable must be nonisolated, which means it cannot access @MainActor-isolated properties. This creates an error when trying to compare views with such properties:
Error Example:
struct MyView: View, Equatable {
let title: String
let count: Int
static func ==(lhs: MyView, rhs: MyView) -> Bool {
// Accessing `title` here would trigger an error due to actor isolation.
return lhs.count == rhs.count
}
var body: some View {
Text(title)
}
}
Error Message:
Main actor-isolated operator function '==' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode.
Any suggestions?
Thanks
FB: FB15753655 (SwiftUI View cannot conform custom Equatable protocol in Swift 6.)
Hello,
While integrating the Liquid Glass UI introduced in iOS 26 into my existing app, I encountered an unexpected issue.
My app uses a UITabBarController, where each tab contains a UINavigationController,
and the actual content resides in each UIViewController.
Typically, I perform navigation using navigationController?.pushViewController(...) and hide the TabBar by setting vc.hidesBottomBarWhenPushed = true when needed.
This structure worked perfectly fine prior to iOS 26, and I believe many apps use a similar approach.
However, after enabling Liquid Glass UI, a problem occurs.
Problem Description
From AViewController, I push BViewController with hidesBottomBarWhenPushed = true.
BViewController appears, and the TabBar is hidden as expected.
When performing a swipe-back gesture, as soon as AViewController becomes visible, the TabBar immediately reappears (likely due to A’s viewWillAppear).
The TabBar remains visible for a short moment even if the gesture is canceled — during that time, it is also interactable.
Before iOS 26, the TabBar appeared synchronized with AViewController and did not prematurely show during the swipe transition.
Tried using the new iOS 18 API:
tabBarController?.setTabBarHidden(false, animated: true)
It slightly improves the animation behavior, but the issue persists.
If hidesBottomBarWhenPushed is now deprecated or discouraged,
migrating entirely to setTabBarHidden would require significant refactoring, which is not practical for many existing apps.
Is this caused by a misuse of hidesBottomBarWhenPushed,
or could this be a regression or design change in iOS 26’s Liquid Glass UI?
Sidebars for mac Catalyst apps running with UIDesignRequiresCompatibility flag render their active items with a white bg tint – resulting in labels and icons being not visible.
mac OS Tahoe 26.1 Beta 3 (25B5062e)
FB20765036
Example (Apple Developer App):
Hey there,
I have an app that allows picking any folder via UIDocumentPickerViewController. Up until iOS18 users were able to pick folders from connected servers (servers connected in the Files app) as well.
On iOS26, the picker allows for browsing into the connected servers, but the Select button is greyed out and does nothing when tapped.
Is this a known issue? This breaks the whole premise of my file syncronization application.
When I compiled my legacy project with Tahoe's macOS 26 SDK, NSRulerViews are showing a very different design:
Under prior macOS versions the horizontal and verrical ruler's background were blurring the content view, which was extending under the rulers, showing through their transparency.
With Tahoe the horizontal ruler is always reflecting the scrollview's background color, showing the blurred content view beneath.
And the vertical ruler is always completely transparent (without any blurring), showing the content together with the ruler's markers and ticks.
It's difficult to describe, I'll try to replicate this behavior with a minimal test project, and probably file a bug report / enhancement request.
But before I take next steps, can anyone confirm this observation? Maybe it is an intentional design decision by Apple?
In iPadOS 26, Apple introduced macOS-style window control buttons (close, minimize, fullscreen) for iPad apps running in a floating window. I'm working on a custom toolbar (UIView) positioned near the top of the window, and I'd like to avoid overlapping with these new controls.
However, I haven't found any public API that exposes the frame, layout margins, or safe area insets related to this new UI region. I've checked the window's safeAreaInsets, additionalSafeAreaInsets, and UIWindowSceneDelegate APIs, but none of them seem to reflect the area occupied by these buttons.
Is there an officially supported way to:
Get the layout information (frame, insets, or margins) of the window control buttons on iPadOS 26?
Or, is there a system-defined guideline or padding value we should use to avoid overlapping this new UI?
Any clarification or guidance would be appreciated!
Hi,
In the WWDC25 session Elevate an app with Swift concurrency (timestamps: 8:04 and later), the StickerViewModel is shown annotated with @Observable but not @MainActor. The narration mentions that updates happen on the main thread, but that guarantee is left implicit in the calling code.
In Swift 6, though, one of the major benefits is stronger compiler enforcement against data races and isolation rules. If a view model were also annotated with @MainActor, then the compiler could enforce that observable state is only updated on the main actor, preventing accidental background mutations or updates that can cause data races between nonisolated and main actor-isolated uses.
Since @Observable already signals that state changes are intended to be observed (and in practice, usually by views), it seems natural that such types should also be main-actor isolated. Otherwise, we’re left with an implicit expectation that updates will always come from the main thread, but without the compiler’s help in enforcing that rule.
This also ties into the concept of local reasoning that was emphasized in other Swift 6 talks (e.g. Beyond the basics of structured concurrency). With @MainActor, I can look at a view model and immediately know that all of its state is main-actor isolated. With only @Observable, that guarantee is left out, which feels like it weakens the clarity that Swift 6 is trying to promote.
Would it be considered a best practice in Swift 6 to use both @Observable and @MainActor for UI-facing view models? Or is the intention that SwiftUI developers should rely on calling context to ensure main-thread updates, even if that means the compiler cannot enforce isolation?
Thanks!
The following is verbatim of a feedback report (FB19809442) I submitted, shared here as someone else might be interested to see it (I hate the fact that we can't see each other's feedbacks).
On iOS 16, TextKit 2 calls NSTextLayoutFragment's draw(at:in:) method once for the first paragraph, but for every other paragraph, it calls it continuously on every scroll step in the UITextView. (The first paragraph is not cached; its draw is called again when it is about to be displayed again, but then it is again called only once per its lifecycle.)
On iOS 17, the behavior is similar; the draw method gets called once for the 1st and 2nd paragraph, and for every other paragraph it again gets called continuously as a user scrolls a UITextView.
On iOS 18 (and iOS 26 beta 4), TextKit 2 calls the layout fragment's draw(at:in:) on every scroll step in the UITextView, for all paragraphs. This results in terrible performance.
TextKit 2 is promised to bring many performance benefits by utilizing the viewport - a new concept that represents the visible area of a text view, along with a small overscroll. However, having the draw method being constantly called almost negates all the performance benefits that viewport brings. Imagine what could happen if someone needs to add just a bit of logic to that draw method. FPS drops significantly and UX is terribly degraded.
I tried optimizing this by only rendering those text line fragments which are in the viewport, by using NSTextViewportLayoutController.viewportBounds and converting NSTextLineFragment.typographicBounds to the viewport-relative coordinate space (i.e. the coordinate space of the UITextView itself). However, this patch only works on iOS 18 where the draw method is called too many times, as the viewport changes. (I may have some other problems in my implementation, but I gave up on improving those, as this can't work reliably on all OS versions since the underlying framework isn't calling the method consistently.)
Is this expected? What are our options for improving performance in these areas?
I have a List with draggable items. According to this thread (https://developer.apple.com/forums/thread/664469) I had to use .itemProvider instead of .onDrag, because otherwise the selection of the list will not work anymore.
The items in my list refer to a file URL. So the dragging allowed to copy the files to the destination of the drag & drop. Therefore I used this code
.itemProvider {
let url = ....... // get the url with an internal function
return NSItemProvider(object: url as NSURL)
}
Since the update to macOS 15.1 this way isn't working anymore. It just happens nothing.
I also tried to use
.itemProvider {
let url = ....
return NSItemProvider(contentsOf: url) ?? NSItemProvider(object: url as NSURL)
}
but this doesn't work too.
The same way with .onDrag works btw.
.onDrag {
let url = ....... // get the url with an internal function
return NSItemProvider(object: url as NSURL)
}
but as I wrote, this will break the possibility to select or to use the primaryAction of the .contextMenu.
Is this a bug? Or is my approach wrong and is there an alternative?
Hello,
I have a number of UIViewControllers that are presented as follows:
vc.modalPresentationStyle = UIModalPresentationStyle.popover
vc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
self.present(vc, animated: true, completion: nil)
The VC is designed from a Storyboard where I set the 'view' of the VC to have a .clear 'backgroundColor', I have a smaller 'Alert View' added as a subview which is what the user interacts with.
In iOS 13 - iOS 18 this would present modally, not take up the entire screen and allow the user to see relevant context from the screen underneath.
In iOS 26 Beta 5 and every beta prior the system injects a 'UIDropShadowView' in the View Hierarchy, this view has a solid color backdrop, either white/black depending on light/dark mode. This causes all underlying content to be blocked and essentially forces a full screen modal presentation despite the existing design.
I am looking for a way to remove this solid color. I'm not sure if it's intentional or a bug / oversight.
I have been able to remove it in a hacky way, I cycle the view hierarchy to find 'UIDropShadowView' and set it's backdrop to transparent. However when you swipe down to partially dismiss the view it turns to Liquid Glass when it is around 75% dismissed and then resets the background color to white/black.
I tried creating a custom UIViewControllerTransitioningDelegate so that I could re-implement the existing behaviour but it's incredibly difficult to mimic the partial dismiss swipe down effect on the VC.
I have also tried changing my presentation to:
vc.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
vc.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
This works but then the user loses the ability to interactively swipe to dismiss.
Any help would be appreciated. Thank you!
I am developing iOS App using SwiftUI and I notice that Myanmar font of number text on 18.4 have clipped on top and bottom. Does anyone have this issues and know the fix? I have provided the Screenshot also.
Hello Team,
We have Advanced App Clip Experiences live but we have add App Clip experience URL since long ago but status remains as Received and never changed to Published, can you please help us to fix this issue.
Please see attached.
Thanks
I'm implementing infinite scrolling with Swift Charts where additional historical data loads when scrolling near the beginning of the dataset. However, when new data is loaded, the chart's scroll position jumps unexpectedly.
Current behavior:
Initially loads 10 data points, displaying the latest 5
When scrolling backwards with only 3 points remaining off-screen, triggers loading of 10 more historical points
After loading, the scroll position jumps to the 3rd position of the new dataset instead of maintaining the current view
Expected behavior:
Scroll position should remain stable when new data is loaded
User's current view should not change during data loading
Here's my implementation logic using some mock data:
import SwiftUI
import Charts
struct DataPoint: Identifiable {
let id = UUID()
let date: Date
let value: Double
}
class ChartViewModel: ObservableObject {
@Published var dataPoints: [DataPoint] = []
private var isLoading = false
init() {
loadMoreData()
}
func loadMoreData() {
guard !isLoading else { return }
isLoading = true
let newData = self.generateDataPoints(
endDate: self.dataPoints.first?.date ?? Date(),
count: 10
)
self.dataPoints.insert(contentsOf: newData, at: 0)
self.isLoading = false
print("\(dataPoints.count) data points.")
}
private func generateDataPoints(endDate: Date, count: Int) -> [DataPoint] {
var points: [DataPoint] = []
let calendar = Calendar.current
for i in 0..<count {
let date = calendar.date(
byAdding: .day,
value: -i,
to: endDate
) ?? endDate
let value = Double.random(in: 0...100)
points.append(DataPoint(date: date, value: value))
}
return points.sorted { $0.date < $1.date }
}
}
struct ScrollableChart: View {
@StateObject private var viewModel = ChartViewModel()
@State private var scrollPosition: Date
@State private var scrollDebounceTask: Task<Void, Never>?
init() {
self.scrollPosition = .now.addingTimeInterval(-4*24*3600)
}
var body: some View {
Chart(viewModel.dataPoints) { point in
BarMark(
x: .value("Time", point.date, unit: .day),
y: .value("Value", point.value)
)
}
.chartScrollableAxes(.horizontal)
.chartXVisibleDomain(length: 5 * 24 * 3600)
.chartScrollPosition(x: $scrollPosition)
.chartXScale(domain: .automatic(includesZero: false))
.frame(height: 300)
.onChange(of: scrollPosition) { oldPosition, newPosition in
scrollDebounceTask?.cancel()
scrollDebounceTask = Task {
try? await Task.sleep(for: .milliseconds(300))
if !Task.isCancelled {
checkAndLoadMoreData(currentPosition: newPosition)
}
}
}
}
private func checkAndLoadMoreData(currentPosition: Date?) {
guard let currentPosition,
let earliestDataPoint = viewModel.dataPoints.first?.date else {
return
}
let timeInterval = currentPosition.timeIntervalSince(earliestDataPoint)
if timeInterval <= 3 * 24 * 3600 {
viewModel.loadMoreData()
}
}
}
I attempted to compensate for this jump by adding:
scrollPosition = scrollPosition.addingTimeInterval(10 * 24 * 3600)
after viewModel.loadMoreData(). However, this caused the chart to jump in the opposite direction by 10 days, rather than maintaining the current position.
What's the problem with my code and how to fix it?
The following WatchOs App example is very short, but already not functioning as it is expected, when using Digital Crown (full code):
import SwiftUI
struct ContentView: View {
let array = ["One","Two","Three","Four"]
@State var selection = "One"
var body: some View {
Picker("Array", selection: $selection) {
ForEach(array, id: \.self) {
Text($0)
}
}
}
}
The following 2 errors are thrown, when using Digital Crown for scrolling:
ScrollView contentOffset binding has been read; this will cause grossly inefficient view performance as the ScrollView's content will be updated whenever its contentOffset changes. Read the contentOffset binding in a view that is not parented between the creator of the binding and the ScrollView to avoid this.
Error: Error Domain=NSOSStatusErrorDomain Code=-536870187 "(null)"
Any help appreciated. Thanks a lot.
If I present "SFSafariViewController" when a "FamilyActivityPicker" is visible, it will automatically dismiss the "SFSafariViewController" and crash the "FamilyActivityPicker."
I'm assuming the cause of the bug is that each is in a separate process (aside from the app), and there's some hacks to try to stop "FamilyActivityPicker" from crashing, and this is causing the new bug because "SFSafariViewController" is also in a separate process.
(I'm not 100% if its just in 18.4 or iOS 18 overall...)
(I'll try to file a feedback soon, but its 100% reproducible for me across multiple devices on iOS 18.4)