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.

All subtopics

Post

Replies

Boosts

Views

Activity

How to resolve SwiftUI.DynamicProperty on MainActor compiler warning on 6.0?
Hi! I'm running into a warning from a SwiftUI.DynamicProperty on a 6.0 development build (swift-6.0-DEVELOPMENT-SNAPSHOT-2024-03-26-a). I am attempting to build a type (conforming to DynamicProperty) that should also be MainActor. This type with also need a custom update function. Here is a simple custom wrapper (handwaving over the orthogonal missing pieces) that shows the warning: import SwiftUI @MainActor struct MainProperty: DynamicProperty { // Main actor-isolated instance method 'update()' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode @MainActor func update() { } } Is there anything I can do about that warning? Does the warning correctly imply that this will be a legit compiler error when 6.0 ships? I can find (at least) two examples of types adopting DynamicProperty from Apple that are also MainActor: FetchRequest and SectionedFetchRequest. What is confusing is that both FetchRequest^1 and SectionedFetchRequest^2 explicitly declare their update method to be MainActor. Is there anything missing from my Wrapper declaration that can get me what I'm looking for? Any more advice about that? Thanks!
4
0
747
Apr ’24
NO ANIMATIONS in NavigationStack or NavigationSplitView
I'm building a macOS app using SwiftUI and I recently updated to xcode 14.3. Since then I've been debugging why none of my animations were working, it turned out that the NavigationSplitView or NavigationStack are somehow interfering with all the animations from withAnimation to .transition() and everything in between. Is anyone else experiencing this, knows a work around or knows why this is happening?
11
9
7.1k
Apr ’23
Control gallery preview bug
Environment: Xcode16, iOS 18.1 official version Background: I created a control center widget using a custom sf symbol Phenomenon: When I first installed it, it displayed normally in the control gallery, but when I recompiled and installed it again, the icon disappeared when I looked at it again in the control gallery. I used Console to check the error log and found that its output was' No image named 'my_custom _symbol_name' found in asset catalog for/private/var/containers/Bundle/Application/F977FCFB-DA1C-4924-8613-50531CA2A364/MyDemoApp. app/PlugIns/MyDemoApp Extension. apex '. I found that this uuid was not consistent with the uuid I print during debugging, as if the control gallery had done some kind of caching; Additionally, when I added my Control to the Control Center, it was able to display normally, and the only issue was with the Control Gallery Attempted method: -Using the system SF Symbol, it works fine and can be displayed normally in the control gallery after recompilation. However, once I switch another SF Symbols, the icons in the control gallery do not update after recompilation and installation -Restarting the device, the same issue still persists Is this a system bug or did I make a mistake? Looking forward to someone helping, thank you My Code: @available(iOSApplicationExtension 18.0, *) struct MySearchControlWidget: ControlWidget { let kind = "MySearchControlWidget" let title = "My Title" var body: some ControlWidgetConfiguration { let intent = MyCommonButtonControlWidgetIntent() StaticControlConfiguration(kind: kind) { ControlWidgetButton(action: intent) { Label("\(title)", image:"my_custom_symbol_name") } } .displayName("\(title)") } }
1
0
98
1w
Use @AppStorage with Arrays
Hey, I know you can write @AppStorage("username") var username: String = "Anonymous" to access a Value, stored In the User Defaults, and you can also overwrite him by changing the value of username. I was wondering if there is any workaround to use @AppStorage with Arrays. Because I don't find anything, but I have a lot of situations where I would use it. Thanks! Max
1
1
881
Dec ’21
I want to report a Apple bug in call recording feature during facetime audio call
I am using iphone 11 with ios version 18.1 and I found one issue in call recording during FT audio call. Call gets dropped as soon as call recording start. This bug is also reproducible on iphone 14 pro max having same ios version. I tried it 5/5 times and it is 100% reproducible. Can you please help to fix this issue. This is really a serious quality concern as per apple standards.
2
0
112
1w
App was crashing in xcode 16 due to Quicklook UI framework
QLPreviewView was used in the app to display the file previews. But the following crash was happening. Date/Time: 2024-09-13 22:03:59.056 +0530 OS Version: Mac OS X 10.13.6 (17G14042) Report Version: 12 Anonymous UUID: 7CA3750A-2BDD-3FFF-5940-E5EEAE2E55F5 Time Awake Since Boot: 4300 seconds System Integrity Protection: disabled Notes: Translocated Process Crashed Thread: 0 Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Termination Reason: DYLD, [0x1] Library missing Application Specific Information: dyld: launch, loading dependent libraries Dyld Error Message: Library not loaded: /System/Library/Frameworks/QuickLookUI.framework/Versions/A/QuickLookUI Referenced from: /private/var/folders/*/Notebook (Beta).app/Contents/MacOS/Notebook (Beta) Reason: image not found
24
4
2.3k
Sep ’24
HStack required to get columns in a Grid
I've looked at lots of Grid examples. I've seen it documented that views within a GridRow are treated as if they were in an HStack. That's not happening for me. I have to explicitly put them into an HStack or they are treated as new rows. Here's my code: @State private var gridRows : Int = 4 @State private var gridCols : Int = 2 @State private var myItems : [Int] = Array(0...8) var body: some View { Group { if myItems.count > 0 { ScrollView([.vertical]) { Grid(alignment: .leading) { ForEach(0..<gridRows, id: \.self) { rowNdx in GridRow { HStack // <<--- { ForEach(0..<gridCols, id: \.self) { colNdx in Text("\(rowNdx) \(colNdx)") } } } } } } } } } With the HStack I get (as expected). 0 0 0 1 1 0 1 1 2 0 2 1 3 0 3 1 Without the HStack I get 0 0 0 1 1 0 1 1 ... What have I done wrong?
2
0
130
1w
Calendar integers in english and alphabets in arabic
we are migrating our app to support Arabic language support but the requirement is we want the calendar/date object to display as missed. That is all the numbers in english digits and rest all the words like days, months should be in Arabic. I tried few options but at the end its resulting everything is in Arabic or in English but not the mixed as expected. Attaching the expected behavior.
2
0
198
2w
`NavigationStack` when presented by sheet is forced to be reevaluated when app is in background
Development environment: Xcode 16.1, macOS 15.1 (24B83) OS version: iOS iOS 17.5 and above When NavigationStack is presented by a sheet, and navigationDestination API is being used for navigation within the stack, the sheet content is forced to be reevaluated when app is in background. Sample Project import SwiftUI struct TestView: View { var id: Int @State private var isLoading = false @State private var presentSheet = false var body: some View { let _ = Self._printChanges() VStack { if isLoading { ProgressView() } else { VStack { Text("View: \(id)") Text("Not loading") Button("Present Sheet in NavStack") { presentSheet = true } NavigationLink("Show Link", value: id * 100) } } } .sheet( isPresented: $presentSheet, content: { NavigationStack { TestView(id: self.id + 1) // Comment this block out and note the view no longer reloads when app is in background when there's > 1 sheet modals .navigationDestination(for: Int.self, destination: { num in TestView(id: num) }) } } ) .task { isLoading = true defer { isLoading = false } try? await Task.sleep(for: .seconds(1)) } } } struct ContentView: View { var body: some View { let _ = Self._printChanges() VStack { content .padding() } } var content: some View { VStack { NavigationStack { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) TestView(id: 0) } .navigationDestination(for: Int.self, destination: { num in TestView(id: num) }) } } } } Steps to reproduce: To reproduce the issue in the sample project: Tap on present sheet in navstack button to invoke View #1 presented in sheet Put the app into multitasking mode by tapping on the simulator home button twice Observe that console does not emit debug messages on SwiftUI View change. Also observe that there was no loading in the view Tap on present sheet in navstack button again to invoke View #2 presented in sheet Repeat step #2, but this time observe that console does emit debug message that SwiftUI View were changed due to the following: TestView: @self, @identity, _isLoading, _presentSheet changed. TestView: _isLoading changed. TestView: _isLoading changed. To remove the issue: 7. Comment out the block on navigationDestination. Recompile the app and run it in simulator 8. Repeat step 2-5. Note this time the console does not emit debug message that SwiftUI View were changed.
1
1
112
2w
Issues with FocusState in List with views containing Textfields
We are having issues with implementing a List that has Views in it that contain a Textfield. The criteria we are trying to achieve is Select to edit the quantity of a product Auto focus on the row with that textfield, with the textfield's contents selected Display/Dismiss the keyboard Mask other rows in the list while interacting with a qty field We explored many routes and are looking for direction on what the designated approach is. This originally was a Tech Support Incident, and I was instructed to post here. There were 2 working project examples available if needed. In an implementation that has the FocusState on the parent view, we see collisions in animation / weird jumpiness // MARK: - Constant enum Constant { static let logTag = "AddReplenishmentProductView" } @Binding var state: ContentViewState // MARK: - Private Properties @State private var focusedLineItemId: String? // MARK: - Life cycle var body: some View { VStack { replenishmentProductList } .background(.tertiary) .navigationTitle("Add Products") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.visible, for: .navigationBar) } // MARK: - Private Computed properties @ViewBuilder private var replenishmentProductList: some View { ScrollViewReader { proxy in List { let list = Array(state.lineItems.enumerated()) ForEach(list, id: \.1.product.id) { (index, lineItem) in RowView( lineItem: $state.lineItems[index], focusedLineItemId: $focusedLineItemId ) .id(lineItem.id.uuidString) .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) .alignmentGuide(.listRowSeparatorLeading) { _ in return 0 } //  Blocks all the other rows that we are not focusing on. .maskingOverlay(focusId: $focusedLineItemId, elementId: "\(lineItem.id)") } .listSectionSeparator(.hidden) } .listStyle(.plain) .scrollDismissesKeyboard(.never) .scrollContentBackground(.hidden) /*  We are looking for a solution that doesn't require us to have this onChange modifier whenever we want to change a focus. */ .onChange(of: focusedLineItemId) { guard let lineItemId = focusedLineItemId else { return } /*  We need to scroll to a whole RowView so we can see both done and cancel buttons. Without this, the focus will auto-scroll only to the text field, due to updating FocusState. We are experiencing weird jumping issues. It feels like the animations for focus on text field and RowView are clashing between each other. To fix this, we added a delay to the scroll so the focus animation completes first and then we scroll to the RowView. However, when we attempt to focus on a row that is partially shown, sometimes the RowView won't update it's focus and won't focus ultimately on the TextField until we scroll. */ DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { withAnimation { //  We need to add the withAnimation call to animate the scroll to the whole row. proxy.scrollTo(lineItemId, anchor: .top) } } } } } } In an implementation where the FocusState is on the row views, we see issues with actually being able to focus. When quantity field we tap is located on a row near the top/bottom of the screen it does not look to be identified correctly, and the ability to scrollTo / the keyboard being presented are broken. struct ContentView: View { // MARK: - Constant enum Constant { static let logTag = "AddReplenishmentProductView" } @Binding var state: ContentViewState // MARK: - Private Properties @State private var focusedLineItemId: String? @FocusState private var focus: String? // MARK: - Life cycle var body: some View { VStack { replenishmentProductList } .background(.tertiary) .navigationTitle("Add Products") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.visible, for: .navigationBar) } // MARK: - Private Computed properties @ViewBuilder private var replenishmentProductList: some View { ScrollViewReader { proxy in List { let list = Array(state.lineItems.enumerated()) ForEach(list, id: \.1.product.id) { (index, lineItem) in RowView( lineItem: $state.lineItems[index], focusedLineItemId: $focusedLineItemId, focus: $focus ) .id(lineItem.id.uuidString) .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) .alignmentGuide(.listRowSeparatorLeading) { _ in return 0 } //  Blocks all the other rows that we are not focusing on. .maskingOverlay(focusId: $focusedLineItemId, elementId: "\(lineItem.id)") } .listSectionSeparator(.hidden) } .listStyle(.plain) .scrollDismissesKeyboard(.never) .scrollContentBackground(.hidden) /*  We are looking for a solution that doesn't require us to have this onChange modifier whenever we want to change a focus. */ .onChange(of: focusedLineItemId) { /*  We need to scroll to a whole RowView so we can see both done and cancel buttons. Without this, the focus will auto-scroll only to the text field, due to updating FocusState. However, we are experiencing weird jumping issues. It feels like the animations for focus on text field and RowView are clashing between each other. */ focus = focusedLineItemId guard let lineItemId = focusedLineItemId else { return } withAnimation { //  We need to add the withAnimation call to animate the scroll to the whole row. proxy.scrollTo(lineItemId, anchor: .top) } } } } }
4
0
140
2w
How to use ManagedAppDistribution Framework
Hi I have tried the code given on link https://developer.apple.com/documentation/appdistribution/fetching-and-displaying-managed-apps. This code is not compilable in Xcode 16.1. After some fixes i am able to run the code but i am getting Error registering for message: [App catalog changed]: An unspecified, unrecoverable error occurred. Kindly help me with this.
2
0
142
1w
UICollectionView Auto cell height problem
Hi, I'm trying to create a UICollectionView where the cell high is automatic. Cells contains a UILabel with all anchors to the contentView of the cell. It seems to work but I have a strange behavior with longer text, on reload data and on device rotation: Cells do not display the whole text or they change row, both randomly. To create my collection view I first create the collection view with a custom flow layout setting the automatic size on viewWillAppear: let collectionViewFlowLayout = CustomFlowLayout() collectionViewFlowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewFlowLayout) and I have also overridden: override func willAnimateRotation(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) { collectionView.setNeedsLayout() self.collectionView.layoutIfNeeded() self.collectionView.collectionViewLayout.invalidateLayout() //self.collectionView.reloadData() } Then, I created the custom layout as follow: import UIKit final class CustomFlowLayout: UICollectionViewFlowLayout { override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { let layoutAttributesObjects = super.layoutAttributesForElements(in: rect)?.map{ $0.copy() } as? [UICollectionViewLayoutAttributes] layoutAttributesObjects?.forEach({ layoutAttributes in if layoutAttributes.representedElementCategory == .cell { if let newFrame = layoutAttributesForItem(at: layoutAttributes.indexPath)?.frame { layoutAttributes.frame = newFrame } } }) return layoutAttributesObjects } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { guard let collectionView = collectionView else { fatalError() } guard let layoutAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as? UICollectionViewLayoutAttributes else { return nil } layoutAttributes.frame.origin.x = sectionInset.left if(indexPath.section == 0){ layoutAttributes.frame.size.width = collectionView.safeAreaLayoutGuide.layoutFrame.width - sectionInset.left - sectionInset.right } else if (indexPath.section == collectionView.numberOfSections - 1){ let width = ScreenUtility.getCollectionCellWidthForElement(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing, multiplier: 3) layoutAttributes.frame.origin.x = ScreenUtility.getCollectionCellOriginForElement(in: collectionView, at: indexPath, forElementHavingWidth: width, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing, multiplier: 3) layoutAttributes.frame.size.width = width } else if (indexPath.section == collectionView.numberOfSections - 3) || (indexPath.section == collectionView.numberOfSections - 4){ let width = ScreenUtility.getCollectionCellWidthForElement(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing) layoutAttributes.frame.origin.x = ScreenUtility.getCollectionCellOriginForElement(in: collectionView, at: indexPath, forElementHavingWidth: width, sectionLeft: sectionInset.left, sectionRight: sectionInset.right, minimumInteritemSpacing: minimumInteritemSpacing) layoutAttributes.frame.size.width = width } else { let width = ScreenUtility.getCollectionCellSizeForElementFullRow(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right) layoutAttributes.frame.origin.x = ScreenUtility.getCollectionCellOriginForElementFullRow(in: collectionView, sectionLeft: sectionInset.left, sectionRight: sectionInset.right) layoutAttributes.frame.size.width = width } return layoutAttributes } } And finally on collection view cells: override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { setNeedsLayout() layoutIfNeeded() let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0) layoutAttributes.frame.size = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel) return layoutAttributes } override func prepareForReuse() { self.nameLabel.text = "" self.idLabel.text = "" self.contentView.setNeedsLayout() self.contentView.layoutIfNeeded() } Let me show you an example on the iPad that is the worst. First Time I open the collection view I have cells on wrong rows and not sized properly Then I rotate the device portrait and the cells are fine On landscape again it changes behavior: This is just an example, things happens apparently randomly, and also sometimes cells disappear (I think the height is set to 0). I really do not understand why, cells width seems to be computed correctly, and cell label is set via setter: open var step: String = "" { didSet { nameLabel.text = step nameLabel.sizeToFit() self.contentView.setNeedsLayout() self.contentView.layoutIfNeeded() } }
2
0
118
1w
iOS 18.1 crash UIHostingView.layoutSubviews() / swift_unknownObjectWeakAssign / objc_storeWeak
We're seeing sporadic crashes on devices running iOS 18.1 - both beta and release builds (22B83). The stack trace is always identical, a snippet of it below. As you can tell from the trace, it's happening in places we embed SwiftUI into UIKit via UIHostingController. Anyone else seeing this? 4 libobjc.A.dylib 0xbe2c _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30 5 libobjc.A.dylib 0xb040 weak_register_no_lock + 396 6 libobjc.A.dylib 0xac50 objc_storeWeak + 472 7 libswiftCore.dylib 0x43ac34 swift_unknownObjectWeakAssign + 24 8 SwiftUI 0xeb74c8 _UIHostingView.base.getter + 160 9 SwiftUI 0x92124 _UIHostingView.layoutSubviews() + 112 10 SwiftUI 0x47860 @objc _UIHostingView.layoutSubviews() + 36
3
0
151
1w
How to draw emojis like the Lock Screen customisation?
On iOS you can create a new Lock Screen that contains a bunch of emoji, and they'll get put on the screen in a repeating pattern, like this: When you have two or more emoji they're placed in alternating patterns, like this: How do I write something like that? I need to handle up to three emoji, and I need the canvas as large as the device's screen, and it needs to be saved as an image. Thanks! (I've already written an emojiToImage() extension on String, but it just plonks one massive emoji in the middle of an image, so I'm doing something wrong there.)
0
0
114
1w
Widget Configuration UI "Add new item"
In the Explore enhancements to App Intents WWDC video at the 11 minute mark I see this UI in the Widget configuration. My question is, how do I configure my Widget to use this UI in the intent configuration? I tried using all different sorts of types and am unable to reproduce it in my app
2
0
133
1w
iPad OS 18 Tab Bar Controller is ignoring isEnabled property on tar bar items
Running an existing Xcode project in an iPad OS 18 simulator is automatically using the newly introduced tab bar view, moved from the bottom to the top. Unfortunately, the isEnabled property on a tar bar item is no longer honored. In Xcode's Storyboard builder, some tab bar items are initially disabled. (can't add a screenshot here, I will try to do that after posting) The iPad OS 17 simulator shows them correctly as disabled and any user interaction is suppressed as expected. The iPad OS 18 simulator shows them as active and they can be selected. Also setting them to disabled inside of the UITabBarViewController doesn't work: for item in self.tabBar.items! { if item.tag != 99 { item.isEnabled = false } } They stay enabled and selectable. As a workaround, I implemented the UITabBarViewControllerDelegate and overrode this method: func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { if Global.shared.accessToken == nil { if viewController is LoginViewController || viewController is SettingsViewController { return true } else { return false } } return true } The user can no longer select the tabs, however, there is no visual indicator that they are not selectable. I cannot find any indication in the release notes or documentation, that this behavior is intentional. So I assume this is a bug.
4
0
288
Oct ’24
Xcode 16.1: 'Cannot Preview in This File' Error on macOS After Adding Firebase SDK
Hi, after updating Xcode to Version 16.1, I started a new multiplatform project targeting macOS and iOS. Everything worked fine until I added Firebase SDK 11.4 (using Swift Package Manager). Now, I'm facing an issue where the preview is not possible with "My Mac" after adding Firebase SDK, even with a very simple view like: struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() } } #Preview { ContentView() } However, previewing with iPhone or iPad works fine. This is really frustrating. When I run the app on a simulator (Mac, iPhone, or iPad), everything works perfectly. The error shown is Cannot preview in this file: Failed to launch [AppName] with the following path: /Users/[myname]/Library/Developer/Xcode/DerivedData/[AppName-gemeoxpjlzrshfifmgmqrkcxdeiz/Build/Products/Debug/FirebaseFirestoreInternal.framework/FirebaseFirestoreInternal Run Destination: macOS 15.1. What I have tried so far: Cleaned the build folder Re-installed Firebase SDK Any insights would be greatly appreciated! Thank you!
0
1
129
1w
Disable new tab bar look
Hi, I am trying out the new UITabBar stuff in iOS18, and I don't think it'll be a good fit for my app. Is there a way to revert to the old iPad UITabBar look and placement that we've been using before? I don't want to make such a big change like this just yet, but I would need to make other changes to the app as well and I don't want to use the new UITabBar just yet. Is there a way to achieve this?
30
17
12k
Jun ’24
PHAssetCollectionChangeRequest.removeAssets Does Not Work
Hello! I am trying to remove a photo from my Photos Library using PhotosUI. I run into this error when I attempt to delete it: "Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)"" No photos access scope requirements declared for changes Failed to log access with error: access= accessor:<> identifier:82068C12-FD10-4DE2-9867-B4406FBFB706 kind:intervalEvent timestampAdjustment:0 visibilityState:0 assetIdentifierCount:0 accessCount:0 tccService:kTCCServicePhotos, error=Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.privacyaccountingd" UserInfo={NSDebugDescription=connection to service named com.apple.privacyaccountingd}
2
0
169
1w