Post

Replies

Boosts

Views

Activity

Reply to How to set timeFormat of DatePicker in swift
So you're not using SwiftUI. You should probably place this post in the UIKit topic instead so it's less confusing. ‎ In UIKit above property isn't available I believe UIDatePicker has a locale property that you can assign a custom locale to. It will do the same as the SwiftUI solution. If this doesn't work, or you have already tried it, then you need to provide more context and the code you are using so we can understand what is going on.
Jun ’24
Reply to How can I subscribe to changes to an @AppStorage var...
From my knowledge, I believe @AppStorage is more like @State. The projectedValue of the Published property wrapper exposes a publisher which is what you are subscribing to. The projectedValue of the AppStorage property wrapper is a binding to a value from UserDefaults. Note: the projectedValue is the property accessed with the $ operator. As a solution, I would use SwiftUI's onChange(of:perform:) modifier, or I guess as an alternative didSet, but this seems to be not what you want. I am not familiar enough with Combine to provide a full working solution, but I can give you some ideas: Create a custom Publisher as an extension on AppStorage to subscribe to Could create a custom property wrapper which replicates AppStorage but has a publisher for its projectedValue Or, could send/publish the change in the didSet of the @AppStorage property using some Combine object
May ’24
Reply to Swift: Navigation link not working.
The issue is you are placing the NavigationLink inside of a button's action closure. The first argument of the Button is action of type () -> Void (no parameters, no return). You are placing a NavigationLink inside which isn't being used at all, causing the warning to be generated. To fix this you need to use either the Button or the NavigationLink. As for your second problem, you are placing the NavigationStack inside of a VStack so the other content won't "show properly". Instead, try moving the NavigationStack to the top level. This code should solve both issues: NavigationStack { // move to top ZStack { Image("iPad Background 810 X 1060") .resizable() .scaledToFill() .ignoresSafeArea() VStack { HStack{ Image("Diabetes Control Logo 1024X1024") .resizable() .frame(width: 100, height: 100, alignment: .leading) .padding(.leading, 40) Text("Diabetes Control") .font(Font.custom("SnellRoundhand-Black", size: 40)) .background(Color(red: 255, green: 253, blue: 208)) .shadow(color: Color(red: 128, green: 128, blue: 128), radius: 3) .padding(.leading, 150) Spacer() }.padding(.bottom, 35) HStack { Text("What would you like to do : ") .font(Font.custom("SnellRoundhand-Black", size: 30)) .background(Color(red: 128, green: 128, blue: 128)) .shadow(color: Color(red: 126, green: 128, blue: 128), radius: 3) Spacer() }.padding(.leading, 35) .padding(.bottom,35) HStack { NavigationLink { // change to use only navlink iPadReadingsEntry() } label: { Text("Enter a BLOOD Glucose reading") }.background(Color(red: 255, green: 253, blue: 208)) .foregroundColor(.black) .font(Font.custom("SnellRoundhand", size: 24)) Spacer() }.padding(.leading, 60) .padding(.bottom, 25) Spacer() }.background(.blue) Spacer() } }
May ’24
Reply to How to use async functions with WithAnimation
Since you haven't provided any code samples, I can only guess at what you're attempting to do. This code will work: struct ContentView: View { @State private var fetchedData: [MyModel] = [] var body: some View { List(fetchedData) { model in Text(model.name) } .task(priority: .background) { let data = try? await modelActor.fetchData() await MainActor.run { withAnimation { fetchedData = data } } } } } It fetches the data asynchronously on a background thread, and then updates the UI with this new data, with an animation and on the main actor. If this is not what you're looking for, or there is more to your issue, then you need to provide some more context and some code.
May ’24
Reply to phaseAnimator: prevent opacity change?
Could you not use two separate state variables? This code works: struct ContentView: View { @State private var value: Int = 0 @State private var trigger = 0 var body: some View { VStack { GeometryReader { geometry in Text("\(value)") .phaseAnimator([0, 1], trigger: trigger) { view, phase in view .offset(x: phase == 1 ? 100 : 0) } animation: { phase in switch phase { case 1: .linear(duration: 1) default: nil } } } Button("Start Animation") { withAnimation { trigger += 1 } completion: { value += 1 } } } } } The trigger property is for triggering the animation. The value property only gets updated when the animation is complete, i.e. on the "snap back". This way the trigger and what is shown in the view cannot interfere with each other. It also ensures the text value can be updated after the animation, not before, like you said you wanted. If this solution is something you're not looking for, or there is more surrounding this problem, then I am still here to help. Just let me know.
May ’24
Reply to SwiftUI Trap change of orientation
In that case, don't give up so easily. When working with background images you don't really need to worry about device orientation. SwiftUI can let you resize the image and scale it to fill the available space. Something like this should work: struct BackgroundImageView: View { var body: some View { ZStack { // Background image Image(.background) .resizable() // make sure image can be resized .scaledToFill() // scale the image so it fills all available space .ignoresSafeArea() // [optional] Makes the image fill the whole screen including going behind the clock and battery (top) and the home bar (bottom) // Other content goes here Text("Main Content") } } }
May ’24
Reply to SwiftUI Trap change of orientation
I am unsure of what you're trying to accomplish. Which do you want to do? Detect when the user rotates their device – in terms of portrait and landscape orientation. Detect when the physical size of your app changes – in terms of size classes. Option 1 isn't recommended in cases such as Split View. For example, an iPad may be in landscape orientation but the width of your app isn't the full width of the device, only a portion of it. Option 2 uses predefined values that tells you whether your app is horizontally (width) or vertically (height) "compact", so you can configure your UI accordingly. I suggest you have a look at the documentation, especially for SwiftUI. You have some concepts about views, data models and communicating between them incorrect. Also check out this guide on layout; the "Device size classes" section might give you a better understanding into what "compact" and "regular" size classes mean.
May ’24
Reply to SwiftUI Orientation Change
The issue you have is that the if statement is placed inline inside the class and Swift doesn't know what to do with it. This is where variable and function declarations go and not code blocks or expressions. Instead, I think you want to put it in an initialiser, like this: init() { if myHorizClass == .compact && myVertClass == .regular { self.myOrient = "Portrait" } else if myHorizClass == .regular && myVertClass == .compact { self.myOrient = "Landscape" } else { self.myOrient = "Something Else" } } Also, I don't know if it was a typo or not, but in the if statement you had elseif instead of else if. Does this solve your problem?
May ’24
Reply to SwiftUI: Cannot find '$lektion' in scope
The toggle requires a Binding to a boolean value but your lektion variable cannot provide one. The solution is to use the Bindable property wrapper like this: ForEach(lektionen) { lektion in @Bindable var lektion = lektion // add this line NavigationLink { VokabelnView(lektion: lektion).navigationTitle("Vokabeln") } label: { Toggle("", isOn: $lektion.isOn) } } Now you can access $lektion which can create bindings to its properties.
Nov ’23
Reply to SwiftUI inspector full height
I believe you need to place the inspector modifier outside of a navigation structure (NavigationStack or NavigationSplitView), which I think was mentioned in the session video. Although you wouldn't necessarily use one for macOS, it's probably needed to have the full-height behaviour. This works for me: struct ContentView: View { var body: some View { NavigationStack { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .toolbar { Text("test") } } .inspector(isPresented: .constant(true)) { Text("this is a test") } } }
Oct ’23
Reply to Disabled button in SwiftUI .alert not working
I encountered a similar issue at the release of iOS 16 which is when I filed a feedback report. At that time, buttons that were disabled didn't show up in the alert at all. Then, sometime during the early iOS 17 betas (beta 4 maybe?), the issue was addressed and this was added to the SwiftUI release notes: Resolved Issues Fixed an issue where dynamically enabled buttons (e.g. with a TextField) were not updated in alerts. (95917673) (FB10463211) I then had to test this to see if things were fixed, and the disabled buttons did show up…but the action closure wasn't called at all. I then filed another feedback report (FB12857555) and nothing has happened yet. I suggest also filing feedback as that will help elevate the problem with Apple and hopefully get it fixed soon.
Sep ’23
Reply to How to create window without border between title bar and content view?
This style of window is without the title bar. You would need to remove/hide it to get this effect. In SwiftUI, you would add this modifier to your main App: WindowGroup { ContentView() } .windowStyle(.hiddenTitleBar) // add this modifier here However, it seems like you are using the AppKit lifecycle which means you will have to do this: myWindow = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 200, height: 200), styleMask: [.closable, .titled, .fullSizeContentView], // can make the contentView consume the full size of the window backing: .buffered, defer: false) // Modify these two properties myWindow.titleVisibility = .hidden myWindow.titlebarAppearsTransparent = true
Sep ’23
Reply to SwifUI - Set frame on Group of Buttons not working as expected
The issue is not with the Group but with the order of the modifiers. The order is very important in SwiftUI as it dictates how views are rendered and can produce different outcomes by just flipping two modifiers around. In your case, you are applying the frame modifier after the background modifier which is why you are seeing this result: To explain, these two snippets are effectively the same and demonstrates what Group is doing: Group { Button { } label: { Text("One") .padding() } .background(.black) .tint(.white) Button { } label: { Text("Two") .padding() } .background(.white) .tint(.black) } .frame(minWidth: 0, maxWidth: .infinity) // <- Button { } label: { Text("One") .padding() } .background(.black) .tint(.white) .frame(minWidth: 0, maxWidth: .infinity) // <- Button { } label: { Text("Two") .padding() } .background(.white) .tint(.black) .frame(minWidth: 0, maxWidth: .infinity) // <- What you really want is this: which can be achieved by applying the frame modifier before the background modifier, like this: Button { } label: { Text("One") .padding() } .frame(minWidth: 0, maxWidth: .infinity) // <- .background(.black) .tint(.white) Button { } label: { Text("Two") .padding() } .frame(minWidth: 0, maxWidth: .infinity) // <- .background(.white) .tint(.black) This has to be done individually as using Group can't fulfil that. What you can do instead is create a custom button style with this max frame (and anything else you want) and then apply that to the Group or HStack.
Sep ’23