Custom TextField Swiftui - swift

How can I create a text field like the one shown in the figure? with background of that color and white line?
import SwiftUI
#available(iOS 16.0, *)
struct SecondView: View {
#State var nome = ""
#State var cognome = ""
var body: some View {
GeometryReader { geo in
ZStack {
Color(red: 57 / 255, green: 63 / 255, blue: 147 / 255)
Text("Ora tocca ai tuoi dati")
.font(Font.custom("Rubik", size: 22)).foregroundColor(Color.white).font(Font.body.bold()).padding(.bottom, 300).font(Font.headline.weight(.light))
Text("Per iniziare ad usare MyEntZo completa i campi qui sotto").multilineTextAlignment(.center)
.font(Font.custom("Rubik", size: 18)).foregroundColor(Color.white).font(Font.body.bold()).padding(.bottom, 80).font(Font.headline.weight(.light))
TextField("Nome", text: $nome, axis: .vertical)
.textFieldStyle(.roundedBorder)
.background(.ultraThinMaterial)
.padding().padding(.bottom, 20).padding(.top, 110).scaledToFill()
.underline()
TextField("Cognome", text: $nome, axis: .vertical)
.textFieldStyle(.roundedBorder)
.background(.ultraThinMaterial)
.padding().padding(.bottom, 20).padding(.top, 190).scaledToFill()
.underline()
Button(action: {
print("sign up bin tapped")
}){
Text("Continua")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.system(size: 18))
.padding()
.foregroundColor(.white)
.overlay(
RoundedRectangle(cornerRadius: 25)
.stroke(Color.green, lineWidth: 2)
)
}
.background(Color.green)
.cornerRadius(25).frame(width: geo.size.width - 50, height: 100)
.padding(.top, 300)
}
}
.ignoresSafeArea()
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
SecondView()
}
}

You can create a custom text field that wraps a regular TextField, passing in the #State as a #Binding, e.g.
struct CustomTextField: View {
let placeholder: String
#Binding var text: String
var body: some View {
VStack {
TextField(placeholder, text: $text)
.padding(.bottom, 4)
.foregroundColor(.white)
Color.white
.frame(height: 2)
}
.padding([.top, .bottom, .trailing])
.background(.blue)
}
}
which you can use like:
struct ContentView: View {
#State private var nome: String = ""
var body: some View {
VStack {
// etc
CustomTextField(placeholder: "Nome", text: $nome)
// etc
}
}
}

struct SecondView: View {
#State var nome = ""
#State var cognome = ""
var body: some View {
GeometryReader { geo in
ZStack {
Color(red: 57 / 255, green: 63 / 255, blue: 147 / 255)
VStack {
Spacer()
Text("Ora tocca ai tuoi dati")
.font(Font.custom("Rubik", size: 22))
.foregroundColor(.white)
.bold()
.padding()
.font(Font.headline.weight(.light))
Text("Per iniziare ad usare MyEntZo completa i campi qui sotto").multilineTextAlignment(.center)
.font(Font.custom("Rubik", size: 18)).foregroundColor(Color.white).font(Font.body.bold()).padding(.bottom, 80).font(Font.headline.weight(.light))
TextField("Nome", text: $nome, prompt: Text("Nome").foregroundColor(.white.opacity(0.7)))
.foregroundColor(.white)
.padding(.horizontal)
Rectangle()
.foregroundColor(.white)
.background(.white)
.frame(maxWidth: .infinity, maxHeight: 2)
.padding(.horizontal)
TextField("Cognome", text: $cognome, prompt: Text("Cognome").foregroundColor(.white.opacity(0.7)))
.foregroundColor(.white)
.padding([.horizontal, .top])
Rectangle()
.foregroundColor(.white)
.background(.white)
.frame(maxWidth: .infinity, maxHeight: 2)
.padding(.horizontal)
Button(action: {
print("sign up bin tapped")
}){
Text("Continua")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.system(size: 18))
.padding()
.foregroundColor(.white)
.overlay(
RoundedRectangle(cornerRadius: 25)
.stroke(Color.green, lineWidth: 2)
)
}
.background(Color.green)
.cornerRadius(25).frame(width: geo.size.width - 50, height: 100)
.padding(.top)
Spacer()
}
}
}
.ignoresSafeArea()
}
}

