Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

SwiftUI Documentation

Post

Replies

Boosts

Views

Activity

MetalKit in SwiftUI
Hi,Are there any plans for integrating Metal/MetalKit with SwiftUI?Is that correct that current recommended way of the integration is to use UIViewControllerRepresentable like in the tutorial?Thank you!
18
1
13k
Jul ’19
SwiftUI - Determining Current Device and Orientation
So currently what I have been doing for determining what device type and orientation I am in for SwiftUI is using sizeClasses, usually something like the following:struct SizeClassView: View { @Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass? @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass? var body: some View { if horizontalSizeClass == .compact && verticalSizeClass == .regular { Text("iPhone Portrait") } else if horizontalSizeClass == .regular && verticalSizeClass == .compact { Text("iPhone Landscape") } else if horizontalSizeClass == .regular && verticalSizeClass == .regular { Text("iPad Portrait/Landscape") } } }What I'd like to know is: Is there any better way to do this in SwiftUI? The main problem I'm having with this method is that I can't differentiate between iPad Portrait and Landscape, but at least I can use it to differentiate between iPhone Portrait and iPhone Landscape and iPad... Any help and insight is greatly appreciated!
8
2
23k
Dec ’19
Mapkit and swiftui
I have updated my map code so that now I have a region that is set as a state var in my strict. My map links to this state var. the problem is now I want to update my map based on my long and last variables that are passed to the struct is there a way to do this - going crazy trying to do this
3
0
4.3k
Jun ’20
Migrating existing SwiftUI apps to the new multi platform template
I have an iOS 13 app that I’m hoping to release soon that is written entirely in SwiftUI. If I was starting from scratch today, I’d obviously use the new multi platform template which looks awesome.... But since I’m not starting from scratch, what are the recommendations/best practices for existing apps? Is there a path for migrating existing apps to take advantage of the new app structure (below) when moving to iOS 14? @main struct HelloWorld: App { var body: some Scene { WindowGroup { Text(“Hello, world!”).padding() } } }
2
0
1.7k
Jun ’20
Prevent dismissal of sheet in SwiftUI
I'd like to emulate the behavior of UIViewController.isModalInPresentation in SwiftUI. In my first attempt, I defined the following view: struct ModalView<Content: View>: UIViewControllerRepresentable { 		var content: () -> Content 		func makeUIViewController(context: Context) -> UIHostingController<Content> { 				let controller = UIHostingController(rootView: content()) 				controller.isModalInPresentation = true 				return controller 		} 		func updateUIViewController(_ imagePickerController: UIHostingController<Content>, context: Context) {} } From my main app view, I then present the ModalView as a sheet: struct ContentView: View { 		@State 		var presentSheet: Bool = true 		var body: some View { 				Text("Hello, world!") 						.sheet(isPresented: $presentSheet) { 								ModalView { 										Text("Sheet") 								} 						} 		} } But the user is still able to dismiss the ModalView by swiping down. I would expect this sheet to be non-dismissible. Is anything like this supposed to work? If not, is there some other way to prevent the dismissal of a sheet in SwiftUI? The closest workaround I've found is to apply .highPriorityGesture(DragGesture()) to the content of the sheet, but swiping down with two fingers still works.
5
1
8.2k
Jun ’20
LinkDylibError when previewing SwiftUI view from a package.
I have two (local) Swift packages (both with a single library product): RemoteImage, which defines setImage(from:) function on UIImageView and SatelitUI package which directly depends on the first one and defines some views. But when I'm trying to preview views from the second package I'm getting the following error: linker command failed with exit code 1 (use -v to see invocation) LinkDylibError: Failed to build TrailerView.swift Linking failed: linker command failed with exit code 1 (use -v to see invocation) ld: warning: directory not found for option '-F/Applications/Xcode-beta.app/Contents/SharedFrameworks-iphonesimulator' Undefined symbols for architecture x86_64:   "(extension in RemoteImage):__C.UIImageView.setImage(from: Foundation.URL?) -> ()", referenced from:       (extension in SatelitUI_PreviewReplacement_TrailerView_2):SatelitUI.TrailerView.(previewupdate in _8C3731B0EF007627509BEEB93277D681)(with: SatelitUI.Trailer?) -> () in TrailerView.2.preview-thunk.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Apparently, Xcode fails to link the library from the first package because it's dynamic. Static linking works as expected. It's a bug I believe?
2
1
1.6k
Jun ’20
Swift UI on iOS 14 not assigning new object to @State property
On iOS 13 I used to use optional @State properties to adapt views. In my case, the presented view would either create a new object (an assignment) if the state that is passed into it is nil, or edit the assignment if an assignment was passed in. This would be done in the action block of a Button and it worked beautifully. On iOS 14 / Xcode 12 this no longer seems to work. Given the following code which creates a new assignment and passes it into the editor view when the user taps a "New Assignment" button, the value of assignment remains nil. Is anyone else experiencing similar behaviour? struct ContentView: View { 		@Environment(\.managedObjectContext) var context 		@State var assignmentEditorIsPresented = false 		@State var assignment: Assignment? = nil 		var Body: some View { 				[...] 				Button("New Assignment", action: { 						self.assignment = Assignment(context: context) 						self.assignmentEditorIsPresented = true 				}) 				.sheet(isPresented: assignmentEditorIsPresented) { 						[...] 				} 		} } What's even weirder is that I tried adding a random piece of state, an Int, to this view and modifying it right before the assignment state (between lines 9 and 10) and it didn't change either.
20
3
11k
Jun ’20
NavigationView jumps when transitioning from displayMode large to inline
In a simple app with a ScrollView inside a NavigationView, on scroll the content of the scrollView doesn't smoothly transition from its size with navigationBarDisplayMode .large to .inline, but rather makes this a jarring jump. Minimum code to reproduce: struct ContentView: View {     var body: some View {         NavigationView {             ScrollView {                 ForEach(0..<200, id: \.self) { i in                     Text("Row \(i)")                         .frame(maxWidth: .infinity)                 }             }             .navigationTitle("Test")         }     } } The following code produces the desired smooth transition though: struct ContentView: View {     var body: some View {         NavigationView {             List {                 ForEach(0..<200, id: \.self) { i in                     Text("Row \(i)")                 }             }             .navigationTitle("Test")         }     } } I could not replicate the issue using UIKit's UITableViewController inside a UINavigationViewController, nor with a UIScrollView inside a UINavigationViewController. Observed in simulator and on device running iOS 14 public beta (18A5319i), built with Xcode 12.0 beta 2 (12A6163b) on macOS 10.15.5 (19F101).
12
4
6.4k
Jul ’20
.sheet no longer dismissable in WatchOS 7?
In WatchOS 6 a presented .sheet could be dismissed by swiping down or tapping on the navigationBarTitle. In the WatchOS 7 beta, presented sheets are no longer dismissible by either method...forcing the addition of a button to dismiss. It appears as if .sheet is now acting as .fullScreenCover within WatchOS 7. Anyone else running into this? Wondering if this is now expected behavior on WatchOS or if it's a bug...
7
0
2.9k
Aug ’20
How should I access @AppStorage and @SceneStorage values outside of views?
The two property wrappers @AppStorage and @SceneStorage are great because you can simply redeclare a property in multiple views to share the value and automatically update other views. But how should I access those same values outside of views? I have helper functions which are used in multiple views and which change behaviour based on those stored properties. I believe I could use the old NSUserDefaults.standard to reference the @AppStorage values, but is that the "right" way to do it, and how do I access @SceneStorage values?
8
2
9.1k
Aug ’20
Swiftui Custom Fonts not showing
Hello, My Custom fonts are not showing in SwiftUI. I am all up to date on all of my software and I have added my TTF's to a fonts folder in my collection. I also added the "Fonts provided by application" array type to my info.plist and the fonts as elements. Here is my code. I have no idea what I'm doing wrong. Is there a bug in the latest version of Swiftui? Text("Hello World") &#9;&#9;&#9;.font(.custom("VervelleScript-lgxR0", size: 36))
6
1
7.0k
Sep ’20
Custom back button with SwiftUI
Hello, I'm trying to remove the current back button behavior in a navigation view and instead have a simple arrow. Disabling the button with navigationBarBackButtonHidden and then adding my own with navigationBarItems works, but then I lose the swipe gesture to go back. I could try to rebuild this swipe gesture, but that seems hard to get the same feel, and it will most likely break often. Is there something simpler ? I'd be satisfied with just removing the text of the back button and keeping only the <. Thanks
10
2
11k
Oct ’20
SwiftUI negative kerning cuts off font
Hey there! Got a question about font kerning: When adding a negative kerning to a text (changes via user input) the last character sometimes gets cut off: dropbox.com/s/49ucdzk8m4k61sj/fontproblem1.png?dl=0 dropbox.com/s/vmklvxp510wjeak/fontproblem2.png?dl=0 What i do is the following: Text("\(pos, specifier: "%.1f")") &#9;.font(.system(size: 100,design: .serif)) &#9;.fontWeight(.bold) &#9;.kerning(-5) When i remove the kerning it works, but as i understood the kerning keeps the letters as they are? Is there an alternative way of doing it?
2
0
989
Oct ’20
Why does same code work differently within SwiftUI Life Cycle and UIKit App Delegate Life Cycle?
Introduction I created a simple app to test enabling Sign In with Google using Observable Objects in a SwiftUI Application. However, the app only functions properly (displaying the signed in user's name and email) with a UIKit App Delegate Life Cycle. The code of the App file for the SwiftUI life cycle and that of the app delegate and scene delegate files of the UIKit App Delegate life cycle should function identical; however, they do not. Project Code SwiftUI Lift Cycle AppDelegate import UIKit import SwiftUI import GoogleSignIn class AppDelegate: NSObject, UIApplicationDelegate { /* GoogleDelegate() is the observable object */ let googleDelegate = GoogleDelegate() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { GIDSignIn.sharedInstance()?.clientID = "CLIENT_ID" GIDSignIn.sharedInstance()?.delegate = googleDelegate return true } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { return GIDSignIn.sharedInstance().handle(url) } } App @main struct WidgiTubeApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var window: UIWindow? { guard let scene = UIApplication.shared.connectedScenes.first, let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate, let window = windowSceneDelegate.window else {             return nil } return window } @Environment(\.scenePhase) private var scenePhase let googleDelegate = (UIApplication.shared.delegate as! AppDelegate).googleDelegate var body: some Scene { WindowGroup { GoogleSignInView() .environmentObject(googleDelegate) }.onChange(of: scenePhase) { (phase) in switch phase { case .active: GIDSignIn.sharedInstance().presentingViewController = window?.rootViewController window?.makeKeyAndVisible() case .inactive: case .background: default: } } } } Using the SwiftUI Life Cycle the User Is signed in; however, the information does not update in the SwiftUI view. (The view is identical between the SwiftUI Life Cycle and UIKit Application Delegate Life Cycle.) UIKit Application Delegate Life Cycle App Delegate DidFinishLaunchingWithOptions GIDSignIn.sharedInstance().clientID = "CLIENT_ID" GIDSignIn.sharedInstance().delegate = googleDelegate return true OpenURL return GIDSignIn.sharedInstance().handle(url) Scene Delegate SceneWillConnectTo let googleDelegate = (UIApplication.shared.delegate as! AppDelegate).googleDelegate let contentView = ContentView().environmentObject(googleDelegate) if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = UIHostingController(rootView: contentView) GIDSignIn.sharedInstance()?.presentingViewController = window.rootViewController self.window = window window.makeKeyAndVisible() } Conclusion Due to this, I have identified that there must be some issue that occurs when adapting the UIKit App Delegate code to the SwiftUI App Code. However, I cannot identify what the issue between the two life cycles is. It is my understanding that anything possible with the UIKit Delegate life cycle should theoretically be possible with SwiftUI. In the mean time, of course, there is no issue continuing with the UIKit Delegate; however, I was hoping to create a SwiftUI app. If anyone could help me identify where the issue lays between these two different life cycles, I would greatly appreciate it. Thanks!
1
0
1.6k
Nov ’20
SwiftUI/CoreData: Simultaneous accesses to 0x7f92efc61cb8, but modification requires exclusive access
I'm working on an iOS app using SwiftUI and CoreData and am running into a problem that I cannot seem to figure out. To provide a little bit of information of what I am trying to do: I have two CoreData entities that have a One-To-Many relationship: Tarantula - A tarantula may molt many times (To Many) and when deleted, all of the molts shold also be removed (Cascade) Molt - A molt belongs to a single Tarantula (To One) and when deleted, should have the reference removed from the Tarantula (Nullify) I then have a view that lists all of the molts for a given Tarantula that allows adding and deleting molts. It looks like this: struct MoltListView: View { &#9;&#9;private static let DATE_FORMATTER: DateFormatter = { &#9;&#9;&#9;&#9;&#9;&#9;let d = DateFormatter() &#9;&#9;&#9;&#9;&#9;&#9;d.dateFormat = "MMM d, y" &#9;&#9;&#9;&#9;&#9;&#9;return d &#9;&#9;&#9;&#9;}() &#9;&#9; &#9;&#9;@Environment(\.managedObjectContext) private var viewContext &#9;&#9; &#9;&#9;@ObservedObject private var tarantula: Tarantula &#9;&#9;@FetchRequest private var molts: FetchedResults<Molt> &#9;&#9;@State private var userMessage: String = "" &#9;&#9;@State private var displayMessage: Bool = false &#9;&#9; &#9;&#9;init(tarantula: Tarantula) { &#9;&#9;&#9;&#9;self.tarantula = tarantula &#9;&#9;&#9;&#9;self._molts = FetchRequest(entity: Molt.entity(), &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; sortDescriptors: [NSSortDescriptor(keyPath: \Molt.date, ascending: false)], &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; predicate: NSPredicate(format: "tarantula = %@", tarantula)) &#9;&#9;} &#9;&#9; &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;List { &#9;&#9;&#9;&#9;&#9;&#9;Section(header: Text("Summary")) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("\(molts.count) Molt\(molts.count == 1 ? "" : "s")") &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;Section(header: Text("Molts")) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;NavigationLink(destination: MoltView(tarantula: tarantula, molt: Molt.newModel())) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("Add Molt").foregroundColor(.blue) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ForEach(molts, id: \.self) { molt in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;NavigationLink(destination: MoltView(tarantula: tarantula, molt: molt)) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text(MoltListView.DATE_FORMATTER.string(from: molt.modelDate)) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.onDelete(perform: deleteItems) &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;}.alert(isPresented: $displayMessage) { &#9;&#9;&#9;&#9;&#9;&#9;Alert(title: Text("Save Failure"), message: Text(userMessage), dismissButton: .default(Text("Ok"))) &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9; &#9;&#9;private func deleteItems(offsets: IndexSet) { &#9;&#9;&#9;&#9;withAnimation { &#9;&#9;&#9;&#9;&#9;&#9;offsets.map { molts[$0] }.forEach(viewContext.delete) &#9;&#9;&#9;&#9;&#9;&#9;do { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;try viewContext.save() &#9;&#9;&#9;&#9;&#9;&#9;} catch { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;viewContext.rollback() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;userMessage = "\(error): \(error.localizedDescription)" &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;displayMessage.toggle() &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;} } The error I am experiencing comes from whenever I try to delete a molt from the list view. The app instantly crashes and the error is: Simultaneous accesses to 0x7f92efc61cb8, but modification requires exclusive access Find the complete error here: error - https://developer.apple.com/forums/content/attachment/6d74dcde-d82b-4024-ade0-5936d8926488 I have tried removing the animation block and have played around with removing different UI components/restructuring. The only way I have been able to prevent this error is to remove the delete rule on the Molt->Tarantula relationship from Nullify to No Action. However, this seems more like a hack to me instead of a fix. Was hoping for some help on this issue.
7
0
3.9k
Dec ’20
ScrollViewReader scrollTo ignores withAnimation-Duration
I tried animating the scrollTo() like so, as described in the docs. - https://developer.apple.com/documentation/swiftui/scrollviewreader swift withAnimation { scrollProxy.scrollTo(index, anchor: .center) } the result is the same as if I do swift withAnimation(Animation.easeIn(duration: 20)) {     scrollProxy.scrollTo(progress.currentIndex, anchor: .center) } I tried this using the example from the ScrollViewReader docs. With the result that up and down scrolling has exactly the same animation. struct ScrollingView: View {     @Namespace var topID     @Namespace var bottomID     var body: some View {         ScrollViewReader { proxy in             ScrollView {                 Button("Scroll to Bottom") {                     withAnimation {                         proxy.scrollTo(bottomID)                     }                 }                 .id(topID)                 VStack(spacing: 0) {                     ForEach(0..100) { i in                         color(fraction: Double(i) / 100)                             .frame(height: 32)                     }                 }                 Button("Top") {                     withAnimation(Animation.linear(duration: 20)) {                         proxy.scrollTo(topID)                     }                 }                 .id(bottomID)             }         }     }     func color(fraction: Double) - Color {         Color(red: fraction, green: 1 - fraction, blue: 0.5)     } } struct ScrollingView_Previews: PreviewProvider {     static var previews: some View {         ScrollingView()     } }
10
5
3.8k
Apr ’21
fileImporter not showing
Hello, in my Mac Catalyst app, I have detail view with sections modeled as DisclosureGroups. The label view has a button, that shall trigger a file import view when pushed. The label view is defined as follows: swift HStack {         Text(LocalizedStringKey("Documents")).font(.title)         Spacer()         Button {           showFileImporter = false           // fix broken picker sheet           DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {             showFileImporter = true           }         } label: {           Image(systemName: "doc.badge.plus")             .padding(.horizontal, 10)         }         .disabled(!expanded)         .fileImporter(                       isPresented: $showFileImporter,               allowedContentTypes: [.data],           allowsMultipleSelection: false) { result in                       // add fileUrl.startAccessingSecurityScopedResource() before accessing file             NSLog("\(result)")           }       } Unfortunately the file import view is not showing, when the button is pushed, although the state changes to true. Does anybody have any hints? BTW the repo is available at https://github.com/thbonk/repti/tree/ui-refactoring The view in question is https://github.com/thbonk/repti/blob/ui-refactoring/Repti/Source/UI/Views/IndividualDetails/DocumentsSubview.swift Thanks &amp; Best regards Thomas
1
0
1.1k
May ’21