Hello I was wondering if this is expected behavior or if there is a way I can fix this to get the behavior I am expecting. I have a Form that has many sections in it and when the content of the section is selected I would like that section to be scrolled to the top to make it easier for the user to know that they selected that section. But when the Section is selected, it is anchored to the top of the form but the header of the Section is cut off. When the Section is anchored to the top I would like the whole section to be seen (the header, content, and footer).
I also tried applying an ID to the section and using that to scroll to and that also didn't work.
Any help would be appreciated.
Here is some code to repo this:
struct ContentView: View {
@State private var selectionSectionContent: SectionContent?
var body: some View {
ScrollViewReader { proxy in
Form {
ForEach(contents, id: \.self) { content in
Section {
Text(content.text)
.onTapGesture {
selectionSectionContent = content
}
} header: {
Text("Header")
} footer: {
Text("Footer")
}
}
}
.onChange(of: selectionSectionContent) { _, newValue in
if let newValue {
// When text is tapped, scroll that section to the top.
withAnimation { proxy.scrollTo(newValue, anchor: .top) }
}
}
.padding()
}
}
let contents: [SectionContent] = [
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent(),
SectionContent()
]
}
class SectionContent: Hashable {
let text = "Fun Section"
public var id: ObjectIdentifier {
ObjectIdentifier(self)
}
static func == (lhs: SectionContent, rhs: SectionContent) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
Here is a GIF of the header getting cut off when it is pinned to the top.
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
Im creating a chat using uiTableView. The response is send as streaming so I need to reload last cell até every response update. However when I do reload row and scroll to bottom, the content of the last cell seems to be drag to the bottom instead of looking as a regular scroll.
I used to be able to display all app icon assets in the UI using UIImage(named: String)
However, it seems this method has been deprecated in Xcode 16 and the iOS 18.
How can I display app icon assets in the UI now, without duplicating the assets?
Hi team. I am working on an app that uses the Screen Time API. I got access to the family controls (distribution) capability through the request process for my main app. I added a DeviceActivityReport extension in XCode, but haven't been able to get the extension to show up on the screen. I noticed that the extension only has the development version of the family controls capability available. Is this the source of my errors? I was able to get the screen time displayed in a test app I built where both the main app and extension used the development version of the capability, which led me to believe that discrepancy could be the issue.
Let me know if there is anything I can provide to help in the debugging process. I didn't send a minimal example in this request due to the fact that I would have to remove most of my functionality to create a "minimal" example (since the signing is only for my main app), but I can do that if needed. Thanks! I looked through the logs in the console for the phone (I'm testing on a real iPhone 13 Pro Max), but didn't see anything that popped out after looking (not exactly sure what to look for though).
STEPS TO REPRODUCE:
Create an app with the Family Controls, Distribution capability. Then create the DeviceActivityReport with the Family Control, Development capability. Attempt to see the DeviceActivityReport in the main app.
NOTE: I was successfully able to create a minimal test app completely separately that used the Development versions of the capabilities for both with the exact same extension code. That's why I think the issue could be due to the capability version discrepancy.
not sure where to post this hence adding here.
how to run in this full screen mode even when the screen is locked. As far as I looked, it’s only live activities that the developers are made available with. Is there a way to create our own UI on lockscreen, given a similar usecase exists?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags:
Inter-process communication
WidgetKit
App Intents
ActivityKit
Hi, we are developing a cross-platform library for creating desktop applications in C++: https://github.com/aseprite/laf
For this reason, in macOS, we cannot rely on the default NSApplication.run() event loop, so we decided to implement our custom event loop using the nextEventMatchingMask method.
Then, when a window is in fullscreen mode, for some reason the window stops receiving mouseMove events when the mouse pointer enters an area at the top of the window.
You can see this issue in action by trying the following example project:
https://github.com/martincapello/custom-event-loop-issue
This project just opens one window and uses a custom event loop, it displays the current mouse position at every mouseMove event received, and when the aforementioned area is entered it suddenly stops updating.
There is also a video showing how to reproduce it.
I was able to see that when the position stops updating, we still receive mouseMove events, but for a different window, a borderless window that is added to the NSApplication.windows collection when switching to fullscreen, and which seems to be taken the mouseMove events before reaching the main window.
Also, this issue doesn't happen when using the default NSApplication.run method, despite the borderless windows being added as well.
I had write a widget after iOS 17+, It had a Toggle to perform a appintent .
When switch the toggle, the appintent will perfrom , just like
`
func perfrom() async throws -> some IntentResult {
// first
let first = try await getFristValue()
let second = try await getSecondValue(by: first)
let third = try awiat getThirdValue(by: second)
return .result()
}
`
and I found, it will work when I am debugging connect with Xcode.
But, when I don't connect xcode, it will not work.
How can I fixed it ?
The Problem
I am trying to implement a pinch-to-zoom feature on images within a UIPageViewController. However, often times when trying to pinch to zoom, the magnification gesture gets overridden by the scrolling gesture built into the UIPageViewController. I'm not sure how to get around this. The Apple Photos app seems to allow pinch to zoom on photos inside a full-page scrolling view without any issue, so I believe it should be possible.
Versions: iOS 17.2.1 - iOS 18.2.1, Swift (SwiftUI), Xcode 15.1
Steps to Reproduce
Run this sample Xcode project on a physical device: https://drive.google.com/file/d/1tB1QyY6QPEp-WLzdHxgDdkM45xCAELLr/view?usp=share_link
Try pinching to zoom on the image. After a few goes at it, you'll likely find that one time it will scroll instead of pinching to zoom. It might take up to a dozen pinches to experience this issue.
What I've Tried
Making the magnification gesture a high priority gesture.
Having only one page in the paging view controller.
Subclassing UIScrollView and conforming to the UIGestureRecognizerDelegate in that subclass, as explained here: https://stackoverflow.com/a/51070947/12218938
Using the iOS 17 ScrollView instead. Unfortunately it has the same issue but even worse! It's possible that since this is a native SwiftUI view, people might have solutions to this, but from a brief search I couldn't find any.
If you set the data source to nil (which indicates that there are no other pages for the paging view controller to scroll to), it does work, but it's not a workable solution since the time you'd want to set the data source to nil is when the user pinches the screen, but you can't know when the user pinches the screen if the gesture doesn't work!
Other Ideas/Workarounds
We could have some "zoom" mode that temporarily cancels the ability to scroll while zooming. But this seems like not too nice/intuitive of a solution.
If there is no paging view that Apple provides which could be made compatible with a pinch-to-zoom gesture, it's possible we would have to make a completely custom paging view. But that would be a lot of work I presume, so it's probably not something we would have time for right now.
I have a swiftui view with Button(intent: ) and using UIHostingViewcontroller to use it in UIKit. The problem is that button not works in uikit but normal button(without intent works)
Xcode 16.2
Swift 6
macOS Sequoia 15.1
SwiftUI
I am a beginner.
If I understand we can add buttons to the default Menu Bar but not delete them. Am I right? If you do not need most of the buttons, how do you solve that?
I can add a button:
import SwiftUI
@main
struct NouMenuProvesApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.commands {
CommandMenu("Custom") {
Button("Custom Action") {
print("Custom Action performed")
}
}
}
}
}
Can I delete a Menu Button or create a new simpler Menu Bar?
We have recently added WidgetKit widgets to an existing product, and they've been working great on Macs using Big Sur and later. Recently, when installing a build on a Montery Mac, the widgets were no longer in Notification Center. After some trial and error, we discovered that if we build the project with Xcode 15.4, the widgets appear, but if we build with Xcode 16, the widgets vanish. This seems to happen on Macs running Big Sur or Monterey. The project is being built on Macs running Sonoma (both Apple Silicon and Intel).
Is there a build setting in Xcode 16 that may have this effect?
Hi,
This issue started with iOS 18, in iOS 17 it worked correctly. I think there was a change in SectionedFetchRequest so maybe I missed it but it did work in iOS 17.
I have a List that uses SectionedFetchRequest to show entries from CoreData. The setup is like this:
struct ManageBooksView: View {
@SectionedFetchRequest<Int16, MyBooks>(
sectionIdentifier: \.groupType,
sortDescriptors: [SortDescriptor(\.groupType), SortDescriptor(\.name)]
)
private var books: SectionedFetchResults<Int16, MyBooks>
var body: some View {
NavigationStack {
List {
ForEach(books) { section in
Section(header: Text(section.id)) {
ForEach(section) { book in
NavigationLink {
EditView(book: book)
} label: {
Text(book.name)
}
}
}
}
}
.listStyle(.insetGrouped)
}
}
}
struct EditView: View {
private var book: MyBooks
init(book: MyBooks) {
print("Init hit")
self.book = book
}
}
Test 1: So now when I change name of the Book entity inside the EditView and do save on the view context and go back, the custom EditView is correctly hit again.
Test 2: If I do the same changes on a different attribute of the Book entity the custom init of EditView is not hit and it is stuck with the initial result from SectionedFetchResults.
I also noticed that if I remove SortDescriptor(\.name) from the sortDescriptors and do Test 1, it not longer works even for name, so it looks like the only "observed" change is on the attributes inside sortDescriptors.
Any suggestions will be helpful, thank you.
Hi everyone.
I'm trying to use the new ControlWidget API introduced on iOS 18 to open a sheet that contains a form when the user taps on the button on the control center.
This is my current code. It opens the app, but I haven't found how to do an action inside the app when the app is opened.
@available(iOS 18, *)
struct AddButtonWidgetControl: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: "com.example.myapp.ButtonWidget") {
ControlWidgetButton(action: LaunchAppIntent()) {
Label("Add a link", systemImage: "plus")
}
}
.displayName("Add a link")
.description("Creates a link.")
}
}
@available(iOS 18, *)
struct LaunchAppIntent: AppIntent {
static var title: LocalizedStringResource { "Launch app" }
static var openAppWhenRun: Bool = true
func perform() async throws -> some IntentResult {
return .result()
}
}
Hi
I am drawing TextKit2 managed NSAttributedStrings into a NSBitmapImageRep successfully, enumerating the Text Layout Fragments is giving me bogus background drawing
This is the core drawing code, its pretty simple: I manage the flipped property myself since NSTextLayoutManager assumes a flipped coordinate.
if let context = NSGraphicsContext(bitmapImageRep: self.textImageRep!)
{
NSGraphicsContext.current = context
let rect = NSRect(origin: .zero, size: self.outputSize)
NSColor.clear.set()
rect.fill()
// Flip the context
context.cgContext.saveGState()
context.cgContext.translateBy(x: 0, y: self.outputSize.height)
context.cgContext.scaleBy(x: 1.0, y: -1.0)
let textOrigin = CGPoint(x: 0.0, y: 0.0 )
let titleRect = CGRect(origin: textOrigin, size: self.themeTextContainer.size)
NSColor.orange.withAlphaComponent(1).set()
titleRect.fill()
self.layoutManager.enumerateTextLayoutFragments(from: nil, using: { textLayoutFragment in
// Get the fragment's rendering bounds
let fragmentBounds = textLayoutFragment.layoutFragmentFrame
print("fragmentBounds: \(fragmentBounds)")
// Render the fragment into the context
textLayoutFragment.draw(at: fragmentBounds.origin, in: context.cgContext)
return true
})
context.cgContext.restoreGState()
}
NSGraphicsContext.restoreGraphicsState()
I have a mutable string which has various paragraph styles which I add to the layout manager / text storage like so
let titleParagraphStyle = NSMutableParagraphStyle()
titleParagraphStyle.alignment = .center
titleParagraphStyle.lineBreakMode = .byWordWrapping
titleParagraphStyle.lineBreakStrategy = .standard
var range = NSMakeRange(0, self.attributedProgrammingBlockTitle.length)
self.attributedProgrammingBlockTitle.addAttribute(.foregroundColor, value: NSColor(red: 243.0/255.0, green: 97.0/255.0, blue: 97.0/255.0, alpha: 1.0), range:range)
self.attributedProgrammingBlockTitle.addAttribute(.backgroundColor, value: NSColor.cyan, range:range)
self.attributedProgrammingBlockTitle.addAttribute(.font, value: NSFont.systemFont(ofSize: 64), range:range)
self.attributedProgrammingBlockTitle.addAttribute(.paragraphStyle, value:titleParagraphStyle, range:range)
range = NSMakeRange(0, self.attributedThemeTitle.length)
self.attributedThemeTitle.addAttribute(.foregroundColor, value: NSColor.white, range:range )
self.attributedThemeTitle.addAttribute(.backgroundColor, value: NSColor.purple, range:range)
self.attributedThemeTitle.addAttribute(.font, value: NSFont.systemFont(ofSize: 48), range:range)
self.attributedThemeTitle.addAttribute(.paragraphStyle, value:NSParagraphStyle.default, range:range)
range = NSMakeRange(0, self.attributedText.length)
self.attributedText.addAttribute(.foregroundColor, value: NSColor.white, range:range )
self.attributedText.addAttribute(.backgroundColor, value: NSColor.yellow, range:range)
self.attributedText.addAttribute(.font, value: NSFont.systemFont(ofSize: 36), range:range)
self.attributedText.addAttribute(.paragraphStyle, value:NSParagraphStyle.default, range:range)
let allText = NSMutableAttributedString()
allText.append(self.attributedProgrammingBlockTitle)
allText.append(NSAttributedString(string: "\n\r"))
allText.append(self.attributedThemeTitle)
allText.append(NSAttributedString(string: "\n\r"))
allText.append(self.attributedText)
self.textStorage.textStorage?.beginEditing()
self.textStorage.textStorage?.setAttributedString(allText)
self.textStorage.textStorage?.endEditing()
self.layoutManager.ensureLayout(for: self.layoutManager.documentRange)
however, i get incorrect drawing for the background color font attributes. Its origin is zero, and not correctly aligned at all with the text.
How can I get correct rendering of backgrounds from TextKit2?
Here is an image of my output:
Hi,
After running the Xcode template "New project > (SwiftUI, SwiftData)" I noticed that there is no insert animation into the list.
The project is a pure vanilla project created from Xcode (Version 16.2 (16C5032a)) and the code is a simple as it gets:
//
// ContentView.swift
//
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
var body: some View {
NavigationSplitView {
List {
ForEach(items) { item in
NavigationLink {
Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
} label: {
Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
}
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
} detail: {
Text("Select an item")
}
}
private func addItem() {
withAnimation {
let newItem = Item(timestamp: Date())
modelContext.insert(newItem)
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(items[index])
}
}
}
}
#Preview {
ContentView()
.modelContainer(for: Item.self, inMemory: true)
}
As you see the template's code does have withAnimation inside addItem but there is no animation. The new added item appears without animation in the the List
Here is a short video. Is this a known bug?
Hello Dear Developers,
Is it only to me or in iOS 18 there's a problem with Settings.bundle, Im using my settings.bundle to set my enivement for my app but after upgrading to iOS 18 I can't see my Settings.Bundle in my settings iphone,
just to mention that I also updated my xcode to 16.
Anyone who has occur with this problem? :)
Hello everyone,
I’m encountering a problem on the latest iOS 18 related to location permissions. When the user denies location access, my app triggers the standard system prompt asking them to enable location from Settings. On iOS 17 and below, tapping the “Settings” button in this system alert would successfully navigate the user to my app’s Settings page. However, on iOS 18, nothing happens. Instead, I see the following warning in the Xcode console:
Warning :
BUG IN CLIENT OF UIKIT: The caller of UIApplication.openURL(:) needs to migrate
to the non-deprecated UIApplication.open(:options:completionHandler:).
Force returning false (NO).
Important details and context:
In my own code, I have already replaced all calls to openURL(:) with open(:options:completionHandler:).
I searched the entire codebase for usage of openURL: and didn’t find any.
The alert that appears is the system location alert (iOS-generated), not a custom UIAlertController. Thus, I have no direct control over the underlying call.
On iOS 17 (and below), tapping “Settings” in the same system dialog works perfectly and takes the user to the app’s permission page.
The console message implies that somewhere—likely inside the system’s own flow—the deprecated API is being called and blocked on iOS 18.
What I’ve tried:
Verified I am not calling openURL: anywhere in my code.
Confirmed that UIApplication.openSettingsURLString works when I programmatically open it in a custom alert.
Tested multiple times on iOS 17 and iOS 18 to confirm the behavior difference.
Steps to reproduce:
Install the app on a device running iOS 18 Beta.
Deny location permission when prompted.
Trigger a piece of code that relies on location (e.g., loading a map screen) so that the OS automatically shows its standard “Location is disabled” alert, which includes a “Settings” button.
Tap “Settings.” On iOS 17, this navigates to the app’s Settings. On iOS 18 Beta, it does nothing, and the console logs the BUG IN CLIENT OF UIKIT warning.
Questions:
Is this a known iOS 18 bug where the system’s own alert is still using the deprecated openURL: call?
If so, are there any workarounds besides presenting a custom alert that manually calls open(_:options:completionHandler:)?
Thank you in advance. Any guidance or confirmation would be appreciated!
I am not able to use SwiftUI Preview
Here is the report I get while trying to see the issue:
Here is the report of the issue:
And here is the call and code preview:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
Please update.
I'm working on a SwiftUI based application for MacOS. I have a TabView component with two child Tab components. These Tab components display a List, each derived from an array of elements.
While the application is running, clicking on the tabs in the TabView should switch between the views of different Lists. What I'm experiencing is that switching between the tabs causes a FAULT. With errors:
Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000>
Followed by:
(
0 CoreFoundation 0x000000019e096e80 __exceptionPreprocess + 176
1 libobjc.A.dylib 0x000000019db7ecd8 objc_exception_throw + 88
2 AppKit 0x00000001a1c744e8 -[NSTableRowData _availableRowViewWhileUpdatingAtRow:] + 0
3 SwiftUI 0x00000001cd8953f4 $s7SwiftUI0A17UIOutlineListViewC11removeItems2at8inParent13withAnimationy10Foundation8IndexSetV_ypSgSo07NSTableeL7OptionsVtF + 1232
...
...
)
And finally:
FAULT: NSTableViewException: Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000>; (user info absent)
This error happens when switching between the two tabs, defined thusly:
@main
struct MyApp: App {
@State var rootDirectory: URL
@State var selectedItem: URL
@State var projectNavItems: [NavigationItem] = []
@State var jotNavItems: [NavigationItem] = []
@State var importerIsPresented: Bool = false
let fileManager = FileManager.default
init() {
rootDirectory = URL(string: FileManager.default.currentDirectoryPath)!
selectedItem = URL(string: FileManager.default.currentDirectoryPath)!.appendingPathComponent("README.md")
}
var body: some Scene {
WindowGroup {
NavigationSplitView {
TabView {
Tab("Projects", systemImage: "tray.and.arrow.down.fill") {
List(projectNavItems, selection: $selectedItem) {
// Changing this NavigationLink line to Text($0.title) makes no difference
NavigationLink($0.title, value: $0.id)
}
}
Tab("Jots", systemImage: "tray.and.arrow.up.fill") {
List(jotNavItems, selection: $selectedJot) {
// Can be written as Text($0.title) with no change in behavior
NavigationLink($0.title, value: $0.id)
}
}
}
} detail: {
Editor(for: selectedItem)
}
.fileImporter(
isPresented: $importerIsPresented,
allowedContentTypes: [UTType.folder],
allowsMultipleSelection: false
) { result in
// Code that gets a security scoped resource and populates the
// projectNavItems: [NavItem] and jotNavItems: [NavItem]
// arrays
}
}
.commands(content: {
CommandGroup (before: .newItem) {
Button("Open Journal...") {
importerIsPresented.toggle()
}
}
})
}
}
The error only happens when both Tab views are populated by a List. If the Tab view have different child components, say a List, and a ForEach of Text components, switching between the tabs doesn't produce this error. List views with Text child components also produce this error.
Here are screenshots of the running application
Once the user selects a directory, we see the first Tab > List component populated by contents from the projectNavItems array:
Clicking on the 'Jots' tab switches to the appropriate tab and correctly lists the items in the jotNavItems array, except there are additional lines, seemingly showing that there's an issue.
Clicking back on the 'Projects' tab switches back, but now the List shows only one of the items from the projectNavItems array.
Finally, clicking on 'Jots' again causes the errors to print in the console and interactivity with the tab components ceases. Last screenshot is representative of this state as the application FAULTS.
This seems like a bug in SwifUI, wondering what workarounds I might be able to implement.
I can provide the full backtrace, I cropped it for content length.
I have a calculator app with lots of buttons. Some of the buttons change appearance when pressed. Others do not. Some of those that do not change the state of a display text field and others do not. The display change is that the button goes white when pressed. I have no explicit code to make a change in appearance in any of the buttons. The display consists of a TextField followed by 4 rows of 6 buttons followed by 4 rows of 6 buttons. What is the explanation for this behavior.
Topic:
UI Frameworks
SubTopic:
SwiftUI