article

Showing posts with label SwiftUI-iOS-Xcode. Show all posts
Showing posts with label SwiftUI-iOS-Xcode. Show all posts

Sunday, February 27, 2022

SwiftUI Loading View | Loading Screen

SwiftUI Loading View | Loading Screen

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {

    @State var progress: CGFloat = 0
    @State var doneLoading: Bool = false
    
    var body: some View {
        ZStack {
            if doneLoading {
                HomeView()
                    .transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
            } else {
                LoadingView(content: Image("logo")
                                        .resizable()
                                        .scaledToFit()
                                        .padding(.horizontal, 50),
                            progress: $progress)
                    // Added to simulate asynchronous data loading
                    .onAppear {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                            withAnimation {
                                self.progress = 0
                            }
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
                                withAnimation {
                                    self.doneLoading = true
                                }
                                
                            }
                        }
                    }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


struct ScaledMaskModifier<Mask: View>: ViewModifier {
    
    var mask: Mask
    var progress: CGFloat
    
    func body(content: Content) -> some View {
        content
            .mask(GeometryReader(content: { geometry in
                self.mask.frame(width: self.calculateSize(geometry: geometry) * self.progress,
                                height: self.calculateSize(geometry: geometry) * self.progress,
                                alignment: .center)
            }))
    }
    
    // Calculate Max Size of Mask
    func calculateSize(geometry: GeometryProxy) -> CGFloat {
        if geometry.size.width > geometry.size.height {
            return geometry.size.width
        }
        return geometry.size.height
    }

}

struct LoadingView<Content: View>: View {

    var content: Content
    @Binding var progress: CGFloat
    @State var logoOffset: CGFloat = 0 //Animation Y Offset
    
    var body: some View {
        content
            .modifier(ScaledMaskModifier(mask: Circle(), progress: progress))
            .offset(x: 0, y: logoOffset)
            .onAppear {
                withAnimation(Animation.easeInOut(duration: 1)) {
                    self.progress = 1.0
                }
                withAnimation(Animation.easeInOut(duration: 0.4).repeatForever(autoreverses: true)) {
                    self.logoOffset = 10
                }
            }
    }
}
HomeView.swift
 
//
//  HomeView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct HomeView: View {
    var body: some View {
        ZStack {
            Color.blue.ignoresSafeArea()
            VStack {
                Text("Hello, SwiftUI!")
                    .font(.largeTitle)
                    .bold()
                Button("Getting Started") {
                    
                }
            }
        }
        .accentColor(Color.black)
    }
}

struct HomeView_Previews: PreviewProvider {
    static var previews: some View {
        HomeView()
    }
}

Friday, February 25, 2022

SwiftUI Loading View Check Network Connection - Loading View | Activity Indicator

SwiftUI Loading View Check Network Connection - Loading View | Activity Indicator

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State private var isLoading = false
    @State private var notconnected = false
    
    @ObservedObject var monitor = NetworkMonitor()
    
    var body: some View {
        ZStack {
            if notconnected {
                VStack {
                    Image(systemName: monitor.isConnected ? "wifi" : "wifi.slash")
                        .font(.system(size: 56))
                    Text(monitor.isConnected ? "Connected!" : "Not connected!")
                        .padding()
                }
            }else {
                Home()
            }
            
            if isLoading {
                loadingView()
            }
        }
        .onAppear {
            startCheckNetworkCall()
        }
    }
    
    func startCheckNetworkCall() {
        isLoading = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            if monitor.isConnected {
                isLoading = false
                notconnected = false
                print("Success")
            }else{
                isLoading = false
                notconnected = true
                print("not connected")
            }

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct loadingView: View {
    
    var body: some View {

        ZStack {
            Color(.systemBackground)
                .ignoresSafeArea()
            
            ProgressView()
                .progressViewStyle(CircularProgressViewStyle(tint: .orange))
                .scaleEffect(3)
        }
    }
}
Home.swift
 
//
//  Home.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct Home: View {
    var body: some View {
        NavigationView {
             
            VStack {
                HStack(spacing: 16) {
                    Image("pic")
                        .resizable()
                        .scaledToFill()
                        .frame(width: 50, height: 50)
                        .clipped()
                        .cornerRadius(50)
                        .overlay(RoundedRectangle(cornerRadius: 44)
                                    .stroke(Color(.label), lineWidth: 1)
                        )
                        .shadow(radius: 5)
                     
                     
                    VStack(alignment: .leading, spacing: 4) {
                        Text("cairocoders")
                            .font(.system(size: 24, weight: .bold))
                         
                        HStack {
                            Circle()
                                .foregroundColor(.green)
                                .frame(width: 14, height: 14)
                            Text("online")
                                .font(.system(size: 12))
                                .foregroundColor(Color(.lightGray))
                        }
                    }
                     
                    Spacer()
                    Button {
                         
                    } label: {
                        Image(systemName: "gear")
                            .font(.system(size: 24, weight: .bold))
                            .foregroundColor(Color(.label))
                    }
                }//End HStack
                .padding()
                 
                ScrollView {
                    ForEach(1..<4){i in
                        Button(action: {
                            
                        }) {
                            VStack {
                                HStack(spacing: 16) {
                                    Image("photo\(i)")
                                        .resizable()
                                        .scaledToFill()
                                        .frame(width: 50, height: 50)
                                        .clipped()
                                        .cornerRadius(50)
                                     
                                    VStack(alignment: .leading) {
                                        Text("User Name \(i)")
                                            .font(.system(size: 16, weight: .bold))
                                        Text("View Profile")
                                            .font(.system(size: 14))
                                            .foregroundColor(Color(.lightGray))
                                    }
                                    Spacer()
                                     
                                    Text("22m")
                                        .font(.system(size: 14, weight: .semibold))
                                }
                                Divider()
                                .padding(.vertical, 8)
                                 
                            }.padding(.horizontal)
                        }
                    }//End ForEach
                    .padding(.bottom, 50)
                }// End scrollview
            }
            .navigationBarHidden(true)
        }
    }
}

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
    }
}
NetworkMonitor.swift
 
//
//  NetworkMonitor.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import Foundation
import Network
 
final class NetworkMonitor: ObservableObject {
    let monitor = NWPathMonitor()
    let queue = DispatchQueue(label: "Monitor")
     
    @Published var isConnected = true
     
    init() {
        monitor.pathUpdateHandler =  { [weak self] path in
            DispatchQueue.main.async {
                self?.isConnected = path.status == .satisfied ? true : false
            }
        }
        monitor.start(queue: queue)
    }
}

Thursday, February 24, 2022

SwiftUI ScrollView Sticky Header

SwiftUI ScrollView Sticky Header

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            StickyHeader {
                StickyHeader {
                    Image("3")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                }
            }
            
            HStack(alignment: .center) {
                VStack {
                    Text("Taylor")
                        .padding()
                        .font(.title)
                    Text("Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..")
                        .padding()
                    Image("1")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(.all, 20)
                    
                    Text("Caitelyn")
                        .padding()
                        .font(.title)
                    
                    Image("2")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(.all, 20)
                
                }.padding(10)
            }
            .frame(maxWidth: .infinity, alignment: .center)
            .background(Color.white)
            .modifier(CardModifier())
            .padding(.all, 10)
            
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct StickyHeader<Content: View>: View {

    var minHeight: CGFloat
    var content: Content
    
    init(minHeight: CGFloat = 200, @ViewBuilder content: () -> Content) {
        self.minHeight = minHeight
        self.content = content()
    }
    
    var body: some View {
        GeometryReader { geo in
            if(geo.frame(in: .global).minY <= 0) {
                content
                    .frame(width: geo.size.width, height: geo.size.height, alignment: .center)
            } else {
                content
                    .offset(y: -geo.frame(in: .global).minY)
                    .frame(width: geo.size.width, height: geo.size.height + geo.frame(in: .global).minY)
            }
        }.frame(minHeight: minHeight)
    }
}

struct CardModifier: ViewModifier {
    func body(content: Content) -> some View {
        content
            .cornerRadius(20)
            .shadow(color: Color.black.opacity(0.2), radius: 20, x: 0, y: 0)
    }
    
}

Tuesday, February 22, 2022

SwiftUI Custom Dropdwon Picker

