Incorrect Spacing in SwiftUI View - ios

Xcode 11.2.1, Swift 5
I have a custom view in SwiftUI and I have been fiddling around with it for a while to try and get rid of the extra space being added. I cannot tell if this is a bug in SwiftUI itself or if I am doing something wrong.
View:
struct Field: View {
#Binding var text: String
var title: String
var placeholderText: String
var leftIcon: Image?
var rightIcon: Image?
var onEditingChanged: (Bool) -> Void = { _ in }
var onCommit: () -> Void = { }
private let height: CGFloat = 47
private let iconWidth: CGFloat = 16
private let iconHeight: CGFloat = 16
init(text: Binding<String>, title: String, placeholder: String, leftIcon: Image? = nil, rightIcon: Image? = nil, onEditingChanged: #escaping (Bool) -> Void = { _ in }, onCommit: #escaping () -> Void = { }) {
self._text = text
self.title = title
self.placeholderText = placeholder
self.leftIcon = leftIcon
self.rightIcon = rightIcon
self.onEditingChanged = onEditingChanged
self.onCommit = onCommit
}
var body: some View {
VStack(alignment: .leading, spacing: 3) {
Text(title.uppercased())
.font(.caption)
.fontWeight(.medium)
.foregroundColor(.primary)
.blendMode(.overlay)
Rectangle()
.fill(Color(red: 0.173, green: 0.173, blue: 0.180))
.blendMode(.overlay)
.cornerRadius(9)
.frame(height: height)
.overlay(
HStack(spacing: 16) {
if leftIcon != nil {
leftIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
ZStack(alignment: .leading) {
if text.isEmpty {
Text(placeholderText)
.foregroundColor(.secondary)
.lineLimit(1)
.truncationMode(.tail)
}
TextField("", text: $text, onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(.white)
.lineLimit(1)
.truncationMode(.tail)
}
Spacer()
if rightIcon != nil {
rightIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
}
.padding(.horizontal, 16)
)
}
}
}
When I create an instance of it like so:
struct ContentView: View {
#State var text = ""
let backgroundGradient = Gradient(colors: [
Color(red: 0.082, green: 0.133, blue: 0.255),
Color(red: 0.227, green: 0.110, blue: 0.357)
])
var body: some View {
ZStack {
LinearGradient(gradient: backgroundGradient, startPoint: .top, endPoint: .bottom)
.edgesIgnoringSafeArea(.all)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
Field(text: $text, title: "field", placeholder: "Required", leftIcon: Image(systemName: "square.and.pencil"), rightIcon: Image(systemName: "info.circle"))
.padding(.horizontal, 30)
}
.onAppear {
UIApplication.shared.windows.forEach { window in
window.overrideUserInterfaceStyle = .dark
}
}
}
}
At first glance, it seems to behave as expected:
The problem appears after the user tries typing in the field. There is too much spacing between the right icon and the text, causing it to be truncated earlier than necessary.
As you can see, there is a much larger amount of spacing between the text field and the right icon (excess spacing) than there is between the text field and the left icon (correct spacing).
All elements of Field should have a spacing of 16 on all sides. For some reason, the TextField is not taking up enough space and thus its spacing from the right icon is less than the desired 16.
How can I fix this spacing?

You have the following:
Spacer()
before the following section of code:
if rightIcon != nil {
rightIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
Removing the Spacer() will give you the same pixels between the left icon and the right icon.

*SwiftUI
///For vertical Custom Spaces
.padding(.vertical, 6)
//For Horizontal
.padding(. horizontal, 6)
//For uniform Spacting
Spacer()
///

Related

How to close sheet view with buttons

I'm currently running into a problem with a sheet not closing when the close button is pushed or the save button has completed transferring the data from the form to the list in homeview. Below is the code for a custom tab bar that when "New Survey" is pushed it will open the formView. The formView has two buttons closed and save. I would like it that when either one of these buttons are selected that it closes the formView.
struct FormView: View {
#Binding var surveys: [Survey]
#State var customerName = ""
#State var city = ""
#State var state = ""
#State var lineName = ""
#State var date = Date()
#Binding var isPresented: Bool
#State var showingFormView = false
var body: some View {
VStack{
ZStack {
NavigationView {
VStack {
ZStack {
Form {
Section(header: Text("Survey Info").font(.custom("Roboto-Light", size: 24)).foregroundColor(Color(red: 0.00, green: 0.188, blue: 0.42)).offset(x: -20)) { TextField("Customer Name", text: $customerName)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
TextField("Customer City", text: $city)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
TextField("State", text: $state)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
TextField("Line Name", text: $lineName)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
DatePicker("Date", selection: $date, displayedComponents: .date)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
}
}
VStack (alignment: .center){
Spacer()
HStack {
**Button(action: {
self.showingFormView = false
self.isPresented = false
}, label: {
Text("Close")
.font(.custom("Roboto-Light", size: 23))
.foregroundColor(Color.white)
.frame(width: 150.0, height: 50.0, alignment: .center)
.background(Color(hue: 0.001, saturation: 0.768, brightness: 0.975))
.cornerRadius(3)
})
Button(action: {
// Save survey data to UserDefaults or any other means
let survey = Survey(customerName: customerName, city: city, state: state, lineName: lineName, date: date)
self.surveys.append(survey)
// Clear text fields
self.customerName = ""
self.city = ""
self.state = ""
self.lineName = ""
self.date = Date()
// Close FormView
self.showingFormView = false
self.isPresented = false
}, label: {
Text("Save")
.font(.custom("Roboto-Light", size: 23))
.foregroundColor(Color.white)
.frame(width: 150.0, height: 50.0, alignment: .center)
.background(Color(red: 0.451, green: 0.729, blue: 0.251))
.cornerRadius(3)
})**
}
}
}
}
.navigationBarHidden(true)
}
}
}
}
}
Custom Tab Bar
struct CustomTabBar: View {
#Binding var surveys: [Survey]
#Binding var isPresented : Bool
#State var showingFormView = false
var body: some View {
NavigationView{
VStack {
Spacer()
HStack (alignment: .bottom) {
Button {
} label: {
GeometryReader { geo in
VStack (alignment: .center, spacing: 4) {
Image(systemName: "magnifyingglass")
.resizable()
.scaledToFit()
.frame(width: 32, height: 32)
Text("Search")
.font(.custom("Roboto-Light", size: 14))
}
.frame(width: geo.size.width,height: geo.size.height)
}
}
.tint(Color(red: 0.0, green: 0.188, blue: 0.42))
**Button(action: {
showingFormView = true
}) {
GeometryReader { geo in
VStack(alignment: .center, spacing: 4) {
Image("PSIcon")
.resizable()
.scaledToFit()
.frame(width: 38, height: 38)
Text("New Survey")
.font(.custom("Roboto-Light", size: 14))
.tint(Color(red: 0.0, green: 0.188, blue: 0.42))
}
.frame(width: geo.size.width, height: geo.size.height)
}
}
.sheet(isPresented: $showingFormView) {
FormView(surveys: $surveys, isPresented: $isPresented) }
//code allows you to call up a specific view so long as a var is indicated
**
Button {
} label: {
GeometryReader { geo in
VStack (alignment: .center, spacing: 4) {
Image(systemName: "arrow.up.arrow.down")
.resizable()
.scaledToFit()
.frame(width: 35, height: 35)
Text("Sort")
.font(.custom("Roboto-Light", size: 14))
}
.frame(width: geo.size.width,height: geo.size.height)
}
}
.tint(Color(red: 0.0, green: 0.188, blue: 0.42))
}
.frame(height: 50.0)
}
}
}
}
The save button saves and creates a new item in the dynamic list but it does not close the formView. The only way for me to close the view is by swiping down on the screen.

How to design floating header in securedField the text set as header when enter in the SecuredField in Swiftui?

I want to set the text as header when the field enter But it does not
work as I want. This is my code section It works but whenever I select
the texts and then write again it shows clear foreground text.
struct PasswordField: View{
#State var isTapped = true
let textFieldHeight: CGFloat = 50
private var placeHolderText: String = ""
#State var leadingImage: String = "lock.fill"
#Binding var text: String
#State private var isEditing = false
public init(placeHolder: String,
text: Binding<String>) {
self._text = text
self.placeHolderText = placeHolder
self.leadingImage = leadingImage
}
var shouldPlaceHolderMove: Bool {
isEditing || (text.count != 0)
}
var body: some View {
ZStack(alignment: .leading) {
ZStack {
if isTapped{
// SecureField("",text: $text)
ZStack {
SecureField("", text: $text)
.font(.system(size: 22))
TextField("", text: $text, onEditingChanged: { (edit) in
isEditing = edit
})
.foregroundColor(.clear)
.disableAutocorrection(true)
.font(.system(size: 22))
}
.padding(.leading,40)
.padding(.trailing,50)
.foregroundColor(Color.white)
.accentColor(Color.teal)
.font(.system(size: 22))
.animation(.linear, value: true)
} else{
TextField("", text: $text, onEditingChanged: { (edit) in
isEditing = edit
})
.padding(.leading,40)
.padding(.trailing,50)
.foregroundColor(Color.white)
.accentColor(Color.teal)
.font(.system(size: 22))
.animation(.linear, value: true)
}
}.overlay(alignment: .trailing){
Image(systemName: isTapped ? "eye.slash.fill": "eye.fill").font(.system(size: 28))
.foregroundColor(.gray).padding(4).onTapGesture{
isTapped.toggle()
}
}
//Floating Placeholder
Text(placeHolderText)
.foregroundColor(.white)
.padding(shouldPlaceHolderMove ?
EdgeInsets(top: 2, leading:40, bottom: textFieldHeight, trailing: 0) :
EdgeInsets(top: 0, leading:50, bottom: 0, trailing: 0))
.scaleEffect(shouldPlaceHolderMove ? 1.2 : 1.3)
.animation(.easeInOut, value: 91)
.overlay(alignment: .leading){
Image(systemName: leadingImage)
.foregroundColor(Color.gray)
.font(.system(size: 28)).padding(4)
}
}
.underlineTextField()
.foregroundColor(shouldPlaceHolderMove ? Color.teal: Color.white)
.frame( height: 90)
}
}
it does not work properly. let me know where I am getting wrong? in my
code Textfield used for isEditting attribute Use only. is there any
other way for getting this functionality in the SecuredField.

How do I add a vertical swipe up gesture(to go to a different view) in a scrollview in SwiftUI

I designed a SwiftUI view which is a scrollview. Now I need to add a vertical swipe gesture to it which shall take it to a different view. I tried to do it using the tabView and adding a rotating effect of -90 degrees to it. But that rotates my original view too and that's not what I want. I couldn't find any relevant help in SwiftUI which deals with swiping up a scrollview to a new view.
Here's my code..
the vertical swipe I achieved using this. But my view get rotated. Setting other angles disappears the view somehow. I am new to SwiftUI, I am stuck on it for a week now.1
GeometryReader { proxy in
TabView {
ScrollView {
VStack(alignment: .center) {
ZStack(alignment: .leading) {
Image("Asset 13").resizable().frame(width: percentWidth(percentage: 100), height: percentHeight(percentage: 50), alignment: .top)
HStack {
Spacer()
Image("Asset 1")//.padding(.bottom, 130)
Spacer()
}.padding(.bottom, 150)
HStack {
VStack(spacing:2) {
Text("followers").foregroundColor(.white).padding(.leading, 20)
HStack {
Image("Asset 3")
Text("10.5k").foregroundColor(.white)
}
}
Spacer()
VStack {
Image("Asset 10").padding(.trailing)
Text("300K Review ").foregroundColor(.white)
}
}.background(Image("Asset 2").resizable().frame(width: percentWidth(percentage: 100), height: percentHeight(percentage: 6), alignment: .leading))
.padding(.top, 410)
HStack {
Spacer()
Image("Asset 14").resizable().frame(width: percentWidth(percentage: 50), height: percentHeight(percentage: 25), alignment: .center)
Spacer()
}.padding(.top, 390)
}
VStack(spacing: 4) {
Text("Karuna Ahuja | Yoga Instructor").font(Font.custom(FontName.bold, size: 22))
Text("12 Years of Experience with Bhartiya Yog Sansthan").tracking(-1).font(Font.custom(FontName.light, size: 16)).opacity(0.4)
}
Divider()
HStack {
ZStack {
Image("Asset 6").resizable().frame(width: percentWidth(percentage: 30), height: percentHeight(percentage: 12), alignment: .center)
VStack {
Image("Asset 5").resizable().frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4), alignment: .center)
Text("245").font(Font.custom(FontName.bold, size: 16))
Text("Video").font(Font.custom(FontName.medium, size: 16)).opacity(0.5)
}
}
ZStack {
Image("Asset 6").resizable().frame(width: percentWidth(percentage: 30), height: percentHeight(percentage: 12), alignment: .center)
VStack {
Image("Asset 7").resizable().frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4), alignment: .center)
Text("45").font(Font.custom(FontName.bold, size: 16))
Text("Live Class").font(Font.custom(FontName.medium, size: 16)).opacity(0.5)
}
}
ZStack {
Image("Asset 6").resizable().frame(width: percentWidth(percentage: 30), height: percentHeight(percentage: 12), alignment: .center)
VStack {
Image("Asset 9").resizable().frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4), alignment: .center)
Text("245").font(Font.custom(FontName.bold, size: 16))
Text("Sessions").font(Font.custom(FontName.medium, size: 16)).opacity(0.5)
}
}
}
Divider()
Text("Shine bright so that your light leads other. I'm a fitness junkie, high-energy yoga instructor. Let's make fitness FUN!").font(Font.custom(FontName.normal, size: 16)).tracking(-1).opacity(0.7).padding([.leading,.trailing], 6)
VideoPlayer(player: AVPlayer(url: videoUrl))
.frame(height: 320)
Spacer()
}.gesture(DragGesture(minimumDistance: 20, coordinateSpace: .global)
.onEnded { value in
let horizontalAmount = value.translation.width as CGFloat
let verticalAmount = value.translation.height as CGFloat
if abs(horizontalAmount) > abs(verticalAmount) {
print(horizontalAmount < 0 ? "left swipe" : "right swipe")
} else {
print(verticalAmount < 0 ? "up swipe" : "down swipe")
}
})
}.edgesIgnoringSafeArea(.all)
.ignoresSafeArea()
Text("this")
Text("this")
Text("this")
// ForEach(colors, id: \.self) { color in
// color // Your cell content
// }
// .rotationEffect(.degrees(-90)) // Rotate content
// .frame(
// width: proxy.size.width,
// height: proxy.size.height
// )
}
.frame(
width: proxy.size.height, // Height & width swap
height: proxy.size.width
)
.rotationEffect(.degrees(90), anchor: .topLeading) // Rotate TabView
.offset(x: proxy.size.width) // Offset back into screens bounds
.tabViewStyle(
PageTabViewStyle(indexDisplayMode: .never)
)
}
The only pure SwiftUI way I see is to do your own ScrollView implementation, which is not too complicated. This example has two views on top of each other. If you drag the first view further up than to the middle of the screen, it swipes away to reveal the second view.
struct ContentView: View {
#State private var offset = CGFloat.zero
#State private var dragOffset = CGFloat.zero
#State private var viewHeight = CGFloat.zero
var body: some View {
GeometryReader { fullgeo in
ZStack(alignment: .top) {
SecondView()
// necessary for second view to resize individually
.frame(height: fullgeo.size.height)
ScrollingView()
.overlay( GeometryReader { geo in Color.clear.onAppear { viewHeight = geo.size.height }})
.offset(y: offset + dragOffset)
.gesture(DragGesture()
.onChanged { value in
dragOffset = value.translation.height
}
.onEnded { value in
withAnimation(.easeOut) {
dragOffset = .zero
offset += value.predictedEndTranslation.height
// if bottom dragged higher than 50% of screen > second view
if offset < -(viewHeight - fullgeo.size.height/2) {
dragOffset = -viewHeight
return
}
// else constrain to top / bottom of ScrollingView
offset = max(min(offset, 0), -(viewHeight - fullgeo.size.height))
}
}
)
}
}
}
}
struct ScrollingView: View {
var body: some View {
VStack {
Text("View Top").font(.headline)
ForEach(0..<10) { _ in
Text("Content")
.frame(width: 200, height: 100)
.background(.white)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.gray)
}
}
struct SecondView: View {
var body: some View {
Text("View Bottom").font(.headline)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.orange)
}
}
Use this code:
import SwiftUI
struct PullToRefreshView: View
{
private static let minRefreshTimeInterval = TimeInterval(0.2)
private static let triggerHeight = CGFloat(100)
private static let indicatorHeight = CGFloat(100)
private static let fullHeight = triggerHeight + indicatorHeight
let backgroundColor: Color
let foregroundColor: Color
let isEnabled: Bool
let onRefresh: () -> Void
#State private var isRefreshIndicatorVisible = false
#State private var refreshStartTime: Date? = nil
init(bg: Color = .neutral0, fg: Color = .neutral90, isEnabled: Bool = true, onRefresh: #escaping () -> Void)
{
self.backgroundColor = bg
self.foregroundColor = fg
self.isEnabled = isEnabled
self.onRefresh = onRefresh
}
var body: some View
{
VStack(spacing: 0)
{
LazyVStack(spacing: 0)
{
Color.clear
.frame(height: Self.triggerHeight)
.onAppear
{
if isEnabled
{
withAnimation
{
isRefreshIndicatorVisible = true
}
refreshStartTime = Date()
}
}
.onDisappear
{
if isEnabled, isRefreshIndicatorVisible, let diff = refreshStartTime?.distance(to: Date()), diff > Self.minRefreshTimeInterval
{
onRefresh()
}
withAnimation
{
isRefreshIndicatorVisible = false
}
refreshStartTime = nil
}
}
.frame(height: Self.triggerHeight)
indicator
.frame(height: Self.indicatorHeight)
}
.background(backgroundColor)
.ignoresSafeArea(edges: .all)
.frame(height: Self.fullHeight)
.padding(.top, -Self.fullHeight)
}
private var indicator: some View
{
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: foregroundColor))
.opacity(isRefreshIndicatorVisible ? 1 : 0)
}
}
sample:
ScrollView{
VStack(spacing:0) {
//top of scrollView
PullToRefreshView{
//todo
}
}
}