Related

Can't display custom pop-up because my tab view is in NavigationView

I want to display a pop-up in my view, where I will be able to display a menu where I can choose how I fell, then it will show what I have chosen and close itself. If I am adding it to the view and it's presenting It shows wrong and Tab Bar does not disappear. Can someone provide a better way to show a pop-up over Tab Bar? The logic is something like this: button pressed -> shows pop-up -> choose status -> shows another pop-up -> disappears.
Code's provided below:
// Smile face that used in question
struct SmileFace: View {
var text: String
var image: String
#Binding var current: String
var body: some View {
Button {
withAnimation {
current = text
}
} label: {
VStack {
Image(image)
.resizable()
.scaledToFill()
.frame(width: 46, height: 46)
Text(text)
.foregroundColor(.white)
}
}
}
}
// Check in answer view
import SwiftUI
struct CheckInAskView: View {
let didClose: () -> Void
var didChose: Bool = false
#State var current: String
var emotions = [
"GREAT" : "good",
"GOOD" : "happy",
"OK" : "moderate",
"BAD" : "sad",
"TERRIBLE" : "verysad"
]
var body: some View {
VStack {
ZStack(alignment: .topLeading) {
Rectangle()
.fill(Color("navigation"))
.cornerRadius(15)
.frame(height: 601)
HStack(alignment: .top) {
ZStack(alignment: .top) {
Circle()
.fill(Color(red: 0.682, green: 0.384, blue: 0.486).opacity(0.10))
.frame(width: 173)
.offset(x: -173/2, y: -90/2)
.clipped()
}
Spacer()
Button {
didClose()
} label: {
ZStack {
Circle()
.fill(Color(red: 0.933, green: 0.933, blue: 0.933).opacity(0.30))
.frame(width: 24)
.clipped()
Image(systemName: "xmark")
.font(.system(size: 15))
.foregroundColor(Color(red: 0.762, green: 0.762, blue: 0.762))
}
.padding(10)
}
}
VStack(alignment: .center) {
Spacer()
Text("How do you feel now?")
.foregroundColor(.white)
.font(.custom("Manrope-Bold", size: 16))
HStack(spacing: 35) {
SmileFace(text: "GOOD", image: "good", current: $current)
}
.padding(.horizontal)
DoubleTextView(topText: "Recommendation for you", buttomText: "We have selected courses based on your goals and \nexperience", topTextSize: 16, buttomTextSize: 14)
BigFrameScrollViewHorizontal()
Spacer()
}
}
.frame(height: 601)
}
.frame(height: 601)
.transition(.move(edge: .bottom))
}
}
// View with all views
struct CheckInView: View {
#StateObject var sheetManager: SheetManager
var body: some View {
VStack {
HStack {
Text("How do you fell now?")
.foregroundColor(.white)
.font(.custom("Manrope-Bold", size: 16))
Spacer()
Button {
} label: {
ZStack {
HStack {
Text("Pass check in")
.padding([.top, .leading, .bottom])
.foregroundColor(.white)
.font(.custom("Manrope-Medium", size: 12))
Image(systemName: "chevron.right")
.foregroundColor(.white)
.font(.system(size: 15))
.padding(.trailing)
}
}
.background(Rectangle()
.fill(Color("active"))
.cornerRadius(100)
.frame(height: 26))
}
}
VStack {
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
}
HStack {
Button {
} label: {
ZStack {
Circle()
.fill(Color("navigation"))
.frame(width: 26)
Image(systemName: "chevron.left")
.foregroundColor(.white)
.font(.system(size: 14))
}
}
Button {
} label: {
ZStack {
Circle()
.fill(Color("navigation"))
.frame(width: 26)
Image(systemName: "chevron.right")
.foregroundColor(Color("inactive"))
.font(.system(size: 14))
}
}
}
.padding(.top)
}
.padding(.horizontal, 15.0)
}
}
struct CheckInView_Previews: PreviewProvider {
static var previews: some View {
CheckInView(sheetManager: SheetManager())
.background(.yellow)
}
}
If I have all of this, how can I create a pop-up over Tab View? Maybe a link to a similar problem?