SwiftUI Custom Dropdwon Picker

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var selection = 1
    
    var body: some View {
        VStack {
            ZStack(alignment: .bottomTrailing) {
                Image("coffee").resizable().frame(height: 350)
                HStack(spacing: 15){
                    Text("Kapeng Barako")
                        .foregroundColor(.white)
                    
                }.padding()
            }
             
            Text("Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit")
            
            DropdownPicker(title: "Size", selection: $selection, options: ["Small", "Medium", "Large", "X-Large"])
            
            Button("Place Order") {
                
            }
            .foregroundColor(.white)
            .frame(width: 300, height: 50)
            .background(Color.orange)
            .cornerRadius(10)
            
            Spacer()
            
        }.padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct DropdownPicker: View {
    
    var title: String
    @Binding var selection: Int
    var options: [String]
    
    @State private var showOptions: Bool = false
    
    var body: some View {
        ZStack {
            // current selection
            HStack {
                Text(title)
                Spacer()
                Text(options[selection])
                    .foregroundColor(Color.black.opacity(0.6))
                Image(systemName: "chevron.right")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 10, height: 10)
            }
            .font(Font.custom("Avenir Next", size: 16).weight(.medium))
            .padding(.horizontal, 12)
            .padding(.vertical, 8)
            .background(Color.white)
            .onTapGesture {
                // show the dropdown options
                withAnimation(Animation.spring().speed(2)) {
                    showOptions = true
                }
            }
            
            // Drop down options
            if showOptions {
                VStack(alignment: .leading, spacing: 4) {
                    Text(title)
                        .font(Font.custom("Avenir Next", size: 16).weight(.semibold))
                        .foregroundColor(.white)
                    HStack {
                        Spacer()
                        ForEach(options.indices, id: \.self) { i in
                            if i == selection {
                                Text(options[i])
                                    .font(.system(size: 12))
                                    .padding(.vertical, 8)
                                    .padding(.horizontal, 12)
                                    .background(Color.white.opacity(0.2))
                                    .cornerRadius(4)
                                    .onTapGesture {
                                        // hide dropdown options - user selection didn't change
                                        withAnimation(Animation.spring().speed(2)) {
                                            showOptions = false
                                        }
                                    }
                            } else {
                                Text(options[i])
                                    .font(.system(size: 12))
                                    .onTapGesture {
                                        // update user selection and close options dropdown
                                        withAnimation(Animation.spring().speed(2)) {
                                            selection = i
                                            showOptions = false
                                        }
                                    }
                            }
                            Spacer()
                        }
                    }
                    .padding(.vertical, 2)
                    .transition(AnyTransition.move(edge: .top).combined(with: .opacity))
                    
                }
                .padding(.horizontal, 12)
                .padding(.vertical, 8)
                .background(Color.black)
                .foregroundColor(.white)
                .transition(.opacity)
                
            }
            
        }
    }
}

Monday, February 21, 2022

SwiftUI View Profile Page - Sheets and ForEach

SwiftUI View Profile Page - Sheets and ForEach

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var data: userlist?
    
    var body: some View {
        NavigationView {
            
            VStack {
                HStack(spacing: 16) {
                    Image("pic")
                        .resizable()
                        .scaledToFill()
                        .frame(width: 50, height: 50)
                        .clipped()
                        .cornerRadius(50)
                        .overlay(RoundedRectangle(cornerRadius: 44)
                                    .stroke(Color(.label), lineWidth: 1)
                        )
                        .shadow(radius: 5)
                    
                    
                    VStack(alignment: .leading, spacing: 4) {
                        Text("cairocoders")
                            .font(.system(size: 24, weight: .bold))
                        
                        HStack {
                            Circle()
                                .foregroundColor(.green)
                                .frame(width: 14, height: 14)
                            Text("online")
                                .font(.system(size: 12))
                                .foregroundColor(Color(.lightGray))
                        }
                    }
                    
                    Spacer()
                    Button {
                        
                    } label: {
                        Image(systemName: "gear")
                            .font(.system(size: 24, weight: .bold))
                            .foregroundColor(Color(.label))
                    }
                }//End HStack
                .padding()
                
                ScrollView {
                    ForEach(user){i in
                        Button(action: {
                            data = .init(id: i.id, name: i.name, image: i.image, pic: i.pic)
                        }) {
                            VStack {
                                HStack(spacing: 16) {
                                    Image(i.image)
                                        .resizable()
                                        .scaledToFill()
                                        .frame(width: 50, height: 50)
                                        .clipped()
                                        .cornerRadius(50)
                                    
                                    VStack(alignment: .leading) {
                                        Text(i.name)
                                            .font(.system(size: 16, weight: .bold))
                                        Text("View Profile")
                                            .font(.system(size: 14))
                                            .foregroundColor(Color(.lightGray))
                                    }
                                    Spacer()
                                    
                                    Text("22m")
                                        .font(.system(size: 14, weight: .semibold))
                                }
                                Divider()
                                .padding(.vertical, 8)
                                
                            }.padding(.horizontal)
                        }
                    }//End ForEach
                    .padding(.bottom, 50)
                    .sheet(item: $data) { rs in
                        Profile(viewdata: rs)
                    }
                }// End scrollview
            }
            .navigationBarHidden(true)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


struct userlist : Identifiable {
     
    var id : Int
    var name : String
    var image : String
    var pic : String
}

var user = [
    userlist(id: 0, name: "Taylor", image: "photo1", pic: "1"),
    userlist(id: 1, name: "Mari", image: "photo2", pic: "2"),
    userlist(id: 2, name: "Sandra", image: "photo3", pic: "3")
]
Profile.swift
 
//
//  Profile.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct Profile : View {
    
    @Environment(\.presentationMode) var presentationMode
    
    let viewdata : userlist
    
    var body : some View{
        
        ZStack{
            Image(viewdata.pic).resizable().edgesIgnoringSafeArea(.all)
            
            VStack{
                HStack{
                    
                    Button(action: {
                    }) {
                        Image(systemName: "slider.horizontal.3").foregroundColor(Color.black).font(.title)
                    }
                    
                    Spacer()
                    
                    Button(action: {
                        presentationMode.wrappedValue.dismiss()
                    }) {
                        Image(systemName: "xmark").foregroundColor(Color.black).font(.title)
                    }
                }
                
                Spacer()
                
                ZStack(alignment: .top) {
                    VStack{
                        HStack{
                            VStack(alignment: .leading, spacing: 10) {
                                
                                Text("\(viewdata.name),").font(.title)
                                Text("19")
                            }
                            
                            Spacer()
                            
                            HStack(spacing: 8){
                                Image(systemName: "mappin.and.ellipse")
                                
                                Text("2 Miles")
                                
                            }.padding(8)
                            .background(Color.black.opacity(0.1))
                            .cornerRadius(10)
                            
                        }.padding(.top,35)
                        
                        Text("Hi! My name \(viewdata.name). I like sharing my thoughts and adore people who except me the way I am. Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit. Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.").padding(.top)
                        
                    }.padding()
                    .background(Blurview())
                    .clipShape(BottomShape())
                    .cornerRadius(25)
                    
                    ZStack{
                        Button(action: {
                        }) {
                            Image(systemName: "message.and.waveform")
                                .frame(width: 20, height: 20)
                                .padding(20)
                                .background(Color.white)
                                .clipShape(Circle())
                                .font(.title)
                                .foregroundColor(Color.green)
                        }
                        
                        Circle().stroke(Color.green, lineWidth: 5).frame(width: 70, height: 70)
                        
                    }.offset(y: -35)
                    
                    HStack{
                        Button(action: {
                            
                        }) {
                            Image(systemName: "suit.heart")
                                .frame(width: 25, height: 20)
                                .padding()
                                .background(Color.white)
                                .clipShape(Circle())
                                .font(.title)
                                .foregroundColor(Color.red)
                        }
                        
                        Spacer()
                        
                        Button(action: {
                            
                        }) {
                            Image(systemName: "hand.thumbsup")
                                .frame(width: 25, height: 25)
                                .padding()
                                .background(Color.white)
                                .clipShape(Circle())
                                .font(.title)
                                .foregroundColor(Color.blue)
                        }
                        
                    }.offset(y: -25)
                    .padding(.horizontal,35)
                        
                }
            }.padding()
        }
    }
}

struct BottomShape : Shape {
    
    func path(in rect: CGRect) -> Path {
        
        return Path{path in

            path.move(to: CGPoint(x: 0, y: 0))
            path.addLine(to: CGPoint(x: 0, y: rect.height))
            path.addLine(to: CGPoint(x: rect.width, y: rect.height))
            path.addLine(to: CGPoint(x: rect.width, y: 0))
            path.addArc(center: CGPoint(x: rect.width / 2, y: 0), radius: 42, startAngle: .zero, endAngle: .init(degrees: 180), clockwise: false)
            
        }
    }
}

struct Blurview : UIViewRepresentable {
    
    func makeUIView(context: UIViewRepresentableContext<Blurview>) -> UIVisualEffectView {
        
        let view = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialLight))
        
        return view
    }
    
    func updateUIView(_ uiView: UIVisualEffectView, context: UIViewRepresentableContext<Blurview>) {
        
    }
}

