Currently, I'm using Combine for textField Validation. However, when the alert text disappears/appears, the Submit button below will be shifting. Is there any way to prevent this behavior ( without giving it a fixed frame size)?
Here is my code
TextField and prompt
VStack(alignment: .leading) {
TextField("", text: $text)
.font(.system(.title2, design: .rounded))
.foregroundColor(.blue)
Text(prompt)
.fixedSize(horizontal: false, vertical: true)
.font(.caption)
}
ContentView
VStack(spacing: 15) {
FloatingTextField(placeHolder : "First name", text: $userVM.firstName, borderColor: $color, prompt: userVM.confirmFnamePrompt)
FloatingTextField(placeHolder : "Last Name", text: $userVM.lastName, borderColor: $color, prompt: userVM.confirmLnamePrompt)
.padding(.bottom, 400)
}
Spacer()
Button {
} label: {
Text("Submit")
}
.disabled(!userVM.isFieldValid)
Related
I have something like that for the first time. The preview and the simulator do not look identical. I really have no idea how to fix it. Normally the simulator and the preview should be identical?
But it may be that I've nested something but I don't know what exactly.
The images and code are below:
Simulator
Preview Layout
var body: some View {
ZStack {
Image("bg-official")
.resizable()
.edgesIgnoringSafeArea(.all)
VStack {
Spacer()
Text("NUMBER MATCH")
.fontWeight(.bold)
.font(.title)
GeometryReader { (geometry : GeometryProxy) in
ZStack {
RoundedRectangle(cornerRadius: 30)
.foregroundColor(Color("bg-roundedrectangle"))
.frame(width: 295, height: 310)
VStack(spacing: 3){
HStack(spacing: 3) {
Button {
} label: {
ZStack {
Rectangle()
.fill(Color.black.opacity(0.7))
.frame(width: geometry.size.width/3, height: geometry.size.height/5.5)
.cornerRadius(radius: 20, corners: [.topLeft])
Text("60 Seconds")
.font(.title3)
.foregroundColor(.white)
}
}
Button {
} label: {
ZStack {
Rectangle()
.fill(Color.black.opacity(0.7))
.frame(width: geometry.size.width/3, height: geometry.size.height/5.5)
.cornerRadius(radius: 20, corners: [.topRight])
Text("Endless")
.font(.title3)
.foregroundColor(.white)
}
}
}
HStack(spacing: 3) {
Spacer()
Button {
} label: {
ZStack {
Rectangle()
.fill(Color.white)
.frame(width: geometry.size.width/3, height: geometry.size.height/5.5)
.cornerRadius(radius: 20, corners: [.bottomLeft])
Text("Game Center")
.font(.title3)
.foregroundColor(.black)
}
}
Button {
withAnimation() {
sheetManager.present(with: .init(
systemName: "info",
title: "Game Info",
content: "The aim of this game is to match as many tiles as you can with the same number and earn points. Tap a tile to select it and tap another tile with matching number of the first tile you tapp ed. Be careful and quick; the game will end if you tap a wrong tile, if the timer runs out or if th board gets filled by tiles!"))
}
} label: {
ZStack {
Rectangle()
.fill(Color.white)
.frame(width: geometry.size.width/3, height: geometry.size.height/5.5)
.cornerRadius(radius: 20, corners: [.bottomRight])
Text("Game Info")
.font(.title3)
.foregroundColor(.black.opacity(0.9))
}
}
Spacer()
}
}
}
}
.popup(with: sheetManager)
}
}
}}
Is it possible to have an expanding menu that does not expand the HStack it is in?
I want a "menu bar" on top of my app and on the right is an expanding menu with all my objects in. But when I expand the menu all of the HStack expands which looks bad.
I tried putting a .fixedsize() on the HStack but it didn't help.
Do I have to move the menu or is it possible?
This is my code:
HStack{
Text("Input searchfunction here")
.foregroundColor(Color.white)
.padding()
Spacer()
Button(action: {
createViewIsActive = true
}, label: {
Text("Lägg till tecken.")
.foregroundColor(Color.white)
.onAppear {
if signs.count != 0 {
activeSign = signs[0]
}
}
Image(systemName: "plus")
.foregroundColor(Color.white)
})
.padding()
Button(action: {
deleteItems()
}, label: {
Text("Delete")
})
Spacer()
DisclosureGroup("Tecken", isExpanded: $isExpanded) {
ScrollView{
VStack{
ForEach(signs, id: \.self) { sign in
HStack{
Text(sign.name!)
.font(.title3)
.padding(.all)
.onTapGesture {
self.isExpanded.toggle()
self.activeSign = sign
}
}
}
}
}
}
.accentColor(.white) // Arrow color
.font(.title3)
.foregroundColor(.white) // Text color
.padding(.all)
.cornerRadius(8)
.frame(minWidth: 10, maxWidth: 300)
}
.background(Color.gray)
.padding()
I am attempting my first steps using matchedgeometry and have followed some tutorials to get a simple view to expand when selected.I have two files, a card view and a content view. I would like to place all of my card views in a horizontal scrollview.
import SwiftUI
struct smallCard: View {
#State private var flag: Bool = true
#Namespace var nspace
var body: some View {
if flag {
VStack{
Image("chemex.jpg")
.resizable()
.matchedGeometryEffect(id: "image", in: nspace)
.scaledToFill()
Spacer()
Button("CHEMEX") { withAnimation(.default) { flag.toggle() } }
.matchedGeometryEffect(id: "text", in: nspace)
Spacer()
.frame(height:8)
}
.matchedGeometryEffect(id: "geoeffect1", in: nspace)
.frame(width: 100, height: 100, alignment: .center)
.background(Color.white)
.cornerRadius(20)
.shadow(color: .gray, radius: 9, x: 0, y: 9)
}
if !flag {
VStack{
Image("chemex.jpg")
.resizable()
.matchedGeometryEffect(id: "image", in: nspace)
.scaledToFit()
Spacer()
Button("CHEMEX") { withAnimation(.default) { flag.toggle() } }
.matchedGeometryEffect(id: "text", in: nspace)
Spacer()
.frame(height:20)
}
.matchedGeometryEffect(id: "geoeffect1", in: nspace)
.layoutPriority(1)
.frame(width: 300, height: 600, alignment: .center)
.background(Color.white)
.cornerRadius(20)
.shadow(color: .gray, radius: 9, x: 0, y: 9)
}
}
I the have my main content view:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
HStack{
Text("My App")
.font(.title)
.padding(.leading, 25)
Spacer()
}
ScrollView(.horizontal){
HStack{
smallCard()
.padding(.horizontal)
smallCard()
.padding(.horizontal)
smallCard()
.padding(.horizontal)
}
}
}
.frame(alignment: .center)
}
This currently works for clicking on the small card and the matched geometry animates this to the larger card. The issue I have is that this changes the height of my scrollview and as such this moves everything else such as my title up and out of view.
Effectively what I would like to achieve is like a popover view, so that this detail view is on top of all of the elements in my content view, but whilst using matchedgeometry (or an alternative solution) to animate nicely between the views.
Is this possible? I am at the point where I do not know if there is a solution to this.
var body: some View {
NavigationView
{
ScrollView
{
LazyVGrid(columns: [
GridItem(.flexible(minimum: 100, maximum: 200), spacing: 16, alignment: .top),
GridItem(.flexible(minimum: 100, maximum: 200), spacing: 16, alignment: .top)], alignment: .leading, spacing: 16, content: {
ForEach(vm.results , id: \.self) { result in
PartyInfo(result: result).onTapGesture {
NavigationLink(
destination: SelectedPlaylistView(),
label: {
Text("")
})
}//.padding(.horizontal)
//.background(Color.black)
}
}).padding(.horizontal, 20)
}
It doesn't work because it is inside the .onTapGesture it is going into the Void of the closure.
Replace
Text("")
With this
PartyInfo(result: result)
Remove the onTapGesture{} the NavigationLink has it built in.
It will give you the result you seem to trying to achieve.
My app has a SwiftUI View that contains both a TextEditor to collect a log entry and a List containing past entries.
When the text editor has a non-empty string, a button is presented to process the entry, add it to the data populating the list, and reset the TextEditor. Presently the button appears suddenly whenever text is typed, and I would love to animate that more smoothly, perhaps by fading in the opacity or scaling up the button. However, I can't figure out where to enter that animation.
#State var newEntryString = ""
var body: some View {
NavigationView{
VStack{
Text("Create a new log entry.")
.padding()
TextEditor(text: $newEntryString)
.cornerRadius(3.0)
.padding()
.border(Color.gray, width: 1)
.frame(minWidth: 0, idealWidth: 100, maxWidth: .infinity, minHeight: 0, idealHeight: 100, maxHeight: 150, alignment: .center)
HStack {
Spacer()
if !newEntryString.isEmpty{
Button(action: {
addEntry()
}) {
Text("Add Entry")
}.buttonStyle(JournalButtonStyle())
.animation(Animation.default.speed(1))
}
}
Divider()
List {
ForEach(entrys) { item in
Text(item.timestamp!, formatter: entryFormatter).font(.footnote)
.foregroundColor(.gray)
.padding(.bottom, -10)
Text((item.entryString!))
}
.onDelete(perform: deleteEntrys)
}.onTapGesture {
UIApplication.shared.endEditing()
}
Use animation on container, like
HStack {
Spacer()
if !newEntryString.isEmpty{
Button(action: {
addEntry()
}) {
Text("Add Entry")
}.buttonStyle(JournalButtonStyle())
}
}.animation(Animation.default.speed(1)) // << here !!