SwiftUI, different Views in same GridView

I need to add two different types of view in same grid view, there is an alignment issue between these view as shown in give image below. The view which contains image is taking more space from top and bottom even after fixing the size
struct TestView: View {
#StateObject var vm = BusinessProfileViewModel()
#Environment(\.presentationMode) private var presentationMode
let columns = [
GridItem(.flexible(minimum: 100), spacing: 20),
GridItem(.flexible(minimum: 100), spacing: 20)
]
var body: some View {
loadView()
}
}
extension TestView {
func loadView() -> some View {
GeometryReader { geometry in
ZStack(alignment: .bottomTrailing) {
ScrollView(.vertical, showsIndicators: false) {
topBusinessImage(geometry: geometry)
VStack {
featureProduct(geometry: geometry)
}.padding()
}.edgesIgnoringSafeArea(.top)
}
}
}
func topBusinessImage(geometry: GeometryProxy) -> some View {
VStack(spacing: 0) {
// Profile Image Stack
// Banner Zstack
ZStack (alignment: .top) {
Image(ImageName.productPlaceholder.rawValue)
.resizable()
.frame(height: geometry.size.height / 2.5)
}
}
}
func featureProduct(geometry: GeometryProxy) -> some View {
VStack(alignment: .leading) {
// product and services button
HStack {
Text("Products & Services")
.font(.custom(Popins.bold.rawValue, size: 20))
Spacer()
Button {
print("list")
} label: {
Image(ImageName.list.rawValue)
.resizable()
.frame(width: 24, height: 24)
}.padding(5)
}
LazyVGrid(columns: columns, spacing: 30) {
BusinessProductCell()
ProductOnlyDetailCell()
ProductOnlyDetailCell()
BusinessProductCell()
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
view that contains image
import SwiftUI
struct BusinessProductCell: View {
var body: some View {
loadView()
}
}
extension BusinessProductCell {
func loadView() -> some View {
VStack(alignment: .leading) {
ZStack(alignment: .topLeading) {
Image(ImageName.business.rawValue)
.resizable()
.frame(height: 205)
.cornerRadius(10)
HStack {
Button {
print("fav")
} label: {
Image(systemName: "heart.fill")
.resizable()
.scaledToFit()
.foregroundColor(UnifiedColor.blue)
.frame(width: 20, height: 20)
}.padding()
Spacer()
Button {
print("fav")
} label: {
Image(systemName: "ellipsis")
.resizable()
.scaledToFit()
.frame(width: 20)
.foregroundColor(.white)
}.padding()
}
}
Text("Dove Body Care")
.foregroundColor(.black)
.font(.custom(Popins.medium.rawValue, size: 16))
HStack {
Text("$49.99")
.font(.custom(Popins.medium.rawValue, size: 12))
.foregroundColor(UnifiedColor.textBlue)
Spacer()
HStack {
Text("(286 Favorites)")
.font(.custom(Popins.regular.rawValue, size: 8))
.foregroundColor(.gray)
Image(ImageName.heart_line.rawValue)
.resizable()
.frame(width: 15, height: 15)
}
}
}
}
}
struct BusinessProductCell_Previews: PreviewProvider {
static var previews: some View {
BusinessProductCell()
.frame(width: 200, height: 250)
}
}
View that only contains text or second view for gird view
struct ProductOnlyDetailCell: View {
var body: some View {
loadView()
}
}
extension ProductOnlyDetailCell {
func loadView() -> some View {
VStack(alignment: .leading, spacing: 10) {
HStack {
Image(ImageName.productPlaceholder.rawValue)
.resizable()
.scaledToFill()
.frame(width: 24, height: 24)
.clipShape(Circle())
.overlay {
Circle().stroke(.white, lineWidth: 1)
}
Text("Anton Jr.")
.font(.custom(Popins.regular.rawValue, size: 12 ))
.foregroundColor(.black)
.lineLimit(1)
Spacer()
Button {
print("more btn")
} label: {
Image(systemName: "ellipsis")
.resizable()
.foregroundColor(.black)
.frame(width: 18, height: 4)
.padding([.trailing, .top, .bottom])
}
}
Text("DJ for night")
.font(.custom(Popins.bold.rawValue, size: 14))
.foregroundColor(.black)
Text("Lorem ipsum dolor sitamet, consectetur adipiscingelit. Lectus idcommodoegestas metusinterdum dolor.")
.multilineTextAlignment(.leading)
.font(.custom(Popins.regular.rawValue, size: 12))
.foregroundColor(.black)
.opacity(0.8)
Spacer()
HStack (spacing: 0){
Text("$15K")
.font(.custom(Popins.bold.rawValue, size: 14))
.foregroundColor(.black)
Text("/")
.font(.custom(Popins.bold.rawValue, size: 14))
.foregroundColor(.gray)
Text("Night")
.font(.custom(Popins.regular.rawValue, size: 14))
.foregroundColor(.gray)
}
Text("25 minute ago")
.font(.custom(Popins.regular.rawValue, size: 10))
.foregroundColor(.gray)
}
.padding(10)
.background(
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.gray.opacity(0.1))
)
}
}

I'd like to use the navigation link.Newbie Wang is in the process of hair loss

I want to use Navigationlink. I've been a novice for 2 weeks since I started.I am currently learning SwiftUi.
I created "OnboredView" after watching YouTube, but I don't know how to connect "OnboredView" to "CountentView".
NavigationView(){
NavigationLink(destination: OnboardView())
I learned how to make it like this through YouTube, but I don't know what to do now. I put it here and there, but the red errors bother me.
Tell me how to connect "NavigationLink" by pressing the button on "CountentView".
I'd like to click "Chevron.Light" to move on to "OnboredView."And if possible, please let me know how I can get rid of the "onboard screen" on the second run?
I am not good at English.I'm sorry. I'm experiencing hair loss again.
import SwiftUI
struct ContentView: View {
#State private var animate: Bool = false
var body: some View {
ZStack{
ZStack{
Image("rogo1")
.resizable()
.frame(width: 75, height: 75)
.offset(y: animate ? -100 : 0)
}
ZStack{
Image("rogo2")
.resizable()
.frame(width: 75, height: 75)
.offset(y: animate ? -100 : 0)
}
VStack {
HStack {
Spacer()
Image("images (1)")
.resizable()
.frame(width: 300, height: 300)
.offset(x: animate ? 300 : 150, y: animate ? -300 : -150)
}
Spacer()
HStack {
Image("images (1)")
.resizable()
.frame(width: 400, height: 400)
.offset(x: animate ? -500 : -150, y: animate ? 500 : 150)
Spacer()
}
}
ZStack(alignment: .bottom){
GeometryReader { g in
VStack (alignment: .leading, spacing: 20){
Text("안녕하세요!")
.font(.title)
.fontWeight(.semibold)
.padding(.top, 20)
//인삿말과 회원가입
Text("기분 좋은 매일습관을 만들기 위한 앱 ( ) 입니다! 시간표와 더불어 루틴을 함께 할수
있도록 설계 되었습니다.저희 ( )와 함께 계획해봐요!")
.fontWeight(.medium)
.multilineTextAlignment(.center)//중앙으로 결집
.padding(5)
ZStack {
Button(action: {},label: {
Image(systemName: "chevron.right")
.font(.system(size:20, weight: .semibold))
.frame(width: 60, height: 60)
.foregroundColor(.black)
.background(Color.white)
.clipShape(Circle())
.overlay(
ZStack {
Circle()
.stroke(Color.black.opacity(0.04),lineWidth: 4)
Circle()
.trim(from: 0, to: 0.03)
.stroke(Color.white,lineWidth: 4)
.rotationEffect(.init(degrees: -40))
})
})
.padding(-10)
}
Spacer()
}
.frame(maxWidth: .infinity)
.padding(.horizontal, 30)
.background(Color.green)
.clipShape(CustomShape(leftCorner: .topLeft, rightCorner: .topRight,
radii: 20))
.offset(y: animate ? g.size.height : UIScreen.main.bounds.height)
}
}.frame(height: 275)
//여기까지 짤라도 됨 온보드
}
.frame(maxWidth: .infinity)
.edgesIgnoringSafeArea(.all)
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
withAnimation(Animation.easeOut(duration: 0.45)){
animate.toggle()
}
}
})
}
{
struct CustomShape: Shape {
var leftCorner: UIRectCorner
var rightCorner: UIRectCorner
var radii: CGFloat
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners:
[leftCorner,rightCorner], cornerRadii: CGSize(width: radii, height: radii))
return Path(path.cgPath)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
Group {
}
}
}
}
import SwiftUI
struct OnboardView: View {
#AppStorage("currentPage") var currentPage = 1
var body: some View {
if currentPage > totalPages {
Home()
}else{
WalkthroughScreen()
}
}
}
struct OnboardView_Previews: PreviewProvider {
static var previews: some View {
OnboardView()
}
}
struct Home: View {
var body: some View{
Text("welcome To Home!!!")
.font(.title)
.fontWeight(.heavy)
}
}
//..Walkthrough Screen..
struct WalkthroughScreen: View {
#AppStorage("currentPage") var currentPage = 1
var body: some View {
//For Slide Animation
ZStack{
//Changing Between Views..
if currentPage == 1 {
ScreenView(image: "image1", title: "Step1", detail: "", bgColor:
Color(.white))
//transition(.scale)영상에서는 넣었으나 오류가나서 사용하지 못함
}
if currentPage == 2 {
ScreenView(image: "image2", title: "Step2", detail: "", bgColor:
Color(.white))
}
if currentPage == 3 {
ScreenView(image: "image3", title: "Step3", detail: "아니 ㅡㅡ 이런 방법이 유레카",
bgColor: Color(.white))
}
}
.overlay(
Button(action: {
//changing views
withAnimation(.easeInOut){
if currentPage < totalPages {
currentPage += 1
}else{
currentPage = 1
//For app testing ONly
}
}
}, label: {
Image(systemName: "chevron.right")
.font(.system(size: 20, weight: .semibold))
.foregroundColor(.black)
.frame(width: 60, height: 60)
.clipShape(Circle())
//strclulat Slider
.overlay(
ZStack{
Circle()
.stroke(Color.black.opacity(0.04),lineWidth: 4
Circle()
.trim(from: 0, to: CGFloat(currentPage) /
CGFloat(totalPages))
.stroke(Color.green,lineWidth: 4)
.rotationEffect(.init(degrees: -99))
}
.padding(-15)
)
})
.padding(.bottom,20)
,alignment: .bottom
)
}
}
struct ScreenView: View {
var image: String
var title: String
var detail: String
var bgColor: Color
#AppStorage("currentPage") var currentPage = 1
var body: some View {
VStack(spacing:20){
HStack {
//Showing it only for first page..
if currentPage == 1{
Text("Hello Members!")
.font(.title)
.fontWeight(.semibold)
//Letter Spacing
.kerning(1.4)
}else{
//Back Butten..
Button(action: {
withAnimation(.easeInOut){
currentPage -= 1
}
}, label: {
Image(systemName: "chevron.left")
.foregroundColor(.white)
.padding(.vertical,10)
.padding(.horizontal)
.background(Color.black.opacity(0.4))
.cornerRadius(10)
})
}
Spacer()
Button(action: {
withAnimation(.easeInOut){
currentPage = 4
}
}, label: {
Text("Skip")//글자입력
.fontWeight(.semibold)//글자 폰트변경
.kerning(1.2)//글자간 간격 조정
})
}
.foregroundColor(.black)//그라운드 컬러 변경
.padding()
Spacer(minLength: 0)//수평,수직 줄바꿈
Image(image)//이미지 삽입
.resizable()//크기 확대
.aspectRatio(contentMode: .fit)//이미지 크기
Text(title)
.font(.title)//폰트 크기변경
.fontWeight(.bold)//폰트 두께 변경
.foregroundColor(.black)//색깔 변경
.padding(.top)
//Change with your Own Thing..
Text(detail)
.fontWeight(.semibold)
.kerning(1.3)//자간조정
.multilineTextAlignment(.center)//텍스트를 중앙으로 결집
Spacer(minLength: 220)//minimun Spacing When phone is reducing수직위치 조정
}
.background(bgColor.cornerRadius(10).ignoresSafeArea())
}
}
var totalPages = 3

Autolayout in SwiftUI

Good afternoon community,
Any way to autolayout in swiftui so that my view looks good both in portrait and landscape?
I've already tried everything with geometry render and frame (.infinity) but I can't get it.
someone who has managed to be able to have his ap in both modes with swuftui?
I attach my code and a couple of images.
import SwiftUI
struct OnBoardingView: View {
var ImageOnTop:some View{
Image("headerPicture")
.resizable()
}
var Title:some View {
Text("Hey You")
.font(.custom("Montserrat-Medium", size: 48))
.foregroundColor(.white)
}
var subTitle:some View{
Text("Out With A Porpuse ")
.font(.custom("Montserrat-SemiBold", size: 16))
.foregroundColor(.white)
}
var secondSubtitle:some View{
Text("Find and build communities with people in your area. \n #GoodbyeCatfish \n #HellowConnections")
.font(.custom("Montserrat-Regular", size: 16))
.foregroundColor(.white)
.multilineTextAlignment(.center)
}
var navigatinButton:some View{
VStack(alignment:.center){
NavigationLink(
destination: CreateAccountView(),
label: {
Text("Create Account")
})
.font(.custom("Montserrat-Medium", size: 18))
.foregroundColor(.white)
.frame(width: 230, height: 42, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 18)
.stroke(Color.yellow, lineWidth: 1.8))
HStack{
Text("Already have an account?")
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.white)
.multilineTextAlignment(.leading)
NavigationLink(
destination: LoginView(LoginViewM: LoginViewModel()),
label: {
Text("Log In")
})
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.yellow)
}
}
}
var lastString: some View{
HStack{
Text("By using this app you agree with the")
.foregroundColor(.white)
.font(.custom("Montserrat-Medium", size: 11))
Text("terms of services")
.underline(true, color: .yellow)
.foregroundColor(.yellow)
.font(.custom("Montserrat-Medium", size: 11))
}
.padding(30)
}
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack(spacing:40){
VStack(alignment: .center,spacing:15){
ImageOnTop
.frame(width: geometry.size.width, height: 270)
Title
subTitle
}
.frame(width: geometry.size.width, height: 270)
secondSubtitle
.frame(width: geometry.size.width, height: 75, alignment: .center)
.padding(30)
navigatinButton
Spacer(minLength: 14)
lastString
Spacer().frame(height:20)
}
.edgesIgnoringSafeArea(.all)
.background(Color.black)
}
.frame(width: geometry.size.width, height: geometry.size.height)
.navigationBarBackButtonHidden(true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
OnBoardingView()
.previewDevice(PreviewDevice(rawValue: "iPhone 12"))
.previewDisplayName("iPhone 12")
}
}
Here is a version of your code that works for all screen sizes and positions. Less is more in SwiftUI. The more the hardcoded values the harder it is for SwiftUI to do the adjusting.
struct OnBoardingView: View {
var ImageOnTop:some View{
//Just to simulate,I switched to a system image you will have to adjust for your own
Image(systemName: "square")
.resizable()
.foregroundColor(.blue)
}
var Title:some View {
Text("Hey You")
.font(.custom("Montserrat-Medium", size: 48))
.foregroundColor(.white)
}
var subTitle:some View{
Text("Out With A Porpuse ")
.font(.custom("Montserrat-SemiBold", size: 16))
.foregroundColor(.white)
}
var secondSubtitle:some View{
VStack{
Text("Find and build communities with people in your area.")
.lineLimit(1)
Text("#GoodbyeCatfish \n #HellowConnections")
}
.font(.custom("Montserrat-Regular", size: 16))
.foregroundColor(.white)
.multilineTextAlignment(.center)
.minimumScaleFactor(0.5)
}
var navigatinButton:some View{
VStack(alignment:.center){
NavigationLink(
destination: Text("CreateAccountView()"),
label: {
Text("Create Account")
})
.font(.custom("Montserrat-Medium", size: 18))
.foregroundColor(.white)
//Don't fix the size or thre won't be any differences between devices
.frame(minWidth: 0, idealWidth: 230, maxWidth: 230, minHeight: 0, idealHeight: 42, maxHeight: 42, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 18)
.stroke(Color.yellow, lineWidth: 1.8))
HStack{
Text("Already have an account?")
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.white)
.multilineTextAlignment(.leading)
NavigationLink(
destination: Text("LoginView(LoginViewM: LoginViewModel()"),
label: {
Text("Log In")
})
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.yellow)
}
}
}
var lastString: some View{
HStack{
Text("By using this app you agree with the")
.foregroundColor(.white)
.font(.custom("Montserrat-Medium", size: 11))
Text("terms of services")
.underline(true, color: .yellow)
.foregroundColor(.yellow)
.font(.custom("Montserrat-Medium", size: 11))
}
.padding(30)
}
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack{
ImageOnTop
.frame(height: geometry.size.height * 0.2)
VStack{
Title
subTitle
}.frame(height: geometry.size.height * 0.25)
Spacer()
secondSubtitle
//You can give spaces more weight by addign spacers
//This makes the space above the button twice as wide as the bottom
Spacer()
Spacer()
navigatinButton
Spacer()
lastString
}
.background(Color.black)
.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
}
.navigationBarBackButtonHidden(true)
}
}
}