struct Profile_Previews: PreviewProvider {
    static var previews: some View {
        Profile(viewdata: userlist(id: 1, name: "Taylor", image: "photo1", pic: "1"))
    }
}

Sunday, February 20, 2022

SwiftUI Show Model Data to Sheet - Sheets and ForEach

SwiftUI Show Model Data to Sheet - Sheets and ForEach

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI
 
struct ContentView : View {
     
    @State var fruit: Fruits?
    
    var body: some View {
        VStack(spacing: 20) {
            ForEach(post) { i in
                Button(i.title) {
                    fruit = .init(id: i.id, title: i.title, price: i.price)
                }
                .foregroundColor(.white)
                .frame(width: 300, height: 50)
                .background(Color.orange)
                .cornerRadius(10)
                .sheet(item: $fruit) { rs in
                    DetailsView(viewdata: rs)
                }
            }
        }
    }
}
 
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct DetailsView: View {

    @State var viewdata: Fruits
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        
        VStack {
            Button("Dismiss") {
                presentationMode.wrappedValue.dismiss()
            }
            Spacer()
            Text(viewdata.title)
                .font(.title)
            Text(viewdata.price)
                .font(.title)
            Spacer()
        }
    }
}

struct Fruits: Identifiable {

    let id: Int
    let title: String
    let price : String
}

var post = [
    Fruits(id: 0, title: "Strawberry", price: "45"),
    Fruits(id: 1, title: "Pineapples", price: "89"),
    Fruits(id: 2, title: "Apple", price: "5"),
    Fruits(id: 3, title: "Watermelon", price: "10"),
    Fruits(id: 4, title: "Orange", price: "32"),
    Fruits(id: 5, title: "Banana", price: "56")
]

Thursday, February 17, 2022

SwiftUI Floating Tab Bar

