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:
Post
Replies
Boosts
Views
Activity
Hey, is there any reason why code coverage is not excluded from the preview in SwiftUI?
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?
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?
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?
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)
}
}
}
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?
Hi, does anyone know if it's possible to change the language from within the code/application so that the change also reflects in the settings in preferred language section?