#State var only changes after second button click SwiftUI

Hello I apologize for my ignorance if this is an overdone or overly simple question. I am using SwiftUI and want my page to have multiple buttons that all send emails with different subject and message bodies. Everything currently works although only after the second time I click a button. The first time the subject is my initialized var ("start") regardless of button.
Another small thing, when I click the same button repeatedly it never updates until I click a different one.
Thank you very much, attached is code, I left out my mailcompose swift file as it all works as expected.
import SwiftUI
import MessageUI
import Foundation
struct ContentView: View {
#State var result: Result<MFMailComposeResult, Error>? = nil
#State private var showSheet = false
#State private var subject: String = "start"
#State private var msgBody: String = ""
let numberString = "201-228-0752"
var body: some View {
ZStack{
Color.white.ignoresSafeArea()
VStack{
Image("Icon-1024")
.resizable()
.aspectRatio(contentMode: .fit)
.clipShape(Circle())
.shadow(radius: 10)
.overlay(Circle().stroke(Color.black, lineWidth: 3))
.frame(width: 50, height: 50, alignment: .center)
.padding(.top, 10)
Text("Contact Us")
.foregroundColor(.black)
.fontWeight(.heavy)
.font(.title)
.padding()
Text("Be part of something bigger.")
.foregroundColor(.black)
.fontWeight(.medium)
.font(.system(size: 20))
.padding()
.padding(.bottom, 5)
.multilineTextAlignment(.center)
Spacer()
VStack(spacing: 0){
Button(action: {
self.subject = "General"
self.msgBody = "Hello, I need help."
self.suggestFeature()
}){
HStack {
Spacer()
Text("General help")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 1.00, green: 0.49, blue: 0.51))
Button(action: {
self.subject = "Technical"
self.msgBody = "Hello, I am having technical difficulties"
self.suggestFeature()
}){
HStack {
Spacer()
Text("Technical issues")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 0.81, green: 0.39, blue: 0.40))
Button(action: {
self.subject = "Gender"
self.msgBody = "Hello, I would like to make a gender or sexuality request."
self.suggestFeature()
}){
HStack {
Spacer()
Text("Gender & Sexuality")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 0.62, green: 0.29, blue: 0.30))
Button(action: {
self.subject = "Delete"
self.msgBody = "Hello, I would like to request a delete of my info."
self.suggestFeature()
}){
HStack {
Spacer()
Text("Delete info")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 0.45, green: 0.19, blue: 0.20))
Button(action: {
let telephone = "tel://"
let formattedString = telephone + numberString
guard let url = URL(string: formattedString) else { return }
UIApplication.shared.open(url)
}){
HStack {
Spacer()
(Text("Call ") + Text(Image(systemName: "phone.fill")))
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(.black))
Spacer()
Text("© Copyright Sixish, Inc.")
.padding(.bottom, 30)
.foregroundColor(.gray)
}.sheet(isPresented: $showSheet) {
MailView(result: self.$result, newSubject: self.subject, newMsgBody: self.msgBody)
}
}
}
}
func suggestFeature() {
print("You've got mail")
if MFMailComposeViewController.canSendMail() {
self.showSheet = true
} else {
print("Error sending mail")
// Alert : Unable to send the mail
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
This is a classic issue that gets run into a lot with sheet() on SwiftUI. The gist is that your sheet's content view can get rendered before it actually appears and before the #State variables' changes propagate to it.
The fix is to use sheet(item:):
struct Message : Identifiable, Hashable {
var id = UUID()
var subject : String
var body : String
}
struct ContentView: View {
//#State var result: Result<MFMailComposeResult, Error>? = nil
#State private var showSheet = false
#State private var message : Message?
let numberString = "201-228-0752"
var body: some View {
ZStack{
Color.white.ignoresSafeArea()
VStack{
Image("Icon-1024")
.resizable()
.aspectRatio(contentMode: .fit)
.clipShape(Circle())
.shadow(radius: 10)
.overlay(Circle().stroke(Color.black, lineWidth: 3))
.frame(width: 50, height: 50, alignment: .center)
.padding(.top, 10)
Text("Contact Us")
.foregroundColor(.black)
.fontWeight(.heavy)
.font(.title)
.padding()
Text("Be part of something bigger.")
.foregroundColor(.black)
.fontWeight(.medium)
.font(.system(size: 20))
.padding()
.padding(.bottom, 5)
.multilineTextAlignment(.center)
Spacer()
VStack(spacing: 0){
Button(action: {
self.message = Message(subject: "General", body: "Hello, I need help.")
self.suggestFeature()
}){
HStack {
Spacer()
Text("General help")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 1.00, green: 0.49, blue: 0.51))
Button(action: {
self.message = Message(subject: "Technical", body: "Hello, I am having technical difficulties")
self.suggestFeature()
}){
HStack {
Spacer()
Text("Technical issues")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 0.81, green: 0.39, blue: 0.40))
Button(action: {
self.message = Message(subject: "Gender", body: "Hello, I would like to make a gender or sexuality request.")
self.suggestFeature()
}){
HStack {
Spacer()
Text("Gender & Sexuality")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 0.62, green: 0.29, blue: 0.30))
Button(action: {
self.message = Message(subject: "Delete", body: "Hello, I would like to request a delete of my info.")
self.suggestFeature()
}){
HStack {
Spacer()
Text("Delete info")
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(red: 0.45, green: 0.19, blue: 0.20))
Button(action: {
let telephone = "tel://"
let formattedString = telephone + numberString
guard let url = URL(string: formattedString) else { return }
UIApplication.shared.open(url)
}){
HStack {
Spacer()
(Text("Call ") + Text(Image(systemName: "phone.fill")))
.font(.system(size: 25))
.fontWeight(.medium)
.foregroundColor(.white)
.padding(.top, 15)
.padding(.bottom, 15)
Spacer()
}
}
.background(Color(.black))
Spacer()
Text("© Copyright Sixish, Inc.")
.padding(.bottom, 30)
.foregroundColor(.gray)
}.sheet(item: $message) { item in
MailView(message: item)
//your code would probably need to be more like MailView(result: self.$result, newSubject: item.subject, newMsgBody: item.body)
}
}
}
}
func suggestFeature() {
print("You've got mail")
if MFMailComposeViewController.canSendMail() {
self.showSheet = true
} else {
print("Error sending mail")
// Alert : Unable to send the mail
}
}
}
struct MailView : View {
var message : Message
var body: some View {
Text(message.subject)
Text(message.body)
}
}
Note that now, your sheet is displayed if message has an item it it. Message is now a struct.
I simplified things a little bit since I didn't have your MailView container (and I temporarily commented out your result property), but the concept presented here should get you started doing what you need to do.