SwiftUI Floating Tab Bar

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var selected = 0
    
    var body: some View {
    
        ZStack(alignment: .bottom){
            
            VStack{
                
                if self.selected == 0{
                    GeometryReader{_ in
                        VStack(spacing: 15){
                            Spacer()
                            Text("Home")
                                .font(.title)
                                .foregroundColor(.white)
                            Image("1").resizable().frame(height: 250).cornerRadius(15)
                            Spacer()
                        }.padding()
                    }
                }
                else if self.selected == 1{
                    GeometryReader{_ in
                        VStack(spacing: 15){
                            Spacer()
                            Text("Wishlist")
                                .font(.title)
                                .foregroundColor(.white)
                            Image("2").resizable().frame(height: 250).cornerRadius(15)
                            Spacer()
                        }.padding()
                    }
                }
                else{
                    GeometryReader{_ in
                        VStack(spacing: 15){
                            Spacer()
                            Text("Cart")
                                .font(.title)
                                .foregroundColor(.white)
                            Image("3").resizable().frame(height: 250).cornerRadius(15)
                            Spacer()
                        }.padding()
                    }
                }
                
            }.background(Color.gray)
            .edgesIgnoringSafeArea(.all)
            
            FloatingTabbar(selected: self.$selected)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct FloatingTabbar : View {
    
    @Binding var selected : Int
    @State var expand = false
    
    var body : some View{
        
        HStack{
            
            Spacer(minLength: 0)
            
            HStack{
                if !self.expand{
                    
                    Button(action: {
                        self.expand.toggle()
                    }) {
                        Image(systemName: "arrow.left").foregroundColor(.green).padding()
                    }
                }
                else{
                    Button(action: {
                        self.selected = 0
                    }) {
                        Image(systemName: "house").foregroundColor(self.selected == 0 ? .green : .gray).padding(.horizontal)
                    }
                    
                    Spacer(minLength: 15)
                    
                    Button(action: {
                        self.selected = 1
                    }) {
                        Image(systemName: "suit.heart").foregroundColor(self.selected == 1 ? .green : .gray).padding(.horizontal)
                    }
                    
                    Spacer(minLength: 15)
                    
                    Button(action: {
                        self.selected = 2
                    }) {
                        Image(systemName: "cart").foregroundColor(self.selected == 2 ? .green : .gray).padding(.horizontal)
                    }
                }
            }.padding(.vertical,self.expand ? 20 : 8)
            .padding(.horizontal,self.expand ? 35 : 8)
            .background(Color.white)
            .clipShape(Capsule())
            .padding(22)
            .onLongPressGesture {
                    
                    self.expand.toggle()
            }
            .animation(.interactiveSpring(response: 0.6, dampingFraction: 0.6, blendDuration: 0.6))
        }
    }
}

Wednesday, February 16, 2022

SwiftUI UnSpash App UI

SwiftUI UnSpash App UI

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView : View {
    
    @State var tabs = ["Wallpapers","Architecture","Nature","People", "Fashion", "Film", "Food & Drink", "Health & Wellnes"]
    @State var txt = ""
    @State var selectedTab = "Nature"
    
    @State var selectedData : [[String]] = [["n1","n2"],["n3","n4"],["n5","n6"]]
    
    @State var wallpaper = [["w1","w2"],["w3","w4"]]
    @State var architecture = [["a1","a2"],["a3","a4"]]
    @State var nature = [["n1","n2"],["n3","n4"],["n5","n6"]]
    @State var people = [["p1","p2"],["p3","p4"]]
    
    var body : some View{
        
        VStack{
            HStack{
                Button(action: {
                    
                }) {
                    Image(systemName: "slider.horizontal.3")
                }
                
                Spacer()
                
                Button(action: {
                    
                }) {
                    Image("logo").renderingMode(.original).resizable().frame(width: 25, height: 25)
                }
                
            }.padding()
            .background(Color.white)
            .overlay(Image("unsplash").renderingMode(.original).resizable().frame(width: 150, height: 25))
            
            ScrollView(.vertical, showsIndicators: false) {
                VStack(alignment: .leading, spacing: 15) {
                    HStack{
                        Image(systemName: "magnifyingglass")
                        TextField("Search", text: self.$txt)
                    }.padding(12)
                    .background(Color("Color"))
                    .clipShape(Capsule())
                    
                    ZStack(alignment: .bottomTrailing) {
                        Image("main").resizable().frame(height: 350)
                        HStack(spacing: 15){
                            Button(action: {
                                
                            }) {
                                Image(systemName: "plus.circle").foregroundColor(Color.white)
                            }
                            
                            Button(action: {
                                
                            }) {
                                Image(systemName: "suit.heart").foregroundColor(Color.white)
                            }
                            
                            Button(action: {
                                
                            }) {
                                Image(systemName: "square.and.arrow.down").foregroundColor(Color.white)
                            }
                            
                        }.padding()
                    }
                    
                    Text("Trending").font(.title).padding(.top)
                    
                    ScrollView(.horizontal, showsIndicators: false) {
                        HStack(spacing: 15){
                            ForEach(tabs,id: \.self){i in
                                
                                Button(action: {
                                    self.selectedTab = i
                                    
                                    if i == "Wallpapers"{
                                        self.selectedData = self.wallpaper
                                        print("Wallpaper")
                                    }
                                    else if i == "Architecture"{
                                         self.selectedData = self.architecture
                                    }
                                    else if i == "Nature"{
                                         self.selectedData = self.nature
                                    }
                                    else{
                                         self.selectedData = self.people
                                    }
                                }) {
                                    VStack{
                                        Text(i).foregroundColor(.black)
                                        
                                        Capsule()
                                            .fill(self.selectedTab == i ? Color.black : Color.clear)
                                            .frame(height: 6)
                                    }
                                }
                            }
                            
                        }.padding(.top)
                    }
                    
                    VStack(spacing: 18){
                        
                        ForEach(selectedData,id: \.self){i in
                            
                            HStack{
                                
                                ForEach(i,id: \.self){j in
                                    
                                    Image(j)
                                        .renderingMode(.original)
                                        .resizable()
                                        .frame(width: UIScreen.main.bounds.width / 2 - 20, height: 180)
                                        .cornerRadius(15)
                                        .contextMenu{
                                            
                                            Button(action: {
                                                UIImageWriteToSavedPhotosAlbum(UIImage(named: j)!, nil, nil, nil)
                                            }) {
                                                HStack{
                                                    Text("Save")
                                                    
                                                    Image(systemName: "arrow.down").resizable().frame(width: 15, height: 15)
                                                }
                                            }
                                        }
                                }
                            }
                        }
                        
                    }.padding(.top)
                }.padding()
            }
        }.background(Color("bg").edgesIgnoringSafeArea(.bottom))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SwiftUI Firebase Search Bar - Integrating searchable

SwiftUI Firebase Search Bar - Integrating searchable

https://console.firebase.google.com/

ContentView.swift
 
//
//  ContentView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

struct ContentView: View {
    
    @State var search = ""
    
    @ObservedObject var data = getData()
    
    var body: some View {
       
        NavigationView{
            List {
 
                ForEach(self.data.datas.filter{(self.search.isEmpty ? true : $0.title.localizedCaseInsensitiveContains(self.search))}, id: \.id) { rs in
                    
                    NavigationLink(destination: Detail(data: rs)) {
                        Text(rs.title)
                    }
                }
            }
            .navigationBarTitle("Search Movie")
            .searchable(text: self.$search)
            {
                ForEach(data.datas, id:\.id) { info in
                    HStack {
                        Text(info.title)
                            .searchCompletion(info.title)
                    }
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


struct Detail : View {
    
    var data : dataType
    
    var body : some View{
        VStack {
            Text(data.title)
                .font(.title)
                .fontWeight(.bold)
            Text(data.description)
        }.padding()
    }
}
Model.swift
 
//
//  Model.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//
import SwiftUI
import Firebase

class getData : ObservableObject{
    
    @Published var datas = [dataType]()
    
    init() {
        
        let db = Firestore.firestore()
        
        db.collection("movielist").getDocuments { (snap, err) in
            
            if err != nil{
                
                print((err?.localizedDescription)!)
                return
            }
            
            for i in snap!.documents{
                
                let id = i.documentID
                let title = i.get("title") as! String
                let description = i.get("description") as! String
                
                self.datas.append(dataType(id: id, title: title, description: description))
            }
        }
    }
}

struct dataType : Identifiable {
    
    var id : String
    var title : String
    var description : String
}
 
//
//  DevSwiftUIApp.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//
  
import SwiftUI
import Firebase
  
@main
struct DevSwiftUIApp: App {
      
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
       
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
   
class AppDelegate: NSObject,UIApplicationDelegate{
       
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
           
        FirebaseApp.configure()
        return true
    }
}

Monday, February 14, 2022

SwiftUI Search Bar

SwiftUI Search Bar

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    private var listOfCountry = countryList
    @State var searchText = ""
    
    var body: some View {
        NavigationView {
            List {
                ForEach(countries, id: \.self) { country in
                    HStack {
                        Text(country.capitalized)
                        Spacer()
                        Image(systemName: "paperplane")
                            .foregroundColor(Color.blue.opacity(0.8))
                    }
                    .padding()
                }
            }
            .searchable(text: $searchText)
            .navigationTitle("Countries")
        }
    }
    
    // Filter countries
    var countries: [String] {
        // Make countries lowercased
        let lcCountries = listOfCountry.map { $0.lowercased() }
        
        return searchText == "" ? lcCountries : lcCountries.filter { $0.contains(searchText.lowercased()) }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Model.swift
 
//
//  Model.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import Foundation

public var countryList = [
    "Afghanistan",
    "Albania",
    "Algeria",
    "American Samoa",
    "Andorra",
    "Angola",
    "Anguilla",
    "Antarctica",
    "Antigua and Barbuda",
    "Argentina",
    "Armenia",
    "Aruba",
    "Australia",
    "Austria",
    "Azerbaijan",
    "Bahamas (the)",
    "Bahrain",
    "Bangladesh",
    "Barbados",
    "Belarus",
    "Belgium",
    "Belize",
    "Benin",
    "Bermuda",
    "Bhutan",
    "Bolivia (Plurinational State of)",
    "Bonaire, Sint Eustatius and Saba",
    "Bosnia and Herzegovina",
    "Botswana",
    "Bouvet Island",
    "Brazil",
    "British Indian Ocean Territory (the)",
    "Brunei Darussalam",
    "Bulgaria",
    "Burkina Faso",
    "Burundi",
    "Cabo Verde",
    "Cambodia",
    "Cameroon",
    "Canada",
    "Cayman Islands (the)",
    "Central African Republic (the)",
    "Chad",
    "Chile",
    "China",
    "Christmas Island",
    "Cocos (Keeling) Islands (the)",
    "Colombia",
    "Comoros (the)",
    "Congo (the Democratic Republic of the)",
    "Congo (the)",
    "Cook Islands (the)",
    "Costa Rica",
    "Croatia",
    "Cuba",
    "Curaçao",
    "Cyprus",
    "Czechia",
    "Côte d'Ivoire",
    "Denmark",
    "Djibouti",
    "Dominica",
    "Dominican Republic (the)",
    "Ecuador",
    "Egypt",
    "El Salvador",
    "Equatorial Guinea",
    "Eritrea",
    "Estonia",
    "Eswatini",
    "Ethiopia",
    "Falkland Islands (the) [Malvinas]",
    "Faroe Islands (the)",
    "Fiji",
    "Finland",
    "France",
    "French Guiana",
    "French Polynesia",
    "French Southern Territories (the)",
    "Gabon",
    "Gambia (the)",
    "Georgia",
    "Germany",
    "Ghana",
    "Gibraltar",
    "Greece",
    "Greenland",
    "Grenada",
    "Guadeloupe",
    "Guam",
    "Guatemala",
    "Guernsey",
    "Guinea",
    "Guinea-Bissau",
    "Guyana",
    "Haiti",
    "Heard Island and McDonald Islands",
    "Holy See (the)",
    "Honduras",
    "Hong Kong",
    "Hungary",
    "Iceland",
    "India",
    "Indonesia",
    "Iran (Islamic Republic of)",
    "Iraq",
    "Ireland",
    "Isle of Man",
    "Israel",
    "Italy",
    "Jamaica",
    "Japan",
    "Jersey",
    "Jordan",
    "Kazakhstan",
    "Kenya",
    "Kiribati",
    "Korea (the Democratic People's Republic of)",
    "Korea (the Republic of)",
    "Kuwait",
    "Kyrgyzstan",
    "Lao People's Democratic Republic (the)",
    "Latvia",
    "Lebanon",
    "Lesotho",
    "Liberia",
    "Libya",
    "Liechtenstein",
    "Lithuania",
    "Luxembourg",
    "Macao",
    "Madagascar",
    "Malawi",
    "Malaysia",
    "Maldives",
    "Mali",
    "Malta",
    "Marshall Islands (the)",
    "Martinique",
    "Mauritania",
    "Mauritius",
    "Mayotte",
    "Mexico",
    "Micronesia (Federated States of)",
    "Moldova (the Republic of)",
    "Monaco",
    "Mongolia",
    "Montenegro",
    "Montserrat",
    "Morocco",
    "Mozambique",
    "Myanmar",
    "Namibia",
    "Nauru",
    "Nepal",
    "Netherlands (the)",
    "New Caledonia",
    "New Zealand",
    "Nicaragua",
    "Niger (the)",
    "Nigeria",
    "Niue",
    "Norfolk Island",
    "Northern Mariana Islands (the)",
    "Norway",
    "Oman",
    "Pakistan",
    "Palau",
    "Palestine, State of",
    "Panama",
    "Papua New Guinea",
    "Paraguay",
    "Peru",
    "Philippines (the)",
    "Pitcairn",
    "Poland",
    "Portugal",
    "Puerto Rico",
    "Qatar",
    "Republic of North Macedonia",
    "Romania",
    "Russian Federation (the)",
    "Rwanda",
    "Réunion",
    "Saint Barthélemy",
    "Saint Helena, Ascension and Tristan da Cunha",
    "Saint Kitts and Nevis",
    "Saint Lucia",
    "Saint Martin (French part)",
    "Saint Pierre and Miquelon",
    "Saint Vincent and the Grenadines",
    "Samoa",
    "San Marino",
    "Sao Tome and Principe",
    "Saudi Arabia",
    "Senegal",
    "Serbia",
    "Seychelles",
    "Sierra Leone",
    "Singapore",
    "Sint Maarten (Dutch part)",
    "Slovakia",
    "Slovenia",
    "Solomon Islands",
    "Somalia",
    "South Africa",
    "South Georgia and the South Sandwich Islands",
    "South Sudan",
    "Spain",
    "Sri Lanka",
    "Sudan (the)",
    "Suriname",
    "Svalbard and Jan Mayen",
    "Sweden",
    "Switzerland",
    "Syrian Arab Republic",
    "Taiwan",
    "Tajikistan",
    "Tanzania, United Republic of",
    "Thailand",
    "Timor-Leste",
    "Togo",
    "Tokelau",
    "Tonga",
    "Trinidad and Tobago",
    "Tunisia",
    "Turkey",
    "Turkmenistan",
    "Turks and Caicos Islands (the)",
    "Tuvalu",
    "Uganda",
    "Ukraine",
    "United Arab Emirates (the)",
    "United Kingdom of Great Britain and Northern Ireland (the)",
    "United States Minor Outlying Islands (the)",
    "United States of America (the)",
    "Uruguay",
    "Uzbekistan",
    "Vanuatu",
    "Venezuela (Bolivarian Republic of)",
    "Viet Nam",
    "Virgin Islands (British)",
    "Virgin Islands (U.S.)",
    "Wallis and Futuna",
    "Western Sahara",
    "Yemen",
    "Zambia",
    "Zimbabwe",
    "Ã…land Islands"
]

Saturday, February 12, 2022

SwiftUI Login Screen

SwiftUI Login Screen

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    @State private var username = ""
    @State private var password = ""
    @State private var wrongUsername: Float = 0
    @State private var wrongPassword: Float  = 0
    @State private var showingLoginScreen = false
    
    
    var body: some View {
        NavigationView {
            ZStack {
                Color.orange
                    .ignoresSafeArea()
                Circle()
                    .scale(1.9)
                    .foregroundColor(.white.opacity(0.29))
                Circle()
                    .scale(1.7)
                    .foregroundColor(.white)

                VStack {
                    Text("Login")
                        .font(.largeTitle)
                        .bold()
                        .padding()
                    
                    TextField("Username", text: $username)
                        .padding()
                        .frame(width: 300, height: 50)
                        .background(Color.black.opacity(0.05))
                        .cornerRadius(10)
                        .border(.red, width: CGFloat(wrongUsername))
                        
                    
                    SecureField("Password", text: $password)
                        .padding()
                        .frame(width: 300, height: 50)
                        .background(Color.black.opacity(0.05))
                        .cornerRadius(10)
                        .border(.red, width: CGFloat(wrongPassword))
                    
                    Button("Login") {
                        authenticateUser(username: username, password: password)
                        }
                    .foregroundColor(.white)
                    .frame(width: 300, height: 50)
                    .background(Color.orange)
                    .cornerRadius(10)
                    
                    NavigationLink(destination: Text("You are logged in @\(username)"), isActive: $showingLoginScreen) {
                        EmptyView()
                    }
                }
            }.navigationBarHidden(true)
        }
    }
    
    func authenticateUser(username: String, password: String) {
        if username.lowercased() == "cairocoders" {
            wrongUsername = 0
            if password.lowercased() == "123456" {
                wrongPassword = 0
                showingLoginScreen = true
            } else {
                wrongPassword = 2
            }
        } else {
            wrongUsername = 2
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SwiftUI Pop Up Menu

SwiftUI Pop Up Menu

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        Menu {
            Button("Cancel", role: .destructive) {
                print("Cancel")
            }
            
            Menu {
                Button(role: .destructive) {
                    print("Report")
                } label: {
                    Label("Report", systemImage: "flag.fill")
                }
            } label: {
                Label("Other", systemImage: "questionmark.circle")
            }
            
            Button {
                print("Download")
            } label: {
                Label("Download", systemImage: "tray.and.arrow.down.fill")
            }
            
            Button {
                print("Share")
            } label: {
                Label("Share", systemImage: "square.and.arrow.up")
            }
        } label: {
            Label("Settings", systemImage: "gearshape.fill")
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Friday, February 11, 2022

SwiftUI WebView

SwiftUI WebView

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI
import WebKit

struct ContentView: View {
    @State private var showWebView = false
    private let urlString: String = "https://www.apple.com/"
    
    var body: some View {
        VStack(spacing: 10) {

            WebView(url: URL(string: urlString)!).frame(height: 650.0)
                .cornerRadius(10)
                .shadow(color: .black.opacity(0.3), radius: 20.0, x: 5, y: 5)
                
            
            // link that opens in a new window
            Link(destination: URL(string: urlString)!, label: {
                Text("Open in new window")
                    .foregroundColor(.blue)
            })
            
            // Present WebView as a Bottom Sheet
            Button {
                showWebView.toggle()
            } label: {
                Text("Open in a sheet")
            }
            .sheet(isPresented: $showWebView) {
                WebView(url: URL(string: urlString)!)
            }
            Spacer()
            
        }.padding()
    }
}

struct WebView: UIViewRepresentable {
    
    var url: URL
    
    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }
    
    func updateUIView(_ webView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        webView.load(request)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SwiftUI Password Strength Checker

SwiftUI Password Strength Checker

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var email : String = ""
    @State var password : String = ""
    @State var passwordStrength : Int = 0
    
    func checkStrength(_ password: String) -> Int {
        let passwordLength = password.count
        var containsSymbol = false
        var containsUppercase = false

        for character in password {
            if "ABCDEFGHIJKLMNOPQRSTUVWXYZ".contains(character) {
                containsUppercase = true
            }
            
            if "!£$%&/()=?^;:_ç°§*,.-_".contains(character) {
                containsSymbol = true
            }
        }
        
        if passwordLength > 8 && containsSymbol && containsUppercase {
            return 1
        } else {
            return 0
        }
    }
    
    var body: some View {
        VStack {
            Spacer()
            
            Group {
                TextField("Email", text: $email)
                    .keyboardType(.emailAddress)
                    .autocapitalization(.none)
                TextField("Password", text: $password)
            }
            .padding(16)
            .background(Color.white)
            
            HStack {
                if checkStrength(password) == 0  {
                    Text("Weak").foregroundColor(Color.red)
                        .font(.system(size: 30.0)).padding()
                } else {
                    Text("Strong").foregroundColor(Color.green)
                        .font(.system(size: 30.0)).padding()
                }
            }
            
            Button {

            } label: {
                HStack {
                    Spacer()
                    Text("Log In")
                        .foregroundColor(.white)
                        .padding(.vertical, 10)
                        .font(.system(size: 14, weight: .semibold))
                    Spacer()
                }.background(Color.blue)
                
            }
            
            Spacer()
            
        }.padding()
        .background(SwiftUI.Color.gray.edgesIgnoringSafeArea(.all))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SwiftUI Date and Time Picker

SwiftUI Date and Time Picker

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    @State var currentTime = Date()
    var closedRange = Calendar.current.date(byAdding: .year, value: -1, to: Date())!
    
    func formatDate() -> String {
        let components = Calendar.current.dateComponents([.hour, .minute, .day, .month, .year], from: currentTime)
        let hour = components.hour ?? 0
        let minute = components.minute ?? 0
        let day = components.day ?? 0
        let month = components.month ?? 0
        let year = components.year ?? 0
        
        return "\(day)-\(month)-\(year) (\(hour):\(minute))"
    }
    
    
    var body: some View {
        Form {
            Section(header:(Text("Date Picker 1"))) {
                DatePicker("Pick a date:", selection: $currentTime) // Normal Date Time Picker
            }
            
            Section(header:(Text("Date Picker 2"))) {
                DatePicker("Pick a future date:", selection: $currentTime, in: Date()...) // Only pick a future date
            }
            
            Section(header:(Text("Date Picker 3"))) {
                DatePicker("Pick a past date:", selection: $currentTime, in: closedRange...Date(), displayedComponents: .date) // Only pick a past date
            }
            
            Section(header:(Text("Date Picker 4"))) {
                DatePicker("Pick a time:", selection: $currentTime, displayedComponents: .hourAndMinute)
            }
            
            Section(header:(Text("Result"))) {
                Text(formatDate())
            }
            
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SwiftUI Splash Screen

SwiftUI Splash Screen

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.gray
                .ignoresSafeArea()
            Text("ContentView")
                .foregroundColor(.white)
                .font(.system(size: 20))
                .bold()
                .padding()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
SplashScreenView.swift
 
//
//  SplashScreenView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct SplashScreenView: View {
    @State var isActive : Bool = false
    @State private var size = 0.8
    @State private var opacity = 0.5
    
    var body: some View {
        if isActive {
            ContentView()
        } else {
            VStack {
                VStack {
                    Image("logo")
                        .resizable()
                        .scaledToFill()
                        .frame(width: 128, height: 128)

                    Text("Cairocoders")
                        .font(Font.custom("Baskerville-Bold", size: 26))
                        .foregroundColor(.black.opacity(0.80))
                }
                .scaleEffect(size)
                .opacity(opacity)
                .onAppear {
                    withAnimation(.easeIn(duration: 1.1)) {
                        self.size = 0.9
                        self.opacity = 1.00
                    }
                }
            }
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                    withAnimation {
                        self.isActive = true
                    }
                }
            }
        }
    }
}

struct SplashScreenView_Previews: PreviewProvider {
    static var previews: some View {
        SplashScreenView()
    }
}
swiftuidev15iosApp.swift
 
//
//  swiftuidev15iosApp.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

@main
struct swiftuidev15iosApp: App {
    var body: some Scene {
        WindowGroup {
            SplashScreenView()
        }
    }
}

Monday, February 7, 2022

SwiftUI Firebase Login Register Log Out - Firebase Auth

SwiftUI Firebase Login Register Log Out - Firebase Auth

Firebase Apple Open Source Development
https://github.com/firebase/firebase-ios-sdk

SDWebImageSwiftUI
https://github.com/SDWebImage/SDWebImageSwiftUI


ContentView.swift
 
//
//  ContentView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

struct ContentView: View {
    
    @State private var isUserCurrentlyLoggedOut: Bool = false
    
    var body: some View {
        NavigationView {
            if self.isUserCurrentlyLoggedOut {
                Home(isUserCurrentlyLoggedOut: $isUserCurrentlyLoggedOut)
            }else {
                LoginRegister(isUserCurrentlyLoggedOut: $isUserCurrentlyLoggedOut)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
LoginRegister.swift
 
//
//  LoginRegister.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

struct LoginRegister: View {
    
    @State var isLoginMode = false
    @State var email = ""
    @State var password = ""
    @State var fname = ""
    @State var lname = ""
    
    @State private var shouldShowLoginAlert: Bool = false
    
    @State var StatusMessage = ""
    
    @Binding var isUserCurrentlyLoggedOut : Bool
    
    var body: some View {
        ScrollView {

            VStack(spacing: 16) {
                Picker(selection: $isLoginMode, label: Text("Picker here")) {
                    Text("Login")
                        .tag(true)
                    Text("Create Account")
                        .tag(false)
                }.pickerStyle(SegmentedPickerStyle())
                
                if !isLoginMode {
                    VStack {
                        Image(systemName: "person.fill")
                            .font(.system(size: 64))
                            .padding()
                            .foregroundColor(Color(.label))
                    }
                    .overlay(RoundedRectangle(cornerRadius: 64)
                                .stroke(Color.black, lineWidth: 3)
                    )
                    Group {
                        TextField("First Name", text: $fname)
                        TextField("Last Name", text: $lname)
                        TextField("Email", text: $email)
                            .keyboardType(.emailAddress)
                            .autocapitalization(.none)
                        SecureField("Password", text: $password)
                    }
                    .padding()
                    .background(Color.white)
                    .cornerRadius(10)
                    
                    Button {
                        handleAction()
                    } label: {
                        HStack {
                            Spacer()
                            Text("Create Account")
                                .foregroundColor(.white)
                                .padding(.vertical, 10)
                                .font(.system(size: 18, weight: .semibold))
                            Spacer()
                        }.background(Color.green)
  
                    }.cornerRadius(10)
                }else{
                    Image("Login")
                        .resizable()
                        .scaledToFill()
                        .frame(width: 128, height: 128)
                        .cornerRadius(64)
                    
                    Group {
                        TextField("Email", text: $email)
                            .keyboardType(.emailAddress)
                            .autocapitalization(.none)
                        SecureField("Password", text: $password)
                    }
                    .padding()
                    .background(Color.white)
                    .cornerRadius(10)
                    
                    Button {
                        loginUser()
                    } label: {
                        HStack {
                            Spacer()
                            Text("Login")
                                .foregroundColor(.white)
                                .padding(.vertical, 10)
                                .font(.system(size: 18, weight: .semibold))
                            Spacer()
                        }.background(Color.green)
  
                    }.cornerRadius(10)
                    .alert(isPresented: $shouldShowLoginAlert) {
                        Alert(title: Text("Email/Password incorrect"))
                    }
                }
                
                Text(self.StatusMessage)
                    .foregroundColor(Color.white)
                
            }.padding()
        } //End ScrollView
        .navigationViewStyle(StackNavigationViewStyle())
        .background(
            LinearGradient(gradient: Gradient(colors: [.white, .blue, .yellow]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
        )
    }
    
    private func loginUser() {
        Auth.auth().signIn(withEmail: email, password: password) { result, err in
            if let err = err {
                print("Failed to login user:", err)
                self.StatusMessage = "Failed to login user: \(err)"
                self.shouldShowLoginAlert = true
                return
            }
  
            print("Successfully logged in as user: \(result?.user.uid ?? "")")
  
            self.StatusMessage = "Successfully logged in as user: \(result?.user.uid ?? "")"

            self.isUserCurrentlyLoggedOut = true
        }
    }
    
    private func handleAction() {
        createNewAccount()
    }
     
    private func createNewAccount() {
        Auth.auth().createUser(withEmail: email, password: password) { result, err in
            if let err = err {
                print("Failed to create user:", err)
                self.StatusMessage = "Failed to create user: \(err)"
                return
            }
            
            print("Successfully created user: \(result?.user.uid ?? "")")
  
            self.StatusMessage = "Successfully created user: \(result?.user.uid ?? "")"
            
            self.storeUserInformation()
        }
    }
    
    private func storeUserInformation() {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let userData = ["fname": self.fname, "lname": self.lname, "email": self.email, "profileImageUrl": "profileurl", "uid": uid]
        Firestore.firestore().collection("users")
            .document(uid).setData(userData) { err in
                if let err = err {
                    print(err)
                    self.StatusMessage = "\(err)"
                    return
                }
 
                print("Success")
            }
    }
}

struct LoginRegister_Previews: PreviewProvider {
    @State static var isUserCurrentlyLoggedOut = false
    static var previews: some View {
        LoginRegister(isUserCurrentlyLoggedOut: $isUserCurrentlyLoggedOut)
    }
}
Home.swift
 
//
//  Home.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI
import Firebase

struct Home: View {
    @State var shouldShowLogOutOptions = false
    
    @ObservedObject private var vm = MainMessagesViewModel()
    
    @Binding var isUserCurrentlyLoggedOut : Bool
    
    @State var index = 0
    
    var body: some View {
            
        VStack {
            //Text("User: \(vm.chatUser?.uid ?? "")")
            customNavBar

            ZStack {
                if self.index == 0 {
                    VStack {
                        Image("home")
                            .resizable()
                    }
                }
                else if self.index == 1 {
                    VStack {
                        Image("profile")
                            .resizable()
                    }
                }
                else if self.index == 2 {
                    Color.red.edgesIgnoringSafeArea(.top)
                    VStack {
                        Text("Notification").foregroundColor(Color.white)
                        Image(systemName: "bell.fill")
                            .resizable()
                            .frame(width: 200, height: 200)
                    }
                }
                else{
                    Color.yellow.edgesIgnoringSafeArea(.top)
                    VStack {
                        Text("Cart").foregroundColor(Color.white)
                        Image(systemName: "cart.fill")
                            .resizable()
                            .frame(width: 200, height: 200)
                    }
                }
            }
                 
            CustomTabBar(index: $index)
        }
        .navigationBarHidden(true)
        .animation(.spring())
    }
    
    private var customNavBar: some View {
        HStack(spacing: 16) {

            WebImage(url: URL(string: vm.chatUser?.profileImageUrl ?? ""))
                .resizable()
                .scaledToFill()
                .frame(width: 50, height: 50)
                .clipped()
                .cornerRadius(50)
                .overlay(RoundedRectangle(cornerRadius: 44)
                            .stroke(Color(.label), lineWidth: 1)
                )
                .shadow(radius: 5)
            
            VStack(alignment: .leading, spacing: 4) {
                let email = vm.chatUser?.email.replacingOccurrences(of: "@gmail.com", with: "") ?? ""
                Text(email)
                    .font(.system(size: 24, weight: .bold))
                
                HStack {
                    Circle()
                        .foregroundColor(.green)
                        .frame(width: 14, height: 14)
                    Text("online")
                        .font(.system(size: 12))
                        .foregroundColor(Color(.lightGray))
                }
                
            }
            
            Spacer()
            Button {
                shouldShowLogOutOptions.toggle()
            } label: {
                Image(systemName: "gear")
                    .font(.system(size: 24, weight: .bold))
                    .foregroundColor(Color(.label))
            }
        }
        .padding()
        .actionSheet(isPresented: $shouldShowLogOutOptions) {
            .init(title: Text("Settings"), message: Text("What do you want to do?"), buttons: [
                .destructive(Text("Sign Out"), action: {
                    print("handle sign out")
                    try? Auth.auth().signOut()
                    self.isUserCurrentlyLoggedOut = false
                }),
                    .cancel()
            ])
        }
    }
}

struct Home_Previews: PreviewProvider {
    @State static var isUserCurrentlyLoggedOut = false
    static var previews: some View {
        Home(isUserCurrentlyLoggedOut: $isUserCurrentlyLoggedOut)
    }
}
MainMessagesViewModel.swift
 
//
//  MainMessagesViewModel.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI
import Firebase

struct ChatUser {
    let uid, email, profileImageUrl: String
}

class MainMessagesViewModel: ObservableObject {
    
    @Published var errorMessage = ""
    @Published var chatUser: ChatUser?
    
    init() {
        
        fetchCurrentUser()
    }
    
    private func fetchCurrentUser() {

        guard let uid = Auth.auth().currentUser?.uid else {
            self.errorMessage = "Could not find firebase uid"
            return
        }
        
        
        Firestore.firestore().collection("users").document(uid).getDocument { snapshot, error in
            if let error = error {
                self.errorMessage = "Failed to fetch current user: \(error)"
                print("Failed to fetch current user:", error)
                return
            }
            
            self.errorMessage = "123"
            
            guard let data = snapshot?.data() else {
                self.errorMessage = "No data found"
                return
                
            }
            self.errorMessage = "Data: \(data.description)"
            let uid = data["uid"] as? String ?? ""
            let email = data["email"] as? String ?? ""
            let profileImageUrl = data["profileImageUrl"] as? String ?? ""
            
            self.chatUser = ChatUser(uid: uid, email: email, profileImageUrl: profileImageUrl)
            
            //self.errorMessage = chatUser.profileImageUrl
            
        }
    }
}
CustomTabBar.swift
 
//
//  CustomTabBar.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
 
struct CustomTabBar : View {
     
    @Binding var index : Int
     
    var body: some View {
         
        HStack(spacing: 15) {
             
            HStack {
                Image(systemName: "house.fill")
                    .resizable()
                    .frame(width: 35, height: 30)
                 
                Text(self.index == 0 ? "Home" : "")
                    .fontWeight(.light)
                    .font(.system(size:14))
            }.padding(15)
            .background(self.index == 0 ? Color.green.opacity(0.5) : Color.clear)
            .clipShape(Capsule())
            .onTapGesture {
                self.index = 0
            }
             
            HStack {
                Image(systemName: "person.fill")
                    .resizable()
                    .frame(width: 35, height: 30)
                 
                Text(self.index == 1 ? "Profile" : "")
                    .fontWeight(.light)
                    .font(.system(size:14))
            }.padding(15)
            .background(self.index == 1 ? Color.blue.opacity(0.5) : Color.clear)
            .clipShape(Capsule())
            .onTapGesture {
                self.index = 1
            }
             
            HStack {
                Image(systemName: "bell.fill")
                    .resizable()
                    .frame(width: 35, height: 30)
                 
                Text(self.index == 2 ? "Notification" : "")
                    .fontWeight(.light)
                    .font(.system(size:14))
            }.padding(15)
            .background(self.index == 2 ? Color.red.opacity(0.5) : Color.clear)
            .clipShape(Capsule())
            .onTapGesture {
                self.index = 2
            }
             
            HStack {
                Image(systemName: "cart.fill")
                    .resizable()
                    .frame(width: 35, height: 30)
                 
                Text(self.index == 3 ? "Cart" : "")
                    .fontWeight(.light)
                    .font(.system(size:14))
            }.padding(15)
            .background(self.index == 3 ? Color.yellow.opacity(0.5) : Color.clear)
            .clipShape(Capsule())
            .onTapGesture {
                self.index = 3
            }
             
        }.padding(.top, 8)
        .frame(width: UIScreen.main.bounds.width)
        .background(Color.white)
        .animation(.default)
    }
}

struct CustomTabBar_Previews: PreviewProvider {
    @State static var index = 0
    static var previews: some View {
        CustomTabBar(index: $index)
    }
}
DevSwiftUIApp.swift
 
//
//  DevSwiftUIApp.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//
 
import SwiftUI
import Firebase
 
@main
struct DevSwiftUIApp: App {
     
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
      
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
  
class AppDelegate: NSObject,UIApplicationDelegate{
      
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
          
        FirebaseApp.configure()
        return true
    }
}

Thursday, January 27, 2022

SwiftUI Spinner Loading/Waiting Activity

SwiftUI Spinner Loading/Waiting Activity

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {

    @State var show = false
    
    var body: some View {

        ZStack {
            if self.show {
                GeometryReader { geometry in
                    Loader()
                        .position(x: geometry.size.width / 2, y: geometry.size.height / 2)
                }.background(Color.black.opacity(0.45).edgesIgnoringSafeArea(.all))
                    .onTapGesture {
                        self.show.toggle()
                    }
                
            }else {
                Button(action: {
                    self.show.toggle()
                }) {
                    Text("Show Custom Indicator")
                }
            }
        }
        

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Loader : View {
    
    @State var animate = false
    
    var body: some View {
        VStack {
            Circle()
                .trim(from: 0, to: 0.8)
                .stroke(AngularGradient(gradient: .init(colors: [.red,.orange]), center: .center), style: StrokeStyle(lineWidth: 8, lineCap: .round))
                .frame(width: 45, height: 45)
                .rotationEffect(.init(degrees: self.animate ? 360 : 0))
                .animation(Animation.linear(duration: 0.7).repeatForever(autoreverses: false))
                .padding(.top, 10)
            
            Text("Please Wait...").padding()
        }
        .background(Color.white)
        .cornerRadius(15)
        .onAppear {
            self.animate.toggle()
        }
    }
}

SwiftUI User Notification

SwiftUI User Notification

ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders 
//

import SwiftUI

struct ContentView: View {

    var body: some View {
        NavigationView {
            ZStack {
                Button(action: {
                    self.send()
                }) {
                    Text("Send Notification")
                }.navigationBarTitle("Home")
            }
        }
    }
    
    func send() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in
            if success {
                print("All set!")
            } else if let error = error {
                print(error.localizedDescription)
            }
        }
        
        let content = UNMutableNotificationContent()
        content.title = "Message"
        content.subtitle = "New Tutorial from cairocoders!!"
        content.sound = UNNotificationSound.default
        
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Thursday, January 13, 2022

SwiftUI Grocery App UI

SwiftUI Grocery App UI
ContentView.swift
//
//  ContentView.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var selected = "Home"
    
    var body: some View {
        
        NavigationView{
            VStack{
                if self.selected == "Home"{
                    Home()
                }
                else if self.selected == "Wishlist"{
                    GeometryReader{_ in
                        Text("Wishlist")
                    }
                }
                else{
                    GeometryReader{_ in
                        Text("Cart")
                    }
                }
                CustomTabView(selected: $selected)
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct CustomTabView : View {
    
    @Binding var selected : String
    
    var body : some View{
        HStack{
            ForEach(tabs,id: \.self){i in
                VStack(spacing: 10){
                    
                    Capsule()
                        .fill(Color.clear)
                        .frame(height: 5)
                        .overlay(
                            Capsule().fill(self.selected == i ? Color("Color") : Color.clear).frame(width: 55, height: 5)
                         )
                    
                    Button(action: {
                        self.selected = i
                    }) {
                        VStack{
                            Image(i).renderingMode(.original)
                            Text(i).foregroundColor(.black)
                        }
                    }
                }
            }
        }.padding(.horizontal)
    }
}
Home.swift
//
//  Home.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct Home : View {
    
    @State var txt = ""
    
    var body : some View{
        
        VStack(spacing: 15){
            HStack(spacing: 12){
                Image("photo1").renderingMode(.original).resizable().frame(width: 30, height: 30)
                Text("Cairocoders").font(.body)
                
                Spacer()
                
                Button(action: {
                }) {
                    Image(systemName: "cart").renderingMode(.original)
                }
            }

            ScrollView(.vertical, showsIndicators: false) {
                VStack(spacing: 15){
                    HStack(spacing: 15){
                        HStack{
                            Image(systemName: "magnifyingglass").font(.body)
                            TextField("Search Groceries", text: $txt)
                        }.padding(10)
                        .background(Color("Color1"))
                        .cornerRadius(20)
                        
                        Button(action: {
                        }) {
                            Image(systemName: "mic").renderingMode(.original)
                        }
                    }
                    
                    Image("banner")
                        .resizable()
                        .frame(height: 170)
                        .cornerRadius(10)
                        .overlay(
                            VStack{
                                Spacer()
                                HStack{
                                    Text("GET 30% OFF").font(.title).foregroundColor(.white)
                                    Spacer()
                                }.padding()
                            }
                        )
                    
                    HStack{
                        Text("Categories").font(.title)
                        
                        Spacer()
                        
                        Button(action: {
                        }) {
                            Text("More")
                        }.foregroundColor(Color("Color"))
                        
                    }.padding(.vertical, 15)
                    
                    ScrollView(.horizontal, showsIndicators: false) {
                        HStack(spacing: 15){
                            ForEach(categories,id: \.self){i in
                                VStack{
                                    Image(i).renderingMode(.original)
                                    Text(i)
                                }
                            }
                        }
                    }

                    HomeBottomView()
                }
            }
        }//end VStack
        .padding(.horizontal)
        .background(Color.white)
    }
}

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
    }
}


struct HomeBottomView : View {
    
    var body : some View{
        
        VStack(spacing: 15){
            HStack{
                Text("Deal of the Day").font(.title)
                
                Spacer()
                
                Button(action: {
                }) {
                    Text("More")
                }.foregroundColor(Color("Color"))
                
            }.padding(.vertical, 15)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 15){
                    ForEach(dealoftheday){i in
                        DealCellView(data: i)
                    }
                }
            }
            
            HStack{
                Text("Popular").font(.title)
                Spacer()
            }.padding(.vertical, 15)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 15){
                    ForEach(recipeitems){i in
                        PopularCellView(data: i)
                    }
                }
            }
        } //End VStack
    }
}

struct DealCellView : View {
    
    var data : deal
    @State var show = false
    
    var body : some View{
        ZStack{
            NavigationLink(destination: Detail(show: self.$show, viewdata: data), isActive: self.$show) {
                Text("")
            }
            VStack(spacing: 10){
                Image(data.image).resizable().scaledToFill().frame(width: 150, height: 150).cornerRadius(10)
                    
                Text(data.name).fontWeight(.semibold)
                Text(data.price).foregroundColor(.green).fontWeight(.semibold)
            }.onTapGesture {
                self.show.toggle()
            }
        }
    }
}

struct PopularCellView : View {
    
    var data : popular

    var body : some View{
        ZStack{
            VStack(spacing: 10){
                Image(data.image).resizable().scaledToFill().frame(width: 150, height: 150).cornerRadius(10)
                
                Text(data.name).fontWeight(.semibold)
                Text(data.price).foregroundColor(.green).fontWeight(.semibold)
            }
        }
    }
}
Detail.swift
//
//  Detail.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

struct Detail : View {
    
    @Binding var show : Bool
    @State var count = 0
    let viewdata : deal
    
    var body : some View{
        
        VStack(spacing: 0){
            Image(viewdata.image)
                .resizable()
                .frame(height: UIScreen.main.bounds.height / 2.5)
                .edgesIgnoringSafeArea(.top)
                .overlay(
                    VStack{
                        HStack(spacing: 12){
                            Button(action: {
                                self.show.toggle()
                            }) {
                                Image(systemName: "arrow.left").renderingMode(.original)
                            }
                            
                            Spacer()
                            
                            Button(action: {
                            }) {
                                Image(systemName: "tray.and.arrow.down.fill").renderingMode(.original)
                            }
                            
                            Button(action: {
                            }) {
                                Image(systemName: "heart").renderingMode(.original)
                            }
                        }.padding()
                        
                        Spacer()
                    }
                )// End Overlay
            
            ScrollView(.vertical, showsIndicators: false) {
                VStack(alignment: .leading,spacing: 15){
                    Text(viewdata.name).font(.title)
                    
                    Text(viewdata.price).foregroundColor(.green)
                    
                    Divider().padding(.vertical, 15)
                    
                    HStack{
                        Text(viewdata.name)
                        
                        Spacer()
                        
                        Button(action: {
                        }) {
                            Image(systemName: "message.and.waveform").renderingMode(.original)
                        }
                    }
                    
                    Text("Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit. Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.").foregroundColor(.gray)
                    
                    HStack(spacing: 20){
                        Spacer(minLength: 12)
                        Button(action: {
                            self.count += 1
                        }) {
                            Image(systemName: "plus.circle").font(.largeTitle)
                        }.foregroundColor(.green)
                        
                        Text("\(self.count)")
                        
                        Button(action: {
                            if self.count != 0{
                                self.count -= 1
                            }
                        }) {
                            Image(systemName: "minus.circle").font(.largeTitle)
                        }.foregroundColor(.green)
                        
                        Button(action: {
                        }) {
                            Text("Add to Cart").padding()
                        }.foregroundColor(.white)
                        .background(Color("Color"))
                        .cornerRadius(12)
                        
                        Spacer(minLength: 12)
                    }
                }
                
            }.padding()
            .background(RoundedCorner().fill(Color.white))
            .padding(.top, -80)
            
            .navigationBarTitle("")
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
            
        }
    }
}

struct Detail_Previews: PreviewProvider {
    @State static var show = false
    static var previews: some View {
        Detail(show: $show, viewdata: deal(id: 1, name: "Banana", price: "5 / kg", image: "1"))
    }
}

struct RoundedCorner : Shape {
    
    func path(in rect: CGRect) -> Path {
        
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 35, height: 35))
        
        return Path(path.cgPath)
    }
}
Model.swift
//
//  Model.swift
//  swiftuidev15ios
//
//  Created by Cairocoders
//

import SwiftUI

var tabs = ["Home","Wishlist","Cart"]

var categories = ["Fruits","Vegetables","Beverages","Meat","Breads"]

struct deal : Identifiable {
    
    var id : Int
    var name : String
    var price : String
    var image : String
}

struct popular : Identifiable {
    
    var id : Int
    var name : String
    var price : String
    var image : String
}

var dealoftheday = [
    deal(id: 0, name: "Strawberry", price: "5.00 / kg",image: "1"),
    deal(id: 1, name: "Pineapples", price: "3.00 / kg",image: "2"),
    deal(id: 2, name: "Banana", price: "3.00 / pack",image: "4")
]

var recipeitems = [
    popular(id: 0, name: "Apple", price: "2.99 / kg",image: "3"),
    popular(id: 1, name: "Salad", price: "4.99 / pack",image: "5"),
    popular(id: 2, name: "Broccoli", price: "5.69",image: "6")
]

Related Post