Change View Swift ui - ios

the swift code below represents two views the first that is displayed is home with the login button and the register button, what I have to do is that when the SIGNUP button is clicked the push to the HomeView view which contains the MapView, practically I have to push to the new view with the click on signup, but with the navigationlink this does not show me the view, how do I solve this?
Home.Swift
import SwiftUI
import MapKit
struct HomeView: View {
#State private var userTrackingMode: MapUserTrackingMode = .follow
#State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(
latitude: 25.7617,
longitude: 80.1918
),
span: MKCoordinateSpan(
latitudeDelta: 10,
longitudeDelta: 10
)
)
var body: some View {
Map(
coordinateRegion: $region,
interactionModes: MapInteractionModes.all,
showsUserLocation: true,
userTrackingMode: $userTrackingMode
)
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
ContectView.Swift
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
LinearGradient(gradient: .init(colors: [Color("Color"), Color("Color1"), Color("Color2")]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
if UIScreen.main.bounds.height > 800 {
Home()
}
else {
ScrollView(.vertical, showsIndicators: false) {
Home()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Home: View {
#State var index = 0
#State var showingDetail = false
#State var isModal: Bool = false
func login() {
}
var body: some View {
VStack {
Image("logo")
.resizable()
.frame(width: 200, height: 180)
HStack {
Button(action: {
withAnimation(.spring(response: 0.8, dampingFraction: 0.5, blendDuration: 0.5)) {
self.index = 0
}
}) {
Text("Login")
.foregroundColor(self.index == 0 ? .black : .white)
.fontWeight(.bold)
.padding(.vertical, 10)
.frame(width: (UIScreen.main.bounds.width - 50) / 2).sheet(isPresented: $isModal, content: {
})
}.background(self.index == 0 ? Color.white : Color.clear)
.clipShape(Capsule())
Button(action: {
withAnimation(.spring(response: 0.8, dampingFraction: 0.5, blendDuration: 0.5)) {
self.index = 1
}
}) {
Text("New User")
.foregroundColor(self.index == 1 ? .black : .white)
.fontWeight(.bold)
.padding(.vertical, 10)
.frame(width: (UIScreen.main.bounds.width - 50) / 2)
}.background(self.index == 1 ? Color.white : Color.clear)
.clipShape(Capsule())
}.background(Color.black.opacity(0.1))
.clipShape(Capsule())
.padding(.top, 25)
if self.index == 0 {
Login(mail: "", pass: "", areYouGoingToSecondView: false)
}
else {
SignUp()
}
if self.index == 0 {
Button(action: {
}) {
Text("Forget Password?")
.foregroundColor(.white)
}
.padding(.top, 20)
}
}
.padding()
}
}
struct Login: View {
#State var mail = ""
#State var pass = ""
#State var areYouGoingToSecondView: Bool = false
var body: some View {
VStack {
VStack {
HStack(spacing: 15) {
Image(systemName: "envelope")
.foregroundColor(.black)
TextField("Enter Email Address", text: self.$mail)
}.padding(.vertical, 20)
Divider()
HStack(spacing: 15) {
Image(systemName: "lock")
.resizable()
.frame(width: 15, height: 18)
.foregroundColor(.black)
SecureField("Password", text: self.$pass)
Button(action: {
}) {
Image(systemName: "eye")
.foregroundColor(.black)
}
}.padding(.vertical, 20)
}
.padding(.vertical)
.padding(.horizontal, 20)
.padding(.bottom, 40)
.background(Color.white)
.cornerRadius(10)
.padding(.top, 25)
Button(action: {
print("Prova di stampa")
}) {
Text("LOGIN")
.foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.frame(width: UIScreen.main.bounds.width - 100)
}.background(
LinearGradient(gradient: .init(colors: [Color("Color2"), Color("Color1"), Color("Color")]), startPoint: .leading, endPoint: .trailing)
)
.cornerRadius(8)
.offset(y: -40)
.padding(.bottom, -40)
.shadow(radius: 15)
}
}
}
struct SignUp: View {
#State var mail = ""
#State var pass = ""
#State var checkpass = ""
#State var repass = ""
#State var name = ""
#State var surname = ""
func signup() -> Bool {
print("Sono in signup")
/*let u = User(email: self.mail, name: self.name, password: self.pass, surname: self.surname)
DispatchQueue.main.asyncAfter(deadline: .now(), execute: {
u.register(completion: { result in
print("\n Risultato:")
print(result)
}
)
}
)*/
NavigationLink(destination: HomeView()) {
Text("Show Detail View")
}
return true
}
var body: some View {
VStack {
VStack {
HStack(spacing: 15) {
Image(systemName: "envelope")
.foregroundColor(.black)
TextField("Enter Email Address", text: self.$mail)
}.padding(.vertical, 20)
Divider()
HStack(spacing: 15) {
Image(systemName: "person")
.resizable()
.frame(width: 15, height: 18)
.foregroundColor(.black)
TextField("Enter Name", text: self.$name)
}.padding(.vertical, 20)
Divider()
HStack(spacing: 15) {
Image(systemName: "person")
.resizable()
.frame(width: 15, height: 18)
.foregroundColor(.black)
TextField("Enter Surname", text: self.$surname)
}.padding(.vertical, 20)
HStack(spacing: 15) {
Image(systemName: "lock")
.resizable()
.frame(width: 15, height: 18)
.foregroundColor(.black)
SecureField("Password", text: self.$pass)
Button(action: {
}) {
Image(systemName: "eye")
.foregroundColor(.black)
}
}.padding(.vertical, 20)
Divider()
HStack(spacing: 15) {
Image(systemName: "lock")
.resizable()
.frame(width: 15, height: 18)
.foregroundColor(.black)
SecureField("Re-Enter Password", text: self.$checkpass)
Button(action: {
}) {
Image(systemName: "eye")
.foregroundColor(.black)
}
}.padding(.vertical, 20)
}
.padding(.vertical)
.padding(.horizontal, 20)
.padding(.bottom, 40)
.background(Color.white)
.cornerRadius(10)
.padding(.top, 25)
//Button for signup user
Button(action: {
signup()
}) {
Text("SIGNUP")
.foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.frame(width: UIScreen.main.bounds.width - 100)
}.background(
LinearGradient(gradient: .init(colors: [Color("Color2"), Color("Color1"), Color("Color")]), startPoint: .leading, endPoint: .trailing)
)
.cornerRadius(8)
.offset(y: -40)
.padding(.bottom, -40)
.shadow(radius: 15)
}
}
}

Related

Reload body items once data from service layer loads in swiftUI

I'm new to the swiftUI, looking for a way to refresh view once service data retrieved. What I want is, once page loads, -or before page loads- I want to call fillUI function so I can retrieve parsed json data from service layer, with that data I want to refresh this code block so my foreach block works with data I have:
VStack(spacing:15 ) {
ScrollView(.horizontal) {
VStack {
ForEach(0..<5) { i in
MeetingCellView(meetingData: meetingListData?.get(at: i) )
.frame(width: 340, height: 150)
.padding(.horizontal)
}.frame(width: 350)
}
}.frame(width: 350)
}
In UIKit, i was able to solve these issues with a way like loading and retrieving all the data first, then showing the view itself with a data. For swiftUI what is the best approach to do that?
Here is the full code of my related view body. I had searched internet but couldn't find the one yet.
import SwiftUI
struct HomeView: View {
#State var username: String = ""
#State var meetingCode: String = ""
#State var data: GetUserDetailModel? = nil
#State var meetingListData: [Datum]? = nil
#State var requestLoaded = false
var body: some View {
ZStack{
VStack {
Image("home.background")
.resizable()
.frame(maxHeight: 338)
Spacer()
ZStack {
VStack {
RoundedRectangle(cornerRadius: 8)
.padding(.top, -20)
.foregroundColor(.white)
}
ScrollView(.vertical, showsIndicators: false)
{
//MARK: - ScrollView Start
VStack {
HStack(spacing: 13.0) {
NavigationLink(destination: CreateMeetingView()) {
ZStack {
RoundedRectangle(cornerRadius: 12)
.foregroundColor(Color(red: 0.935, green: 0.914, blue: 0.957))
VStack(spacing: 18) {
HStack {
Image("icon.camera")
Spacer()
}
HStack {
Text("New Meeting")
.foregroundColor(Color(red: 0.476, green: 0.228, blue: 0.701))
.font(.custom("inter-semibold", size: 15))
Spacer()
}
}.padding(.horizontal, 15)
}.frame(maxWidth: .infinity, idealHeight: 101)
.padding(.leading, 25)
}
NavigationLink(destination: Text("there"))
{
ZStack {
RoundedRectangle(cornerRadius: 12)
.foregroundColor(Color(red: 0.897, green: 0.939, blue: 0.978))
VStack(spacing: 18) {
HStack {
Image("icon.calendar")
Spacer()
}
HStack {
Text("Schedule Now")
.foregroundColor(Color(red: 0.038, green: 0.525, blue: 0.917))
.font(.custom("inter-semibold", size: 15))
Spacer()
}
}.padding(.horizontal, 15)
}.frame(maxWidth: .infinity, idealHeight: 101)
.padding(.trailing, 25)
}
}
}
VStack {
HStack {
Text("Upcoming Meetings")
.font(.custom("inter-semibold", size: 17))
.padding(.leading, 25)
Spacer()
}
ZStack {
VStack(spacing: 30) {
HStack {
Image("upcoming.calendar")
}
HStack {
Text("You do not have a upcoming meeting.")
.font(.custom("inter-regular", size: 15))
.foregroundColor(Color(red: 0.692, green: 0.692, blue: 0.692))
}
}.hidden()
.padding(.vertical, 46)
VStack(spacing:15 ) {
ScrollView(.horizontal) {
VStack {
ForEach(0..<5) { i in
MeetingCellView(meetingData: meetingListData?.get(at: i) )
.frame(width: 340, height: 150)
.padding(.horizontal)
}.frame(width: 350)
}
}.frame(width: 350)
}
}
.padding(.horizontal ,15)
}.padding(.top, 25)
.padding(.bottom, 100)
//MARK: ScrollView End
}
}
}.ignoresSafeArea()
VStack {
HStack {
Image("splash.logo")
.resizable()
.frame(maxWidth: 100, maxHeight: 20)
.padding(.leading, 24)
Spacer()
Image("icon.profile")
.padding(.trailing,25)
}
VStack(spacing: 10.0) {
HStack {
Text("Good Morning,")
.font(.custom("inter-semibold", size: 13))
.foregroundColor(.white)
Spacer()
}
HStack {
Text(username)
.font(.custom("inter-semibold", size: 22))
.foregroundColor(.white)
Spacer()
}
}.padding(.leading, 24)
ZStack {
Color.white
VStack(spacing: 10.0) {
HStack {
Text("Join Meeting")
.font(.custom("inter-semibold", size: 13))
Spacer()
}
HStack {
TextField("Enter meeting code", text: $meetingCode)
.font(.custom("inter-regular", size: 15))
.keyboardType(.numbersAndPunctuation)
}
}.padding(.horizontal, 15)
}
.cornerRadius(6)
.frame(maxWidth: .infinity, maxHeight: 75.0)
.padding(.horizontal, 25.0)
.padding(.top, 30)
Spacer()
}.hiddenNavigationBarStyle()
}
.onAppear(perform: fillUI)
}
func fillUI() {
username = data?.givenName ?? "error"
Network.meetingList {meetings in
//print(meetings)
meetingListData = meetings?.data
requestLoaded = true
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
We use task(priority:_:) for that, .e.g
List {
ForEach(meetings) { meeting in
MeetingView(meeting: meeting)
}
}
.navigationTitle(loaded ? "Meetings" : "Loading...")
.task {
loaded = false
meetings = await Meeting.fetchAll()
loaded = true
}
Also your body is far too large and you have too many #State. Break it up into subviews and try to only have 1 or 2 #State per View.

How to set the background of a View in SwiftUI

I'm making a swiftui app, I have a NavigationView that contains a VStack and a List inside.
I've tried to put the following line of code in a lot of places .background(Color.blue) but it had no effect anywhere (nothing happened).
How can I set a background for the view itself?
I know it’s a very simple thing, but it doesn’t work out at all...
This is my code:
struct ContentView: View {
#Environment(\.managedObjectContext) var managedObjectContext
#FetchRequest(entity: Todo.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Todo.name, ascending: true)]) var todos: FetchedResults<Todo>
#State private var showingAddTodoView: Bool = false
#State private var animatingButton: Bool = false
var body: some View {
NavigationView {
ZStack {
List {
ForEach(self.todos, id: \.self) { todo in
HStack {
Circle()
.frame(width: 12, height: 12, alignment: .center)
.foregroundColor(self.colorize(priority: todo.priority ?? "Normal"))
Text(todo.name ?? "Unknown")
.fontWeight(.semibold)
Spacer()
Text(todo.priority ?? "Unkown")
.font(.footnote)
.foregroundColor(Color(UIColor.systemGray2))
.padding(3)
.frame(minWidth: 62)
.overlay(
Capsule().stroke(Color(self.colorize(priority: todo.priority ?? "Normal")), lineWidth: 0.75)
)
Spacer()
Image(systemName: todo.completed ? "checkmark.square": "square")
.foregroundColor(todo.completed ? .green : .black)
.onTapGesture {
self.updateTodo(todo)
}
}
.padding(.vertical, 10)
}
.onDelete(perform: deleteTodo)
}
.navigationBarTitle("Todos", displayMode: .inline)
.navigationBarItems(
leading: EditButton(),
trailing:
Button(action: {
self.showingAddTodoView.toggle()
}) {
Image(systemName: "plus")
}
.sheet(isPresented: $showingAddTodoView) {
AddTodoView().environment(\.managedObjectContext, self.managedObjectContext)
}
)
if todos.count == 0 {
NoTodosView()
}
}
.sheet(isPresented: $showingAddTodoView) {
AddTodoView().environment(\.managedObjectContext, self.managedObjectContext)
}
.overlay(
ZStack {
Group {
Circle()
.fill(Color.blue)
.opacity(self.animatingButton ? 0.2 : 0)
.scaleEffect(self.animatingButton ? 1 : 0)
.frame(width: 68, height: 68, alignment: .center)
Circle()
.fill(Color.blue)
.opacity(self.animatingButton ? 0.15 : 0)
.scaleEffect(self.animatingButton ? 1 : 0)
.frame(width: 88, height: 88, alignment: .center)
}
.animation(Animation.easeInOut(duration: 2).repeatForever(autoreverses: true))
Button(action: {
self.showingAddTodoView.toggle()
}) {
Image(systemName: "plus.circle.fill")
.resizable()
.scaledToFit()
.background(Circle().fill(Color("Color")))
.frame(width: 48, height: 48, alignment: .center)
}
.onAppear(perform: {
self.animatingButton.toggle()
})
}
.padding(.bottom, 15)
.padding(.trailing, 15)
, alignment: .bottomTrailing
)
}
}
I want to set the background color for this view:
try this...
struct ContentView: View {
var body: some View {
UITableView.appearance().backgroundColor = .clear
UITableViewCell.appearance().backgroundColor = .clear
return NavigationView {
ZStack {
Color.blue
.edgesIgnoringSafeArea(.all)
List{
ForEach((1...5), id: \.self){_ in
HStack{
Text("item")
}
}
// .listRowBackground(Color.blue)
}
}
}
}
}

SwiftUI - Dismiss a popup and add a button to the current main view , when a button in the popup is clicked

I'm new to swiftUI.
I have a button, on its click I'm displaying a popup view. When close button in the popup is clicked it should dismiss the popupview and add a new button onto the main view. Any help is appreciated. Here's my code
struct SelectLocation: View {
#State private var showPopUp = false
#State private var passCode: String = ""
var body: some View {
ZStack{
VStack{
Button(action: {
withAnimation {
self.showPopUp = true
}
}, label: {
Text("Select Location")
.frame(minWidth: 0, maxWidth: 500)
.padding()
.background(Color.clear)
.foregroundColor(Color.black)
.font(.custom("Open Sans", size: 18))
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 2)
)
})
if(self.showPopUp){
popupPassCode()
}
}
}
}
func popupPassCode()-> some View {
VStack{
SecureField("Enter Code", text: $passCode)
.frame(width: 300, height: 50, alignment: .leading)
.cornerRadius(3.0)
.overlay(RoundedRectangle(cornerRadius: 3.0)
.stroke(Color.gray, lineWidth: 1)
)
.padding()
Button(action: {
withAnimation {
self.showPopUp = false
self.showsCorrectOrIncorrect = true
}
}, label: {
Text("Enter")
.frame(width: 150, height: 30)
.padding()
.background(Color.red)
.foregroundColor(Color.white)
.font(.custom("Open Sans", size: 28))
})
if showsCorrectOrIncorrect {
btnStart()
}
}
.padding()
.frame(width: 440, height: 300)
.background(Color.white)
.cornerRadius(20)
.shadow(radius: 20 )
}
func btnStart() -> some View {
VStack{
Button(action: {
}, label: {
Text("Start Order")
.frame(width: 150, height: 30)
.background(Color.red)
.foregroundColor(Color.white)
.font(.custom("Open Sans", size: 28))
})
}
}
}
When Enter button in the popup is clicked , it should add a new button to the bottom of the main view (means view that has "Select Location" button)
Use a struct instead of function for the start button and pop up and show them when showPopUp and showsCorrectOrIncorrect is true.
struct SelectLocation: View {
#State private var showPopUp = false
#State private var passCode: String = ""
#State var showsCorrectOrIncorrect = false
var body: some View {
ZStack{
VStack{
Button(action: {
withAnimation {
self.showPopUp = true
}
}, label: {
Text("Select Location")
.frame(minWidth: 0, maxWidth: 500)
.padding()
.background(Color.clear)
.foregroundColor(Color.black)
.font(.custom("Open Sans", size: 18))
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 2)
)
})
if showPopUp {
PopUpPassCode(passCode: $passCode, showPopUp: $showPopUp, showsCorrectOrIncorrect: $showsCorrectOrIncorrect)
}
if showsCorrectOrIncorrect {
StartButton()
}
}
}
}
}
struct PopUpPassCode: View {
#Binding var passCode: String
#Binding var showPopUp: Bool
#Binding var showsCorrectOrIncorrect: Bool
var body: some View {
VStack{
SecureField("Enter Code", text: $passCode)
.frame(width: 300, height: 50, alignment: .leading)
.cornerRadius(3.0)
.overlay(RoundedRectangle(cornerRadius: 3.0)
.stroke(Color.gray, lineWidth: 1)
)
.padding()
Button(action: {
withAnimation {
self.showPopUp = false
self.showsCorrectOrIncorrect = true
}
}, label: {
Text("Enter")
.frame(width: 150, height: 30)
.padding()
.background(Color.red)
.foregroundColor(Color.white)
.font(.custom("Open Sans", size: 28))
})
}
.padding()
.frame(width: 440, height: 300)
.background(Color.white)
.cornerRadius(20)
.shadow(radius: 20 )
}
}
struct StartButton: View {
var body: some View {
VStack{
Button(action: {
}, label: {
Text("Start Order")
.frame(width: 150, height: 30)
.background(Color.red)
.foregroundColor(Color.white)
.font(.custom("Open Sans", size: 28))
})
}
}
}

Removing items from a child view generated by For Each loop causes Fatal Error

I hope you are having a more pleasant evening than mine!
So as I mentioned in the title, my for each loop crashes whenever I try to remove an item from the original list with a binding. I did some research and the problem is that for each generates a view with an id but when you delete the item in your child view it can't find the contents and crashes. Returns 'Thread 1: Fatal error: Index out of range'. I can fix the issue by declaring a #State var instead of #Binding, which really works! However, I have more than a delete button in my child view and if I don't use a binding declaration, changes made don't reflect on the main view. I don't wanna give up on neither the delete button nor buttons. Is there way to keep all of them in my childview?
Mainview declarations;
struct ContentView: View {
#ObservedObject var superReminders = SuperReminders()
#State var superReminder = SuperReminder()}
My list View;
List{
ForEach(superReminders.reminderlist.indices, id: \.self) { index in
NavigationLink(destination: DetailedRemView(superReminder : self.$superReminders.reminderlist[index] ).environmentObject(superReminders)) {
squareImageView(superReminder : self.$superReminders.reminderlist[index]).environmentObject(superReminders).environmentObject(superReminders)
}.listRowBackground(Color.clear)
}.onDelete { indexSet in
superReminders.reminderlist.remove(atOffsets: indexSet)}
}
Childview declarations;
import SwiftUI
struct DetailedRemView: View {
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "EE, MMM d, YYYY"
return formatter
}
#State public var showingDetail = false
#Environment(\.colorScheme) var colorScheme: ColorScheme
#State private var deleteReminderAlert = false
#EnvironmentObject var superReminders : SuperReminders
#Environment(\.presentationMode) var presentationMode
#Binding var superReminder : SuperReminder
#State private var showDialog = false
#State var animate = false
var body: some View {
VStack{
HStack(alignment: .center){
Text(superReminder.remdate)
.font(.title)
.multilineTextAlignment(.leading)
.padding(.leading)
.frame(minWidth: 100,maxWidth: .infinity, maxHeight: 50)
Spacer()
Button(action: {
self.showDialog.toggle()
}, label: {
ZStack{
RoundedRectangle(cornerRadius: 10)
.fill(Color.blue)
.frame(width: 80, height: 35)
HStack{
Text("Edit")
.foregroundColor(.white)
.multilineTextAlignment(.center)
.cornerRadius(8)
Image(systemName: "pencil")
.foregroundColor(.white)
}
}
.shadow(color:Color.gray.opacity(0.3), radius: 3, x: 3, y: 3)
.padding(.leading)
.alert(isPresented: $showDialog,
TextAlert(title: "Edit reminder title",
message: "Enter a new title or dissmis.", placeholder: superReminder.remdate,
keyboardType: .default) { result in
if let text = result {
if text != "" {
superReminder.remdate = text }
else{}
} else {
}
})
})
.padding(.leading)
}
.frame(minWidth: 100, maxWidth: /*#START_MENU_TOKEN#*/.infinity/*#END_MENU_TOKEN#*/, maxHeight: 50, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.padding(.vertical, -10)
ZStack(alignment: .topTrailing){
Image(superReminder.image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(minWidth: 0,maxWidth: .infinity,minHeight: 200,maxHeight: .infinity)
.saturation(superReminder.pastreminder ? 0.1 : 1)
.clipShape(Rectangle())
.cornerRadius(10)
.padding(.all)
.pinchToZoom()
HStack{
Text(superReminder.dateactual, formatter: dateFormatter)
.foregroundColor(.white)
.frame(width: 180, height: 30, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.background( superReminder.pastreminder ? Color.gray : Color.lightlygreen)
.cornerRadius(8)
.animation(/*#START_MENU_TOKEN#*/.easeIn/*#END_MENU_TOKEN#*/)
if superReminder.pastreminder == true {
ZStack{
RoundedRectangle(cornerRadius: 8)
.fill(Color.black)
.frame(width: 30, height: 30)
Image(systemName: "moon.zzz")
.foregroundColor(.white)
}.offset(x: animate ? -3 : 0)
.onAppear(perform: {
shake()
})
}
else{}
}
.zIndex(0)
.offset(x: -10, y: 10)
.padding()
}
.zIndex(1)
.shadow(color: Color.gray.opacity(0.4), radius: 3, x: 1, y: 2)
HStack{
Button(action: {
self.showingDetail.toggle()
}){
ZStack{
RoundedRectangle(cornerRadius: 10)
.fill(Color.lightlygreen)
.frame(width: 140, height: 40)
HStack{
Text("Reschedule")
.foregroundColor(.white)
.multilineTextAlignment(.center)
.cornerRadius(8)
Image(systemName: "calendar")
.foregroundColor(.white)
}
}
.shadow(color:Color.gray.opacity(0.3), radius: 3, x: 3, y: 3)
.padding(.all, 4.0)
}
.sheet(isPresented: $showingDetail, content :{
remdatepicker(isPresented: self.$showingDetail, superReminder: $superReminder)})
Button(action: {
if superReminder.pastreminder == true {
superReminder.pastreminder = false
}
else if superReminder.pastreminder == false{
superReminder.pastreminder = true
}
}, label: {
ZStack{
RoundedRectangle(cornerRadius: 10)
.fill(superReminder.pastreminder == true ? Color.lightlyblue : Color.gray)
.frame(width: 100, height: 40)
HStack{
Text(superReminder.pastreminder == true ? "Activate" : "Silence")
.foregroundColor(.white)
.multilineTextAlignment(.center)
.cornerRadius(8)
Image(systemName: superReminder.pastreminder == true ? "checkmark.circle" : "moon.zzz")
.foregroundColor(.white)
}
}
.shadow(color:Color.gray.opacity(0.3), radius: 3, x: 3, y: 3)
.padding(.all, 4.0)
})
Button(action: {
self.deleteReminderAlert.toggle()
}, label: {
ZStack{
RoundedRectangle(cornerRadius: 10)
.fill(Color(.red))
.frame(width: 40, height: 40)
HStack{
Image(systemName: "trash")
.foregroundColor(.white)
}
}
.shadow(color:Color.gray.opacity(0.3), radius: 3, x: 3, y: 3)
.padding(.all, 4.0)
})
}.padding(.bottom, 20)
.alert(isPresented: $deleteReminderAlert){
Alert(
title: Text("Are you sure?"),
message: Text("Do you want to delete this reminder?"),
primaryButton: .destructive(Text("Yes"), action: {
superReminders.remove(superReminder: superReminder)
self.presentationMode.wrappedValue.dismiss()
}),
secondaryButton: .cancel(Text("No"))
)
}
}
}
func shake() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
withAnimation(Animation.default.repeatCount(6).speed(7)){
animate.toggle()}}}
}
Class and List;
import SwiftUI
struct SuperReminder: Identifiable, Codable, Equatable {
var id = UUID()
var remdate = ""
var dateactual = Date.init()
var image = "New1"
var pastreminder = false
}
class SuperReminders: ObservableObject {
#Published var reminderlist: [SuperReminder]
init() {
self.reminderlist = [
]
}
func add(superReminder: SuperReminder) {
reminderlist.append(superReminder)
}
func remove(superReminder: SuperReminder) {
if let index = reminderlist.firstIndex(of: superReminder) {
reminderlist.remove(at: index)
}
}
}
This answer is similar to
Accessing and manipulating array item in an EnvironmentObject
Loop over superReminders.reminderlist since SuperReminder: Identifiable, Codable, Equatable.
ForEach(superReminders.reminderlist) { superReminder in
NavigationLink(destination: DetailedRemView(superReminders: superReminders,
superReminder: superReminder)) {
-----
}
}
In DetailedRemView, do the following:
struct DetailedRemView: View {
#ObservedObject var superReminders : SuperReminders
var superReminder : SuperReminder
// find index of current superReminder
var indexOfReminder: Int? {
superReminders.reminderlist.firstIndex {$0 == superReminder}
}
var body: some View {
// Unwrap indexOfReminder
if let index = indexOfReminder {
VStack {
------
}
}
}
----
}
Use superReminders.reminderlist[index] in DetailRemView whereever you need to update superReminder.
superReminders.reminderlist[index].pastreminder = false

How to add .fullScreenCover() to a button by condition in SwiftUI?

I created a simple collection with navigation from the last page to the next screen.
How to correctly write transition condition if I need to apply the .fullScreenCover modifier to the button on the last page array index?
How do I correctly place the background image on the first collection screen so that it is not on the following screens, by convention, if the index is the first?
import SwiftUI
struct IntroView: View {
#ObservedObject var viewModel = IntroViewModel()
#State private var tabSelection = 0
#State private var isLastPage = false
var body: some View {
ZStack {
TabView(selection: $tabSelection) {
ForEach(0..<viewModel.pages.endIndex) { index in
VStack {
Image("icnDE")
.padding(.bottom, 20)
.padding(.top, 50)
.frame(alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
Text(viewModel.pages[index].name)
.font(Font.custom("TeXGyreAdventor-Bold", size: 32))
.foregroundColor(.white)
.multilineTextAlignment(.center)
.padding(.horizontal,30)
Button(action: {
self.tabSelection += 1
self.isLastPage = false
}) {
Text(viewModel.pages[index].buttonName)
.font(Font.custom("TeXGyreAdventor-Bold", size: 18))
.frame(width: 335, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(12)
.padding(.top, 50)
}
if tabSelection == viewModel.pages.count - 1, isLastPage == true {
Button(action: {
self.tabSelection += 1
self.isLastPage = false
}) {
Text(viewModel.pages[index].buttonName)
.font(Font.custom("TeXGyreAdventor-Bold", size: 18))
.frame(width: 335, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(12)
.padding(.top, 50)
}.fullScreenCover(isPresented: $isLastPage, content: {
LoginView()})
}
}
}
}
.tabViewStyle(PageTabViewStyle())
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
.tabViewStyle(PageTabViewStyle.init(indexDisplayMode: .never))
.edgesIgnoringSafeArea(.all)
}
.background(
Image("imgHappypeople")
.resizable()
.edgesIgnoringSafeArea(.all)
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
}
}
struct Intro_Previews: PreviewProvider {
static var previews: some View {
IntroView()
.previewDevice("iPhone 11")
}
}
For open full screen cover, Add .fullScreenCover at the top of the ZStack and no need to add a condition for two-button.
struct IntroView: View {
#ObservedObject var viewModel = IntroViewModel()
#State private var tabSelection = 0
#State private var isLastPage = false
var body: some View {
ZStack {
TabView(selection: $tabSelection) {
ForEach(0..<viewModel.pages.endIndex) { index in
VStack {
Image("icnDE")
.padding(.bottom, 20)
.padding(.top, 50)
.frame(alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
Text(viewModel.pages[index].name)
.font(Font.custom("TeXGyreAdventor-Bold", size: 32))
.foregroundColor(.white)
.multilineTextAlignment(.center)
.padding(.horizontal,30)
Button(action: {
if self.tabSelection == viewModel.pages.count - 1 {
self.isLastPage = true
} else {
self.tabSelection += 1
} //<-- Use this condition
}) {
Text("\(index)")
.font(Font.custom("TeXGyreAdventor-Bold", size: 18))
.frame(width: 335, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(12)
.padding(.top, 50)
}
}
}
}
.tabViewStyle(PageTabViewStyle())
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
.tabViewStyle(PageTabViewStyle.init(indexDisplayMode: .never))
.edgesIgnoringSafeArea(.all)
}
.fullScreenCover(isPresented: $isLastPage, content: {
Text("Details")}) //<== Use fullScreenCover here
.background(
Image("imgHappypeople")
.resizable()
.edgesIgnoringSafeArea(.all)
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
}
}

Resources