Unwanted animation effect with .navigationBarHidden(true)

I have a simple loading view on SwiftUI.
When I am displaying this loading screen with .navigationBarHidden(true) on NavigationView.
There is an issue that animation has an unwanted effect on it.
This is my loading animation
struct LoaderThreeDot: View {
var size: CGFloat = 20
#State private var shouldAnimate = false
var body: some View {
HStack(alignment: .center) {
Circle()
.fill(Color.blue)
.scaleEffect(shouldAnimate ? 1.0 : 0.5, anchor: .center)
.animation(Animation.easeInOut(duration: 0.5).repeatForever())
.frame(width: size, height: size)
Circle()
.fill(Color.blue)
.scaleEffect(shouldAnimate ? 1.0 : 0.5, anchor: .center)
.animation(Animation.easeInOut(duration: 0.5).repeatForever().delay(0.3))
.frame(width: size, height: size, alignment: .center)
Circle()
.fill(Color.blue)
.scaleEffect(shouldAnimate ? 1.0 : 0.5, anchor: .center)
.animation(Animation.easeInOut(duration: 0.5).repeatForever().delay(0.6))
.frame(width: size, height: size, alignment: .center)
}
.onAppear {
self.shouldAnimate = true
}
}
}
LoadingView as follow:
struct LoadingView<Content>: View where Content: View {
let title: String
var content: () -> Content
#State var showLoader = false
var body: some View {
ZStack {
self.content()
.disabled(true)
.blur(radius: 3)
Rectangle()
.foregroundColor(Color.black.opacity(0.4))
.ignoresSafeArea()
VStack {
if showLoader {
LoaderThreeDot()
}
Text(title)
.foregroundColor(.black)
.font(.body)
.padding(.top, 10)
}
.padding(.all, 60)
.background(backgroundView)
}
.onAppear {
showLoader.toggle()
}
}
private var backgroundView: some View {
RoundedRectangle(cornerRadius: 12)
.foregroundColor(Color.white)
.shadow(radius: 10)
}
}
And simply presenting it as follow:
NavigationView {
ZStack {
LoadingView(title: "Loading...") {
Rectangle()
.foregroundColor(.red)
}
}
.navigationBarHidden(true)
}
If I remove .navigationBarHidden(true) animation looks ok.
So I am guessing that the animation effect started when the navigation bar was shown and it somehow affecting the animation after the navigation bar is hidden.
Is there any way I can avoid this?
Change your toggle on the main thered.
// Other code
.onAppear() {
DispatchQueue.main.async { //<--- Here
showLoader.toggle()
}
}
// Other code

