Post

Replies

Boosts

Views

Activity

Map behaves differently compared to MKMapView
Hey, I have a problem. I was using MKMapView in my app, and in the view where I had a background at the top of the screen, in the example it was Color.red, it extended all the way to the top of the screen. Now, I wanted to switch to the newer Map and I'm seeing an issue because I'm getting a navigation bar that cuts off my color as I indicated in the picture. Does anyone know why this is happening and if there's another way to achieve this? Steps to reproduce: Change MapView() to Map() to see difference import SwiftUI import MapKit @main struct TestAppApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { NavigationStack { ScrollView(.vertical) { Color.red .padding(.top, -200) .frame(height: 200) MapView().frame(minHeight: 300) // change this line to Map } .navigationTitle("Title") .navigationBarTitleDisplayMode(.large) } } } private typealias ViewControllerRepresentable = UIViewControllerRepresentable struct MapView: ViewControllerRepresentable { typealias ViewController = UIViewController class Controller: ViewController { var mapView: MKMapView { guard let tempView = view as? MKMapView else { fatalError("View could not be cast as MapView.") } return tempView } override func loadView() { let mapView = MKMapView() view = mapView } } func makeUIViewController(context: Context) -> Controller { Controller() } func updateUIViewController(_ controller: Controller, context: Context) { update(controller: controller) } func update(controller: Controller) { } } #Preview { ContentView() } I got: I want:
1
0
387
Jul ’24
Different behavior of FocusState on iOS 17
Hi, I have a problem adding a field to the application where the user enters formatted text and has the ability to delete it when focused. Interestingly, the application behaves correctly on iOS 17, and pressing 'x button' while typing deletes the text. However, on lower iOS versions, nothing happens and text doesn't disappear. First gif (iOS 15.5) second (iOS 17.2) and here is my code. import SwiftUI struct ContentView: View { @FocusState var isFocused: Bool @State var text = 0 var body: some View { VStack { HStack { TextField("write text here...", value: $text, format: .number) .focused($isFocused) .keyboardType(.numberPad) if isFocused { Button("", systemImage: "xmark.circle.fill") { text = 0 } } } .border(.black) } .padding() } } Does anyone know what's going on and how to make the application work on all iOS versions the way it does on 17?
0
0
313
Jan ’24
Matched Geometry Effect: Card View Expanding
Hey, I'm trying to create a view where cards with different subscriptions are displayed, and when you toggle, they expand to show details. I want the animation of one card to smoothly affect others, seamlessly shifting them. Here is the result I have achieved so far And that's my code import SwiftUI struct ContentView: View { @State private var toogle1: Bool = false @State private var toogle2: Bool = false var body: some View { VStack(spacing: 0) { ScrollView { VStack { subscriptionCurrentYearView() subscriptionPreviousYearView() } .padding(16) } } } @ViewBuilder func subscriptionCurrentYearView() -> some View { SubscriptionView(toggleOn: $toogle1) } @ViewBuilder func subscriptionPreviousYearView() -> some View { SubscriptionView(toggleOn: $toogle2) } } struct SubscriptionView: View { @Namespace private var animation @Binding var toggleOn: Bool var body: some View { VStack { HStack { Text("I want to subscribe this product from the current year") .foregroundColor(.secondary) .frame(width: 250, alignment: .leading) Toggle("", isOn: $toggleOn) .frame(width: 50) } .matchedGeometryEffect(id: "Header", in: animation) .padding() if toggleOn { VStack(alignment: .leading) { Text("Estimated current balance") TextField("", text: .constant("$ 0.00")) .font(.title) Text("Your whole amount must be transferred for the current tax year") } .matchedGeometryEffect(id: "Content", in: animation) .foregroundColor(.secondary) .padding() } } .frame(maxHeight: .infinity) .padding() .background(Color(uiColor: UIColor.lightGray)) .clipShape(RoundedRectangle(cornerRadius: 20)) .animation(.linear, value: toggleOn) } } #Preview { ContentView() } As you can see, the animation is jittery and doesn't look good. I tried using matchedGeometryEffect, but it doesn't seem to change anything - I'm probably doing it wrong. Does anyone know how to do this correctly?
1
0
506
Jan ’24
TextField automatic apply formatting when reach end point
Hello, I have a situation where I want to format a TextField and simultaneously end input after reaching a certain number of characters. For e.g. this is my view modifier which activate when user enter text of lenght struct TextFieldLimitModifer: ViewModifier { @Binding var value: String var length: Int func body(content: Content) -> some View { content .onChange(of: value) { if value.count > length { value = String($0.prefix(length)) } } } } And this is my formatter public struct SortCodeFormatStyle: ParseableFormatStyle { public init() {} } extension SortCodeFormatStyle { public var parseStrategy: Self { self } public func format(_ value: String) -> String { value.chunks(ofCount: 2) .joined(separator: "-") } } extension SortCodeFormatStyle: ParseStrategy { public func parse(_ value: String) -> String { value.components(separatedBy: "-").joined() } } extension FormatStyle where Self == SortCodeFormatStyle { public static var sortCode: Self { Self() } } Interestingly, on iOS 17 devices, formatting is applied after reaching a certain number of characters, while on older iOS versions, the user can continue typing beyond that limit, and the text is truncated upon pressing submit. And this becomes problematic, for example, when we have .keyboardType(.numberPad) and would like to enable this limit during input because we don't have a "done" button. Are we supposed to do something here?
0
0
361
Jan ’24
Challenged shouldChangeCharactersIn behaviour.
Hey, writing again due to difficulties in completing this example. Despite the bad user experience, I want the text to be formatted dynamically as I type, rather than at the end and make space after every 2 letters. Everything works fine until we want to edit a string within our TextField. I want to perform these operations on a limited text, a maximum of 13 characters, so I think it's possible to do but still have some issues with text editing. Has anyone done something similar or has an idea on how to fix this? struct CustomTextFieldView: UIViewRepresentable { @Binding var text: String func makeUIView(context: Context) -> UITextField { let textField = UITextField() textField.delegate = context.coordinator textField.text = text textField.placeholder = "Enter text here" return textField } func updateUIView(_ uiView: UITextField, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(text: $text) } class Coordinator: NSObject, UITextFieldDelegate { @Binding var text: String init(text: Binding<String>) { self._text = text } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // Get the current text in the textField guard let currentText = textField.text, let textRange = Range(range, in: currentText) else { return true } // Construct the new text after replacement let newText = currentText.replacingCharacters(in: textRange, with: string) // Disallow input if the total character count exceeds 13 or contains a space if !string.isEmpty { if newText.count > 13 || string.contains(" "){ return false } // Insert a space after every 2 characters if newText.count % 3 == 0 { let insertionIndex = newText.index(newText.startIndex, offsetBy: newText.count - 1) textField.text?.insert(" ", at: insertionIndex) } } return true } } } struct ContentView: View { @State var text = "" var body: some View { VStack { CustomTextFieldView(text: $text) } } }
2
1
598
Dec ’23
Wrong cursor behaviour during updating TextField input in SwiftUI
Hey, I have an issue with a certain behaviour of TextField in SwiftUI. I created a custom ParseableFormatStyle and pass it to formatted in the getter for the text just like below. TextField("", text: .init( get: { textValue.formatted(format) }, set: { value in textValue = value }) ) and in formatter I just chunk the input to get "AB AD AC" from "ABADAC" for example. public struct ChunkedFormatStyle: ParseableFormatStyle { public var parseStrategy: DefaultParseStrategy { DefaultParseStrategy() } private let distance: Int public init(distance: Int) { self.distance = distance } // returns a string with a white space after every 2 characters. public func format(_ value: String) -> String { value.chunked(into: distance) } } public struct DefaultParseStrategy: ParseStrategy { public func parse(_ value: String) throws -> String { value } } private extension String { func chunked(into distance: Int) -> Self { self.lazy .filter { $0 != " " } .chunks(ofCount: distance) .map { String($0) } .joined(separator: " ") } } The issue is that when typing text in the TextField, everything works fine, and the text dynamically changes; however, if I want to edit the text, the cursor automatically jumps to the beginning of the input. What can be done to prevent this from happening?
3
0
830
Dec ’23