SwiftUI: Padding inside TextField

I have a TextField in SwiftUI. When I apply padding to it as
TextField(text, text: $value)
.padding()
the padding is outside of the tap area of the TextField, i.e. tapping on the padding does not bring the text field into focus.
I would like to be able to focus the TextField even if the user taps on the padding.
You can try this. At least worked for me. Hope that helps someone:
TextField("", text: $textfieldValueBinding)
.frame(height: 48)
.padding(EdgeInsets(top: 0, leading: 6, bottom: 0, trailing: 6))
.cornerRadius(5)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(lineWidth: 1.0)
)
you can check this. for now i only did with top and bottom padding. you can do the same with the leading and trailing(or with horizontal and vertical).
as asked in the question this would do this
"I would like to be able to focus the TextField even if the user taps on the padding."
struct ContentView: View {
#State var name = ""
#State var isTextFieldFocused = false
var body: some View {
ZStack {
HStack{
Text(name)
.font(.system(size: 50 , weight: .black))
.foregroundColor(isTextFieldFocused ? Color.clear : Color.black)
Spacer()
}
TextField(name, text: $name , onEditingChanged: { editingChanged in
isTextFieldFocused = editingChanged
})
.font(.system(size: isTextFieldFocused ? 50 : 100 , weight: .black))
.foregroundColor(isTextFieldFocused ? Color.black : Color.clear)
.frame(width: 300, height: isTextFieldFocused ? 50 : 100 , alignment: .center)
.padding(.leading, isTextFieldFocused ? 25 : 0 )
.padding(.trailing, isTextFieldFocused ? 25 : 0 )
.padding(.top,isTextFieldFocused ? 25 : 0 )
.padding(.bottom,isTextFieldFocused ? 25 : 0 )
}.frame(width: 300)
.background(Color.red.opacity(0.2))
}
}
Yes, but you have to create your own TextFieldStyle. Here's an example:
struct CustomTextField: View {
public struct CustomTextFieldStyle : TextFieldStyle {
public func _body(configuration: TextField<Self._Label>) -> some View {
configuration
.font(.largeTitle) // set the inner Text Field Font
.padding(10) // Set the inner Text Field Padding
//Give it some style
.background(
RoundedRectangle(cornerRadius: 5)
.strokeBorder(Color.primary.opacity(0.5), lineWidth: 3))
}
}
#State private var password = ""
#State private var username = ""
var body: some View {
VStack {
TextField("Test", text: $username)
.textFieldStyle(CustomTextFieldStyle()) // call the CustomTextField
SecureField("Password", text: $password)
.textFieldStyle(CustomTextFieldStyle())
}.padding()
}
}
For iOS 15 and above you can use this:
var body: some View {
TextField("placeholder", text: $text).focusablePadding()
}
extension View {
func focusablePadding(_ edges: Edge.Set = .all, _ size: CGFloat? = nil) -> some View {
modifier(FocusablePadding(edges, size))
}
}
private struct FocusablePadding : ViewModifier {
private let edges: Edge.Set
private let size: CGFloat?
#FocusState private var focused: Bool
init(_ edges: Edge.Set, _ size: CGFloat?) {
self.edges = edges
self.size = size
self.focused = false
}
func body(content: Content) -> some View {
content
.focused($focused)
.padding(edges, size)
.contentShape(Rectangle())
.onTapGesture { focused = true }
}
}
TextField(
"TextFiled",
text: $teamNames,
prompt: Text("Text Field")
.foregroundColor(.gray)
)
.padding(5)
.frame(width: 250, height: 50, alignment: .center)
.background(
RoundedRectangle(cornerRadius: 25, style: .continuous)
.foregroundColor(.white)
.padding(.horizontal, -30)
)
I don't know if you can give padding inside of a TextField, but you can pad it from outside environment and give it a background of a shape with the same color of your TextField background.
Try this;
TextField("Username", text: $value)
.background(Color.yellow)
.padding(50)
.background(Capsule().fill(Color.white))

Resources