// // ContentView.swift // Test // // Created by Cairocoders // import SwiftUI struct ContentView: View { var body: some View { Image(systemName: "person.fill") .data(url: URL(string: "https://freepngimg.com/thumb/one_piece/23231-5-one-piece-chibi-image-thumb.png")!) .scaleEffect() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } extension Image { func data(url:URL) -> Self { if let data = try? Data(contentsOf: url) { return Image(uiImage: UIImage(data: data)!) .resizable() } return self .resizable() } }
article
Wednesday, June 9, 2021
SwiftUI fetch image from URL
SwiftUI fetch image from URL
Sunday, June 6, 2021
Display Loading Image when AJAX call is in Progress using Python Flask PostgreSQL
Display Loading Image when AJAX call is in Progress using Python Flask PostgreSQL
app.py
install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2
CREATE TABLE posts (
id serial PRIMARY KEY,
title VARCHAR ( 100 ) NOT NULL,
content TEXT NOT NULL,
link VARCHAR ( 100 ) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO
posts(title, content, link, created_at)
VALUES
('What is AngularJS', 'AngularJS is a JavaScript MVC framework developed by Google that lets you build well structured, easily testable, declarative and maintainable front-end applications which provides solutions to standard infrastructure concerns.', 'link-5', '2021-03-20 16:00:00'),
('What is MongoDB', 'It is a quick tutorial on MongoDB and how you can install it on your Windows OS. We will also learn some basic commands in MongoDB for example, creating and dropping a Database, Creation of a collection and some more operations related to the collection.', 'link-6', '2021-03-21 16:00:00'),
('Python Flask Load content Dynamically in Bootstrap Modal with Jquery AJAX and Mysqldb', 'Python Flask Load content Dynamically in Bootstrap Modal with Jquery AJAX and Mysqldb', 'link-6', '2021-03-20 16:00:00'),
('AutoComplete Textbox with Image using jQuery Ajax PHP Mysql and JqueryUI', 'AutoComplete Textbox with Image using jQuery Ajax PHP Mysql and JqueryUI', 'link-7', '2021-03-14 16:00:00'),
('PHP Mysql Registration Form Validation using jqBootstrapValidation with Jquery Ajax', 'PHP Mysql Registration Form Validation using jqBootstrapValidation with Jquery Ajax', 'link-8', '2021-03-20 16:00:00'),
('Python Flask Registration Form Validation using jqBootstrapValidation with Jquery Ajax and Mysql', 'Python Flask Registration Form Validation using jqBootstrapValidation with Jquery Ajax and Mysql', 'link-9', '2021-03-19 16:00:00'),
('Displaying Popups data on mouse hover using Jquery Ajax and PHP Mysql database', 'Displaying Popups data on mouse hover using Jquery Ajax and PHP Mysql database', 'link-10', '2021-03-15 16:00:00'),
('Displaying Popups data on mouse hover using Jquery Ajax and Python Flask Mysql database', 'Displaying Popups data on mouse hover using Jquery Ajax and Python Flask Mysql database', 'link-11', '2021-03-14 16:00:00');
#app.py from flask import Flask, request, render_template, jsonify, json import psycopg2 #pip install psycopg2 import psycopg2.extras app = Flask(__name__) app.secret_key = "cairocoders-ednalan" DB_HOST = "localhost" DB_NAME = "sampledb" DB_USER = "postgres" DB_PASS = "admin" conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST) @app.route('/') def home(): return render_template('index.html') @app.route("/fetchdeta",methods=["POST","GET"]) def fetchdeta(): cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) if request.method == 'POST': search = request.form['search'] print(search) query = "SELECT * from posts WHERE title LIKE '%{}%'".format(search,) cursor.execute(query) postslist = cursor.fetchall() cursor.close() return jsonify({'htmlresponse': render_template('response.html',postslist=postslist)}) if __name__ == "__main__": app.run()templates.index.html
//templates.index.html <html> <head> <title>Display Loading Image when AJAX call is in Progress using Python Flask PostgreSQL</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h3 align="center">Display Loading Image when AJAX call is in Progress using Python Flask PostgreSQL</h3> Search : <input type='text' id='search' class="form-control" style="width:40%;"><br/> <input type='button' id='but_search' value='Search' class="btn btn-default"><br/> <!-- Image loader --> <div id='loader' style='display: none;'> <img src='/static/img/loader.gif'> <b>Loading..</b> </div> <br/> <!-- Image loader --> <div class='response'></div> </div> </div> <script type='text/javascript'> $(document).ready(function(){ $("#but_search").click(function(){ var search = $('#search').val(); $.ajax({ url: '/fetchdeta', type: 'post', data: {search:search}, beforeSend: function(){ // Show image container $("#loader").show(); }, success: function(response){ $('.response').empty(); $('.response').append(response.htmlresponse); }, complete:function(data){ // Hide image container $("#loader").hide(); } }); }); }); </script> <style> .post{ width: 97%; min-height: 200px; padding: 5px; border: 1px solid gray; margin-bottom: 15px; } .post h1{ letter-spacing: 1px; font-weight: normal; font-family: sans-serif; } .post p{ letter-spacing: 1px; text-overflow: ellipsis; line-height: 25px; } </style> </body> </html>templates/response.html
//templates/response.html {% for row in postslist %} <div class="post" id="post_{{row.id}}"> <h1>{{row.title}}</h1> <p>{{row.content}}</p> <a href="{{row.link}}" class="more" target="_blank">More</a> </div> {% endfor %}
Friday, June 4, 2021
Filter Records using jQuery UI slider with Jquery Ajax and Python Flask PostgreSQL
Filter Records using jQuery UI slider with Jquery Ajax and Python Flask PostgreSQL
app.py
install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2
CREATE TABLE employee (
id serial PRIMARY KEY,
name VARCHAR ( 100 ) NOT NULL,
position VARCHAR ( 100 ) NOT NULL,
office VARCHAR ( 100 ) NOT NULL,
age INT NOT NULL,
salary INT NOT NULL,
photo VARCHAR ( 150 ) NOT NULL,
);
INSERT INTO
employee(name, position, office, age, salary, photo)
VALUES
('Tiger Wood', 'Accountant', 'Tokyo', 36, 5689, '01.jpg'),
('Mark Oto Ednalan', 'Chief Executive Officer (CEO)', 'London', 56, 5648, '02.jpg'),
('Jacob thompson', 'Junior Technical Author', 'San Francisco', 23, 5689, '03.jpg'),
('cylde Ednalan', 'Software Engineer', 'Olongapo', 23, 54654, '04.jpg'),
('Rhona Davidson', 'Software Engineer', 'San Francisco', 26, 5465, '05.jpg'),
('Quinn Flynn', 'Integration Specialist', 'New York', 53, 56465, '06.jpg'),
('Tiger Nixon', 'Software Engineer', 'London', 45, 456, '07.jpg'),
('Airi Satou', 'Pre-Sales Support', 'New York', 25, 4568, '08.jpg'),
('Angelica Ramos', 'Sales Assistant', 'New York', 45, 456, '09.jpg'),
('Ashton updated', 'Senior Javascript Developer', 'Olongapo', 45, 54565, '01.jpg'),
('Bradley Greer', 'Regional Director', 'San Francisco', 27, 5485, '02.jpg'),
('Brenden Wagner', 'Javascript Developer', 'San Francisco', 38, 65468, '03.jpg'),
('Brielle Williamson', 'Personnel Lead', 'Olongapo', 56, 354685, '04.jpg'),
('Bruno Nash', 'Customer Support', 'New York', 36, 65465, '05.jpg'),
('cairocoders', 'Sales Assistant', 'Sydney', 45, 56465, '06.jpg'),
('Zorita Serrano', 'Support Engineer', 'San Francisco', 38, 6548, '07.jpg'),
('Zenaida Frank', 'Chief Operating Officer (COO)', 'San Francisco', 39, 545, '08.jpg'),
('Sakura Yamamoto', 'Support Engineer', 'Tokyo', 48, 5468, '05.jpg'),
('Serge Baldwin', 'Data Coordinator', 'Singapore', 85, 5646, '05.jpg'),
('Shad Decker', 'Regional Director', 'Tokyo', 45, 4545, '05.jpg');
JqueryUI Slider https://jqueryui.com/slider/
#app.py from flask import Flask, request, render_template, jsonify, json import psycopg2 #pip install psycopg2 import psycopg2.extras app = Flask(__name__) app.secret_key = "cairocoders-ednalan" DB_HOST = "localhost" DB_NAME = "sampledb" DB_USER = "postgres" DB_PASS = "admin" conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST) @app.route('/') def home(): try: cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) cursor.execute("SELECT * from employee order by name asc") employeelist = cursor.fetchall() return render_template('index.html',employeelist=employeelist) except Exception as e: print(e) finally: cursor.close() @app.route("/fetchdeta",methods=["POST","GET"]) def fetchdeta(): try: cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) if request.method == 'POST': min = request.form['min'] max = request.form['max'] cursor.execute("SELECT * from employee WHERE salary>=(%s) AND salary<=(%s)", [min,max,]) employeelist = cursor.fetchall() return jsonify({'htmlresponse': render_template('response.html',employeelist=employeelist)}) except Exception as e: print(e) finally: cursor.close() if __name__ == "__main__": app.run()templates/index.html
//templates/index.html <!doctype html> <html> <head> <title>Filter Records using jQuery UI slider with Jquery Ajax and Python Flask PostgreSQL</title> <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script type='text/javascript'> $(document).ready(function(){ // Initializing slider $( "#slider" ).slider({ range: true, min: 100, max: 360000, values: [ 100, 360000 ], slide: function( event, ui ) { // Get values var min = ui.values[0]; var max = ui.values[1]; $('#range').text(min+' - ' + max); // AJAX request $.ajax({ url: '/fetchdeta', type: 'post', data: {min:min,max:max}, success: function(response){ // Updating table data $('#emp_table tr:not(:first)').remove(); $('#emp_table').append(response.htmlresponse); } }); } }); }); </script> </head> <body > <div class="container" > <div class="row" style="padding:50px;"> <p><h1>Filter Records using jQuery UI slider with Jquery Ajax and Python Flask PostgreSQL</h1></p> <!-- slider --> <div id="slider"></div><br/> Range: <span id='range'></span> <table id='emp_table' class="alternate" width='100%'> <tr> <th>Name</th> <th>Position</th> <th>Office</th> <th>Salary</th> </tr> {% for row in employeelist %} <tr> <td>{{row.name}}</td> <td>{{row.position}}</td> <td>{{row.office}}</td> <td>{{row.salary}}</td> </tr> {% endfor %} </table> </div> </div> <style> .alternate tr:nth-child(2n) { background-color: silver; } .alternate tr { background-color: white; } .alternate tr td {padding: 8px;} .alternate tr:nth-child(2n):hover, .alternate tr:hover { background-color: grey; } </style> </body> </html>templates/response.html
//templates/response.html {% for row in employeelist %} <tr> <td>{{row.name}}</td> <td>{{row.position}}</td> <td>{{row.office}}</td> <td>{{row.salary}}</td> </tr> {% endfor %}
Thursday, June 3, 2021
SwiftUI Contact and Details Using List and Navigation View
SwiftUI Contact and Details Using List and Navigation View
ContentView.swift
ContentView.swift
// // ContentView.swift // Test // // Created by Cairocoders // import SwiftUI struct ContentView: View { var body: some View { NavigationView { List(contacts) { contact in NavigationLink(destination: DetailView(contact: contact)) { ContactRow(contact: contact) } } .navigationBarTitle("Contacts") } .environment(\.colorScheme, .light) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct ContactRow: View { let contact: Contact var body: some View { HStack { Image(contact.imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 60, height: 60) .clipped() .cornerRadius(50) VStack(alignment: .leading) { Text(contact.name) .font(.system(size: 21, weight: .medium, design: .default)) Text(contact.phone) } } } }Contact.swift
// // Contact.swift // Test // // Created by Cairocoders // import Foundation struct Contact: Identifiable { let imageName: String let name: String let phone: String let email: String let office: String let position: String let age: String let startdate: String let salary: Int let id = UUID() } let contacts = [ Contact(imageName: "photo1", name: "Airi Satou", phone: "+0123-4567896", email: "airisatou@gmail.com", office: "Tokyo", position: "Accountant", age: "25", startdate: "2008/11/28", salary: 89560), Contact(imageName: "photo2", name: "Angelica Ramos", phone: "+1(698)-1881047", email: "engelicaramos@gmail.com.com", office: "London", position: "Chief Executive Officer (CEO)", age: "45", startdate: "2009/10/09", salary: 58568), Contact(imageName: "photo3", name: "Ashton Cox", phone: "+1(234)-3442899", email: "astoncox@gmail.com", office: "San Francisco", position: "Junior Technical Author", age: "56",startdate: "2008/11/28", salary: 1560), Contact(imageName: "photo4", name: "Bradley Greer", phone: "+1(765)-7448466", email: "bradlyfresn@gmail.com", office: "London", position: "Software Engineer", age: "26", startdate: "2008/11/28", salary: 9960), Contact(imageName: "photo5", name: "Brenden Wagner", phone: "+1(213)-5115553", email: "brdndanwgner@gmail.com", office: "San Francisco", position: "Software Engineer", age: "26", startdate: "2008/11/28", salary: 8860), Contact(imageName: "photo6", name: "Brielle Williamson", phone: "+1(453)-0663954", email: "brillewilson@gmail.com", office: "New York", position: "Software Engineer", age: "56", startdate: "2008/11/28", salary: 8760) ]DetailView.swift
// // DetailView.swift // Test // // Created by Cairocoders // import SwiftUI struct DetailView: View { let contact: Contact var body: some View { VStack { Image(contact.imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 150, height: 150) .clipped() .cornerRadius(150) .shadow(radius: 3) Text(contact.name) .font(.title) .fontWeight(.medium) Form { Section { HStack { Text("Phone") Spacer() Text(contact.phone) .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } HStack { Text("Email") Spacer() Text(contact.email) .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } HStack { Text("Office") Spacer() Text(contact.office) .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } HStack { Text("Position") Spacer() Text(contact.position) .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } HStack { Text("Age") Spacer() Text(contact.age) .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } HStack { Text("Start Date") Spacer() Text(contact.startdate) .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } HStack { Text("Salary") Spacer() Text("$\(contact.salary)") .foregroundColor(.gray) .font(.callout) .frame(alignment: .leading) } } Section { Button(action: { print("Send a message") }) { Text("Send a message") } Button(action: { print("Call") }) { Text("Call") } } } } .environment(\.colorScheme, .light) } } struct DetailView_Previews: PreviewProvider { static var previews: some View { DetailView(contact: contacts[0]) .padding(.top, 60) } }
Wednesday, June 2, 2021
SwiftUI Firestore CRUD Create, Read, Update and Delete
SwiftUI Firestore CRUD Create, Read, Update and Delete
ContentView.swift
Movie list screen is the homepage of the application it shows a list of all the movie records
Tap list item display details
tapping add plus button dialog form display add new records tap done button to add new movie
cancel button to dismiss dialog
tapping edit button to edit dialog form then save or Delete record
Swift packages https://github.com/firebase/firebase-ios-sdk
// // ContentView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI struct ContentView: View { @StateObject var viewModel = MoviesViewModel() //MovieViewModel.swift @State var presentAddMovieSheet = false private var addButton: some View { Button(action: { self.presentAddMovieSheet.toggle() }) { Image(systemName: "plus") } } private func movieRowView(movie: Movie) -> some View { NavigationLink(destination: MovieDetailsView(movie: movie)) { //MovieDetailsView.swift VStack(alignment: .leading) { Text(movie.title) .font(.headline) //Text(movie.description) // .font(.subheadline) Text(movie.year) .font(.subheadline) } } } var body: some View { NavigationView { List { ForEach (viewModel.movies) { movie in movieRowView(movie: movie) } .onDelete() { indexSet in //viewModel.removeMovies(atOffsets: indexSet) viewModel.removeMovies(atOffsets: indexSet) } } .navigationBarTitle("Movie") .navigationBarItems(trailing: addButton) .onAppear() { print("MoviesListView appears. Subscribing to data updates.") self.viewModel.subscribe() } .sheet(isPresented: self.$presentAddMovieSheet) { MovieEditView() //MovieEditView.swift } }// End Navigation }// End Body } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }Models/Movie.swift
// // Movie.swift // DevSwiftUI // // Created by Cairocoders // import Foundation import Foundation import FirebaseFirestoreSwift struct Movie: Identifiable, Codable { @DocumentID var id: String? var title: String var description: String var year: String enum CodingKeys: String, CodingKey { case id case title case description case year } }DevSwiftUIApp.swift
// // DevSwiftUIApp.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI import Firebase @main struct DevSwiftUIApp: App { init() { FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView() } } }ViewModels/MoviesViewModel.swift
// // MoviesViewModel.swift // DevSwiftUI // // Created by Cairocoders on 6/3/21. // import Foundation import Combine import FirebaseFirestore class MoviesViewModel: ObservableObject { @Published var movies = [Movie]() private var db = Firestore.firestore() private var listenerRegistration: ListenerRegistration? deinit { unsubscribe() } func unsubscribe() { if listenerRegistration != nil { listenerRegistration?.remove() listenerRegistration = nil } } func subscribe() { if listenerRegistration == nil { listenerRegistration = db.collection("movielist").addSnapshotListener { (querySnapshot, error) in guard let documents = querySnapshot?.documents else { print("No documents") return } self.movies = documents.compactMap { queryDocumentSnapshot in try? queryDocumentSnapshot.data(as: Movie.self) } } } } func removeMovies(atOffsets indexSet: IndexSet) { let movies = indexSet.lazy.map { self.movies[$0] } movies.forEach { movie in if let documentId = movie.id { db.collection("movielist").document(documentId).delete { error in if let error = error { print("Unable to remove document: \(error.localizedDescription)") } } } } } }ViewModels/MovieViewModel.swift
// // MovieViewModel.swift // DevSwiftUI // // Created by Cairocoders // import Foundation import Combine import FirebaseFirestore class MovieViewModel: ObservableObject { @Published var movie: Movie @Published var modified = false private var cancellables = Set<anycancellable>() init(movie: Movie = Movie(title: "", description: "", year: "")) { self.movie = movie self.$movie .dropFirst() .sink { [weak self] movie in self?.modified = true } .store(in: &self.cancellables) } // Firestore private var db = Firestore.firestore() private func addMovie(_ movie: Movie) { do { let _ = try db.collection("movielist").addDocument(from: movie) } catch { print(error) } } private func updateMovie(_ movie: Movie) { if let documentId = movie.id { do { try db.collection("movielist").document(documentId).setData(from: movie) } catch { print(error) } } } private func updateOrAddMovie() { if let _ = movie.id { self.updateMovie(self.movie) } else { addMovie(movie) } } private func removeMovie() { if let documentId = movie.id { db.collection("movielist").document(documentId).delete { error in if let error = error { print(error.localizedDescription) } } } } // UI handlers func handleDoneTapped() { self.updateOrAddMovie() } func handleDeleteTapped() { self.removeMovie() } }View/MovieDetailsView.swift
// // MovieDetailsView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI struct MovieDetailsView: View { @Environment(\.presentationMode) var presentationMode @State var presentEditMovieSheet = false var movie: Movie private func editButton(action: @escaping () -> Void) -> some View { Button(action: { action() }) { Text("Edit") } } var body: some View { Form { Section(header: Text("Movie")) { Text(movie.title) Text(movie.description) } Section(header: Text("Year")) { Text(movie.year) } } .navigationBarTitle(movie.title) .navigationBarItems(trailing: editButton { self.presentEditMovieSheet.toggle() }) .onAppear() { print("MovieDetailsView.onAppear() for \(self.movie.title)") } .onDisappear() { print("MovieDetailsView.onDisappear()") } .sheet(isPresented: self.$presentEditMovieSheet) { MovieEditView(viewModel: MovieViewModel(movie: movie), mode: .edit) { result in if case .success(let action) = result, action == .delete { self.presentationMode.wrappedValue.dismiss() } } } } } struct MovieDetailsView_Previews: PreviewProvider { static var previews: some View { let movie = Movie(title: "title movie", description: "this is a sample description", year: "2021") return NavigationView { MovieDetailsView(movie: movie) } } }View/MovieEditView.swift
// // MovieEditView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI enum Mode { case new case edit } enum Action { case delete case done case cancel } struct MovieEditView: View { @Environment(\.presentationMode) private var presentationMode @State var presentActionSheet = false @ObservedObject var viewModel = MovieViewModel() var mode: Mode = .new var completionHandler: ((Result<Action, Error>) -> Void)? var cancelButton: some View { Button(action: { self.handleCancelTapped() }) { Text("Cancel") } } var saveButton: some View { Button(action: { self.handleDoneTapped() }) { Text(mode == .new ? "Done" : "Save") } .disabled(!viewModel.modified) } var body: some View { NavigationView { Form { Section(header: Text("Movie")) { TextField("Title", text: $viewModel.movie.title) TextField("Year", text: $viewModel.movie.year) } Section(header: Text("Description")) { TextField("Description", text: $viewModel.movie.description) } if mode == .edit { Section { Button("Delete Movie") { self.presentActionSheet.toggle() } .foregroundColor(.red) } } } .navigationTitle(mode == .new ? "New Movie" : viewModel.movie.title) .navigationBarTitleDisplayMode(mode == .new ? .inline : .large) .navigationBarItems( leading: cancelButton, trailing: saveButton ) .actionSheet(isPresented: $presentActionSheet) { ActionSheet(title: Text("Are you sure?"), buttons: [ .destructive(Text("Delete Movie"), action: { self.handleDeleteTapped() }), .cancel() ]) } } } // Action Handlers func handleCancelTapped() { self.dismiss() } func handleDoneTapped() { self.viewModel.handleDoneTapped() self.dismiss() } func handleDeleteTapped() { viewModel.handleDeleteTapped() self.dismiss() self.completionHandler?(.success(.delete)) } func dismiss() { self.presentationMode.wrappedValue.dismiss() } } //struct MovieEditView_Previews: PreviewProvider { // static var previews: some View { // MovieEditView() // } //} struct MovieEditView_Previews: PreviewProvider { static var previews: some View { let movie = Movie(title: "Sample title", description: "Sample Description", year: "2020") let movieViewModel = MovieViewModel(movie: movie) return MovieEditView(viewModel: movieViewModel, mode: .edit) } }
SwiftUI Firebase Fetch data and display in a List
SwiftUI Firebase Fetch data and display in a List
In this tutorial we will learn how to display firebase data in List
ContentView.swift// // ContentView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI struct ContentView: View { @ObservedObject private var viewModel = userViewModel() var body: some View { NavigationView { List(viewModel.users) { user in VStack(alignment: .leading) { Text(user.name).font(.title) Text(user.surname).font(.subheadline) } }.navigationBarTitle("Users") .onAppear() { self.viewModel.fetchData() } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }User.swift
// // User.swift // DevSwiftUI // // Created by Cairocoders // import Foundation struct User: Identifiable { var id: String = UUID().uuidString var name: String var surname: String }UserViewModel.swift
// // UserViewModel.swift // DevSwiftUI // // Created by Cairocoders // import Foundation import FirebaseFirestore class userViewModel: ObservableObject { @Published var users = [User]() private var db = Firestore.firestore() func fetchData() { db.collection("users").addSnapshotListener { (querySnapshot, error) in guard let documents = querySnapshot?.documents else { print("No documents") return } self.users = documents.map { (queryDocumentSnapshot) -> User in let data = queryDocumentSnapshot.data() let name = data["name"] as? String ?? "" let surname = data["surname"] as? String ?? "" return User(name: name, surname: surname) } } } }DevSwiftUIApp.swift
// // DevSwiftUIApp.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI import Firebase @main struct DevSwiftUIApp: App { init() { FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView() } } }
Saturday, May 29, 2021
Jquery Ajax Live Editable Table using Python Flask PostgreSQL
Jquery Ajax Live Editable Table using Python Flask PostgreSQL
app.py
install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2
Create TABLE
CREATE TABLE users (
id serial PRIMARY KEY,
fullname VARCHAR ( 100 ) NOT NULL,
username VARCHAR ( 50 ) NOT NULL,
password VARCHAR ( 255 ) NOT NULL,
email VARCHAR ( 50 ) NOT NULL
);
#app.py from flask import Flask, request, render_template, jsonify import psycopg2 #pip install psycopg2 import psycopg2.extras app = Flask(__name__) app.secret_key = "cairocoders-ednalan" DB_HOST = "localhost" DB_NAME = "sampledb" DB_USER = "postgres" DB_PASS = "admin" conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST) @app.route('/') def home(): try: cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) cursor.execute("SELECT * from users order by id") userslist = cursor.fetchall() return render_template('index.html',userslist=userslist) except Exception as e: print(e) finally: cursor.close() @app.route("/update",methods=["POST","GET"]) def update(): try: cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) if request.method == 'POST': field = request.form['field'] value = request.form['value'] editid = request.form['id'] if field == 'username': sql = "UPDATE users SET username=%s WHERE id=%s" if field == 'name': sql = "UPDATE users SET fullname=%s WHERE id=%s" data = (value, editid) cursor.execute(sql, data) conn.commit() success = 1 return jsonify(success) except Exception as e: print(e) finally: cursor.close() if __name__ == "__main__": app.run()templates/index.html
//templates/index.html <!doctype html> <html> <head> <title>Jquery Ajax Live Editable Table using Python Flask PostgreSQL</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script type='text/javascript'> $(document).ready(function(){ // Show Input element $('.edit').click(function(){ $('.txtedit').hide(); $(this).next('.txtedit').show().focus(); $(this).hide(); }); // Save data $(".txtedit").focusout(function(){ // Get edit id, field name and value var id = this.id; var split_id = id.split("_"); var field_name = split_id[0]; var edit_id = split_id[1]; var value = $(this).val(); // Hide Input element $(this).hide(); // Hide and Change Text of the container with input elmeent $(this).prev('.edit').show(); $(this).prev('.edit').text(value); $.ajax({ url: '/update', type: 'post', data: { field:field_name, value:value, id:edit_id }, success:function(response){ if(response == 1){ console.log('Save successfully'); }else{ console.log("Not saved."); } } }); }); }); </script> </head> <body > <div class="container" > <div class="row" style="padding:50px;"> <p><h1>Jquery Ajax Live Editable Table using Python Flask PostgreSQL</h1></p> <table width='100%' border='0'> <tr> <th width='10%'>ID</th> <th width='40%'>Username</th> <th width='40%'>Name</th> </tr> {% for row in userslist %} <tr> <td>{{row.id}}</td> <td> <div class='edit' > {{row.username}}</div> <input type='text' class='txtedit' value='{{row.username}}' id='username_{{row.id}}' > </td> <td> <div class='edit' >{{row.fullname}} </div> <input type='text' class='txtedit' value='{{row.fullname}}' id='name_{{row.id}}' > </td> </tr> {% endfor %} </table> </div> </div> <style> .edit{ width: 100%; height: 25px; } .editMode{ border: 1px solid black; } table { border:3px solid lavender; border-radius:3px; } table tr:nth-child(1){ background-color:#4285f4; } table tr:nth-child(1) th{ color:white; padding:10px 0px; letter-spacing: 1px; } table td{ padding:10px; } table tr:nth-child(even){ background-color:lavender; color:black; } .txtedit{ display: none; width: 99%; height: 30px; } </style> </body> </html>
DataTable AJAX using Python Flask PostgreSQL
DataTable AJAX using Python Flask PostgreSQL
app.py
Download Datatables from here. https://datatables.net/download/
install psycopg2 https://pypi.org/project/psycopg2/
Psycopg is the most popular PostgreSQL database adapter for the Python programming language.
(venv) PS C:\flaskmyproject> pip install psycopg2
CREATE TABLE employee (
id serial PRIMARY KEY,
name VARCHAR ( 100 ) NOT NULL,
position VARCHAR ( 100 ) NOT NULL,
office VARCHAR ( 100 ) NOT NULL,
age INT NOT NULL,
salary INT NOT NULL,
photo VARCHAR ( 150 ) NOT NULL,
);
INSERT INTO
employee(name, position, office, age, salary, photo)
VALUES
('Tiger Wood', 'Accountant', 'Tokyo', 36, 5689, '01.jpg'),
('Mark Oto Ednalan', 'Chief Executive Officer (CEO)', 'London', 56, 5648, '02.jpg'),
('Jacob thompson', 'Junior Technical Author', 'San Francisco', 23, 5689, '03.jpg'),
('cylde Ednalan', 'Software Engineer', 'Olongapo', 23, 54654, '04.jpg'),
('Rhona Davidson', 'Software Engineer', 'San Francisco', 26, 5465, '05.jpg'),
('Quinn Flynn', 'Integration Specialist', 'New York', 53, 56465, '06.jpg'),
('Tiger Nixon', 'Software Engineer', 'London', 45, 456, '07.jpg'),
('Airi Satou', 'Pre-Sales Support', 'New York', 25, 4568, '08.jpg'),
('Angelica Ramos', 'Sales Assistant', 'New York', 45, 456, '09.jpg'),
('Ashton updated', 'Senior Javascript Developer', 'Olongapo', 45, 54565, '01.jpg'),
('Bradley Greer', 'Regional Director', 'San Francisco', 27, 5485, '02.jpg'),
('Brenden Wagner', 'Javascript Developer', 'San Francisco', 38, 65468, '03.jpg'),
('Brielle Williamson', 'Personnel Lead', 'Olongapo', 56, 354685, '04.jpg'),
('Bruno Nash', 'Customer Support', 'New York', 36, 65465, '05.jpg'),
('cairocoders', 'Sales Assistant', 'Sydney', 45, 56465, '06.jpg'),
('Zorita Serrano', 'Support Engineer', 'San Francisco', 38, 6548, '07.jpg'),
('Zenaida Frank', 'Chief Operating Officer (COO)', 'San Francisco', 39, 545, '08.jpg'),
('Sakura Yamamoto', 'Support Engineer', 'Tokyo', 48, 5468, '05.jpg'),
('Serge Baldwin', 'Data Coordinator', 'Singapore', 85, 5646, '05.jpg'),
('Shad Decker', 'Regional Director', 'Tokyo', 45, 4545, '05.jpg');
#app.py from flask import Flask, request, render_template, jsonify, json import psycopg2 #pip install psycopg2 import psycopg2.extras app = Flask(__name__) app.secret_key = "cairocoders-ednalan" DB_HOST = "localhost" DB_NAME = "sampledb" DB_USER = "postgres" DB_PASS = "admin" conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST) @app.route('/') def home(): return render_template('index.html') @app.route("/ajaxfile",methods=["POST","GET"]) def ajaxfile(): try: cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) if request.method == 'POST': draw = request.form['draw'] row = int(request.form['start']) rowperpage = int(request.form['length']) searchValue = request.form["search[value]"] #print(draw) print(row) print(rowperpage) #print(searchValue) ## Total number of records without filtering cursor.execute("select count(*) as allcount from employee") rsallcount = cursor.fetchone() totalRecords = rsallcount['allcount'] print(totalRecords) ## Total number of records with filtering #likeString = "%" + searchValue + "%" likeString = "{}%".format(searchValue) print(likeString) cursor.execute("SELECT count(*) as allcount from employee WHERE name LIKE %s", (likeString,)) rsallcount = cursor.fetchone() totalRecordwithFilter = rsallcount['allcount'] print(totalRecordwithFilter) ## Fetch records if searchValue=='': cursor.execute('SELECT * FROM employee LIMIT {limit} OFFSET {offset}'.format(limit=rowperpage, offset=row)) employeelist = cursor.fetchall() else: cursor.execute("SELECT * FROM employee WHERE name LIKE %s LIMIT %s OFFSET %s;", (likeString, rowperpage, row,)) employeelist = cursor.fetchall() data = [] for row in employeelist: data.append({ 'name': row['name'], 'position': row['position'], 'age': row['age'], 'salary': row['salary'], 'office': row['office'], }) response = { 'draw': draw, 'iTotalRecords': totalRecords, 'iTotalDisplayRecords': totalRecordwithFilter, 'aaData': data, } return jsonify(response) except Exception as e: print(e) finally: cursor.close() if __name__ == "__main__": app.run()templates/index.html
//templates/index.html <!doctype html> <html> <head> <title>DataTable AJAX using Python Flask PostgreSQL</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <link href='https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'> <script src="https://code.jquery.com/jquery-3.5.1.js"></script> <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script> </head> <body > <div class="container" > <div class="row" style="padding:50px;"> <p><h1>DataTable AJAX using Python Flask PostgreSQL</h1></p> <div > <table id='empTable' class='display dataTable' width='100%'> <thead> <tr> <th>Employee Name</th> <th>Position</th> <th>Age</th> <th>Salary</th> <th>Office</th> </tr> </thead> </table> </div> </div> </div> <script> $(document).ready(function() { var empDataTable = $('#empTable').DataTable({ 'processing': true, 'serverSide': true, 'serverMethod': 'post', 'ajax': { 'url':'/ajaxfile' }, 'lengthMenu': [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]], searching: true, sort: false, "serverSide": true, 'columns': [ { data: 'name' }, { data: 'position' }, { data: 'age' }, { data: 'salary' }, { data: 'office' }, ] }); }); </script> </body> </html>
SwiftUI Onboarding View using PageTabViewStyle
SwiftUI Onboarding View using PageTabViewStyle
ContentView.swift
// // ContentView.swift // Devapp // // Created by Cairocoders // import SwiftUI // struct ContentView: View { @State private var isOnboardinDone: Bool = false var body: some View { if isOnboardinDone { HomeView() } else if !isOnboardinDone { SplashView(done: $isOnboardinDone) } else { HomeView() } } } struct details_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct HomeView: View { @State private var showpopover = false var body: some View { Button("Show menu") { showpopover = true } .popover(isPresented: $showpopover) { VStack(alignment: .leading,spacing: 7.0){ HStack(spacing: 15){ Button(action: {}, label: { HStack { Image(systemName: "paperplane.circle") .font(.largeTitle) Text("Submit") .fontWeight(.heavy) .foregroundColor(.white) .padding(.vertical) .frame(maxWidth: .infinity) } .background(Color.blue) .foregroundColor(.white) .cornerRadius(15) }) Button(action: { withAnimation{ } }, label: { HStack { Image(systemName: "arrowshape.turn.up.forward.circle") .font(.largeTitle) Text("Next") .fontWeight(.heavy) .foregroundColor(.white) .padding(.vertical) .frame(maxWidth: .infinity) } .background(Color.green) .foregroundColor(.white) .cornerRadius(15) }) } //End HStack .padding(.bottom) }//End VStack .padding() } } } struct SplashView: View { @Binding var done: Bool @State private var currentTab = 0 var body: some View { TabView(selection: $currentTab, content: { ForEach(OnboardingData.list) { viewData in OnboardingView(data: viewData, done: $done) .tag(viewData.id) } }) .tabViewStyle(PageTabViewStyle()) .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always)) .background( LinearGradient(gradient: Gradient(colors: [.blue, .white, .yellow]), startPoint: .topLeading, endPoint: .bottomTrailing) ) } }OnboardingData.swift
// // OnboardingData.swift // Devapp // // Created by Cairocoders // import Foundation struct OnboardingData: Hashable, Identifiable { let id: Int let backgroundImage: String let primaryText: String let secondaryText: String static let list: [OnboardingData] = [ OnboardingData(id: 0, backgroundImage: "pic1", primaryText: "Online Course", secondaryText: "Online Course any place anytime"), OnboardingData(id: 1, backgroundImage: "pic2", primaryText: "Kick start your learning", secondaryText: "Kick start your learning Development"), OnboardingData(id: 2, backgroundImage: "pic3", primaryText: "Learn SwiftUI", secondaryText: "Learn SwiftUI beginners to advance") ] }OnboardingView.swift
// // OnboardingView.swift // Devapp // // Created by Cairocoders // import SwiftUI struct OnboardingView: View { var data: OnboardingData @Binding var done: Bool @State private var isAnimating: Bool = false var body: some View { VStack(spacing: 20) { ZStack { Image(data.backgroundImage) .resizable() .scaledToFit() } Spacer() Spacer() Text(data.primaryText) .font(.title2) .bold() .foregroundColor(Color.black) Text(data.secondaryText) .font(.headline) .multilineTextAlignment(.center) .frame(maxWidth: 250) .foregroundColor(Color.black) Spacer() Button(action: { done.toggle() }, label: { Text("Get Started") .font(.headline) .foregroundColor(.white) .padding(.horizontal, 50) .padding(.vertical, 16) .background(Color.green) .foregroundColor(.white) .cornerRadius(15) }) .shadow(radius: 10) Spacer() } .onAppear(perform: { isAnimating = false withAnimation(.easeOut(duration: 0.5)) { self.isAnimating = true } }) } }
Wednesday, May 26, 2021
SwiftUI Splash Screen tap start button goto HomepageView
SwiftUI Splash Screen tap start button goto HomepageView
// // ContentView.swift // Devapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { @State private var isOnboardinDone: Bool = false var body: some View { if isOnboardinDone { Homepage() } else if !isOnboardinDone { OnboardingView(done: $isOnboardinDone) } else { Homepage() } } } struct details_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct Homepage: View { var body: some View { NavigationView { List { Text("Episode IV – A New Hope") Text("Episode V – The Empire Strikes Back") Text("Episode VI – Return of the Jedi") } .navigationTitle("Home") } } } struct OnboardingView: View { @Binding var done: Bool var body: some View { ScrollView { VStack(alignment: .center) { Spacer() TitleView() InformationContainerView() Spacer(minLength: 30) Button(action: { done.toggle() }, label: { Text("Start") .customButton() }) .padding(.horizontal) } } } } struct InformationDetailView: View { var title: String = "title" var subTitle: String = "subTitle" var imageName: String = "" var body: some View { HStack(alignment: .center) { Image(systemName: imageName) .font(.largeTitle) .foregroundColor(.mainColor) .padding() .accessibility(hidden: true) VStack(alignment: .leading) { Text(title) .font(.headline) .foregroundColor(.primary) .accessibility(addTraits: .isHeader) Text(subTitle) .font(.body) .foregroundColor(.secondary) .fixedSize(horizontal: false, vertical: true) } } .padding(.top) } } struct InformationContainerView: View { var body: some View { VStack(alignment: .leading) { InformationDetailView(title: "Splash Screen", subTitle: "Onboarding screen is shown (OnboardingView)", imageName: "desktopcomputer") InformationDetailView(title: "Start Button", subTitle: "By tapping Start Button Go to home page (HomeView)", imageName: "forward.frame.fill") InformationDetailView(title: "Start App", subTitle: "Splash Screen Start the application", imageName: "iphone") } .padding(.horizontal) } } struct TitleView: View { var body: some View { VStack { Image("pic1") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 180, alignment: .center) .accessibility(hidden: true) Text("Welcome") .customTitleText() Text("Take Some time out") .customTitleText() .foregroundColor(.mainColor) } } } struct ButtonModifier: ViewModifier { func body(content: Content) -> some View { content .foregroundColor(.white) .font(.headline) .padding() .frame(minWidth: 0, maxWidth: .infinity, alignment: .center) .background(RoundedRectangle(cornerRadius: 15, style: .continuous) .fill(Color.mainColor)) .padding(.bottom) } } extension View { func customButton() -> ModifiedContent<Self, ButtonModifier> { return modifier(ButtonModifier()) } } extension Text { func customTitleText() -> Text { self .fontWeight(.black) .font(.system(size: 36)) } } extension Color { static var mainColor = Color(UIColor.systemGreen) }
SwiftUI Carousel Slider Welcome Page
SwiftUI Carousel Slider Welcome Page
// // ContentView.swift // Devapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { var body: some View { Home() } } struct details_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct Home: View { @State var CurrentIndex : Int = 1 var body: some View { VStack { //Carousel Slider TabView(selection: $CurrentIndex) { ForEach(1...3,id: \.self) {index in //Custom Scroll Effect GeometryReader{proxy -> AnyView in let minX = proxy.frame(in: .global).minX let width = UIScreen.main.bounds.width let progress = -minX / (width * 2) var scale = progress > 0 ? 1 - progress : 1 + progress scale = scale < 0.7 ? 0.7 : scale return AnyView( VStack{ Image("pic\(index)") .resizable() .aspectRatio(contentMode: .fit) .padding(.horizontal,10) Text("Loren ipsum dlipsum") .font(.largeTitle) .fontWeight(.heavy) .foregroundColor(.white) //.background(Color.green) .padding() Text("Loren ipsum, or dlipsum as is somtine know text usded in layoyt Loren ipsum, or dlipsum as is somtine know text usded in layoyt") .font(.system(size: 16, weight: .bold)) .foregroundColor(.white) .padding(.horizontal) } .frame(maxHeight: .infinity, alignment: .center) .scaleEffect(scale) ) } .tag(index) } } .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) //custom tab indicator CustomeTabIndicator(count: 3, current: $CurrentIndex) .padding(.vertical) .padding(.top) VStack(spacing:15) { Button(action: {}, label: { HStack{ Image(systemName: "arrow.right.square") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 25, height: 25) .foregroundColor(.white) Text("Start") .fontWeight(.bold) .foregroundColor(.white) .frame(maxWidth: .infinity, alignment: .center) } .padding(.vertical,13) .padding(.horizontal) .background( RoundedRectangle(cornerRadius: 10) .fill(Color.black) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(Color.white,lineWidth: 1) ) ) }) } .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.blue).ignoresSafeArea() } } struct CustomeTabIndicator: View { var count: Int @Binding var current: Int var body: some View { HStack { HStack { ForEach(0..<count,id: \.self) { index in ZStack { //image index start from 1.. if (current - 1) == index { Circle() .fill(Color.green) } else { Circle() .fill(Color.white) .overlay( Circle() .stroke(Color.green, lineWidth: 1.5) ) } } .frame(width: 10, height: 10) } } } } }
SwiftUI how to call a function when button pressed
SwiftUI how to call a function when button pressed
// // ContentView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { @State private var count = 0 var body: some View { VStack { Button(action: {stepCount() }, label: { Text("Increment Count") .fontWeight(.heavy) .foregroundColor(.white) .padding() .background(Color.blue) .cornerRadius(15) }) Text("The count is: \(self.count)") } } // End body func stepCount() { count += 1 } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
SwiftUI Grid Layout Using LazyVGrid
SwiftUI Grid Layout Using LazyVGrid
// // ContentView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI struct Photo: Identifiable { var id = UUID() var name: String } let listphotoloop = (1...11).map { Photo(name: "\($0)") } //1.jpg to 11.jpg Assets.xcassets struct ContentView: View { @State var gridLayout: [GridItem] = [GridItem(.flexible()), GridItem(.flexible())] var body: some View { NavigationView { ScrollView { LazyVGrid(columns: gridLayout, alignment: .center, spacing: 10) { ForEach(listphotoloop.indices) { index in Image(listphotoloop[index].name) .resizable() .scaledToFill() .frame(minWidth: 0, maxWidth: .infinity) .frame(height: 200) .cornerRadius(10) .shadow(color: Color.primary.opacity(0.3), radius: 1) } } // End ScrollView .padding(.all, 10) .animation(.interactiveSpring()) }// End ScrollView .navigationTitle("Grid Layout Using LazyVGrid") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button(action: { self.gridLayout = Array(repeating: .init(.flexible()), count: self.gridLayout.count % 4 + 1) }) { Image(systemName: "square.grid.2x2") .font(.title) .foregroundColor(.primary) } } } } // End Navigation } // End body } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Tuesday, May 25, 2021
SwiftUI how to add URL image
SwiftUI how to add URL image
// // ContentView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { let getURL = "https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" var body: some View { URLImage(url: getURL) .aspectRatio(contentMode: .fit) .frame(width: 200) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct URLImage: View { private enum LoadState { case loading, success, failure } private class Loader: ObservableObject { var data = Data() var state = LoadState.loading init(url: String) { guard let parsedURL = URL(string: url) else { fatalError("Invalid URL: \(url)") } URLSession.shared.dataTask(with: parsedURL) { data, response, error in if let data = data, data.count > 0 { self.data = data self.state = .success } else { self.state = .failure } DispatchQueue.main.async { self.objectWillChange.send() } }.resume() } } @StateObject private var loader: Loader var loading: Image var failure: Image var body: some View { selectImage() .resizable() } init(url: String, loading: Image = Image(systemName: "photo"), failure: Image = Image(systemName: "multiply.circle")) { _loader = StateObject(wrappedValue: Loader(url: url)) self.loading = loading self.failure = failure } private func selectImage() -> Image { switch loader.state { case .loading: return loading case .failure: return failure default: if let image = UIImage(data: loader.data) { return Image(uiImage: image) } else { return failure } } } }
SwiftUI how to add button to navigation bar
SwiftUI how to add button to navigation bar
Ho to add buttons and images to navigation bar in swiftUI NavigationView
// // ContentView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { @State var showAlert: Bool = false @State var msg: String = "" var body: some View { NavigationView { Text("Cairocoders - tutorial101.blogspot.com") .navigationBarTitle("Tutorials") .navigationBarItems(trailing: HStack { Button(action: { self.showAlert = true self.msg = "Reload button pressed..." }) { Text("Reload") } Button(action: { self.showAlert = true self.msg = "Edit button pressed..." }) { Image(systemName: "person.crop.circle").imageScale(.large) //SF Symbol } } ) } .alert(isPresented: $showAlert, content: { Alert(title: Text(self.msg)) }) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Monday, May 24, 2021
SwiftUI Horizontal scroll or horizontal list view
SwiftUI Horizontal scroll or horizontal list view
// // ContentView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { var body: some View { VStack { Divider() ScrollView(.horizontal) { HStack(spacing: 10) { ForEach(0..<21) { index in NumberView1to20(label: "\(index)") } }.padding() }.frame(height: 100) Divider() Spacer() } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct NumberView1to20: View { @State var label: String var body: some View { ZStack { Circle() .fill(Color.green) .frame(width: 70, height: 70) Text(label) .foregroundColor(.white) } } }
Local storage UserDefaults CRUD Create Read Update Delete
ContentView.swift
A simple app Swift UI that allow to create, read,upate and delete value in local storage using UserDefaults
// // ContentView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { @State var showAlert: Bool = false var body: some View { NavigationView { VStack { Text("Local storage UserDefaults CRUD Create Read Update Delete") .font(.largeTitle) .bold() .padding(.bottom, 50) HStack { NavigationLink (destination: AddView(), label: { Text("Add") .font(.headline) .foregroundColor(.white) .padding() .background(Color.green) }) NavigationLink (destination: DataView(), label: { Text("View") .font(.headline) .foregroundColor(.white) .padding() .background(Color.green) }) NavigationLink (destination: EditView(), label: { Text("Edit") .font(.headline) .foregroundColor(.white) .padding() .background(Color.green) }) Button(action: { LocalStorage.removeValue() //Delete a value from local storage self.showAlert = true }, label: { Text("Delete") .font(.headline) .foregroundColor(.white) .padding() .background(Color.green) }) } } .alert(isPresented: $showAlert, content: { Alert(title: Text("Data has been removed")) }) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }LocalStorage.swift
This file will handle the creating, fetching, updating and deleting the data from local storage.
// // LocalStorage.swift // Testapp // // Created by Cairocoders // import Foundation class LocalStorage { private static let myKey: String = "myKey" //static constant named public static var myValue: String { set { UserDefaults.standard.set(newValue, forKey: myKey) } get { return UserDefaults.standard.string(forKey: myKey) ?? "" } } public static func removeValue() { UserDefaults.standard.removeObject(forKey: myKey) //removeValue() remove that value from UserDefaults. } }AddView.swift
// // AddView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct AddView: View { @State var value: String = "" @State var showAlert: Bool = false var body: some View { VStack { TextField("Enter value", text: $value) .padding(10) .background(Color(.systemGray6)) .cornerRadius(5) .disableAutocorrection(true) Button(action: { LocalStorage.myValue = self.value //Add value to local storage self.showAlert = true }, label: { Text("Save") }) } .padding() .alert(isPresented: $showAlert, content: { Alert(title: Text("Data has been saved")) }) } } struct AddView_Previews: PreviewProvider { static var previews: some View { AddView() } }DataView..swift
// // DataView..swift // Testapp // // Created by Cairocoders // import SwiftUI struct DataView: View { var body: some View { Text(LocalStorage.myValue) //Get value from local storage } } struct DataView_Previews: PreviewProvider { static var previews: some View { DataView() } }EditView.swift
// // EditView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct EditView: View { @State var value: String = "" @State var showAlert: Bool = false var body: some View { VStack { TextField("Enter value", text: $value) .padding(10) .background(Color(.systemGray6)) .cornerRadius(5) .disableAutocorrection(true) Button(action: { LocalStorage.myValue = self.value self.showAlert = true }, label: { Text("Update") }) } .padding() .onAppear(perform: { self.value = LocalStorage.myValue //Edit value in local storage }) .alert(isPresented: $showAlert, content: { Alert(title: Text("Data has been updated")) }) } } struct EditView_Previews: PreviewProvider { static var previews: some View { EditView() } }
Thursday, May 20, 2021
Monday, May 17, 2021
SwiftUI Firebase Auth using firebase-ios-sdk
SwiftUI Firebase Auth using firebase-ios-sdk
https://console.firebase.google.com/
https://github.com/firebase/firebase-ios-sdk
// // Firebase_AuthApp.swift // Firebase Auth // // Created by Cairocoders // import SwiftUI import Firebase @main struct Firebase_AuthApp: App { init() { FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView() } } }
// // ContentView.swift // Firebase Auth // // Created by Cairocoders // import SwiftUI import Firebase struct ContentView: View { @State var email = "" @State var password = "" var body: some View { VStack { TextField("Email", text: $email) SecureField("Password", text: $password) Button(action: { login() }) { Text("Sign In") } } .padding() } func login(){ Auth.auth().signIn(withEmail: email, password: password) { result, error in if error != nil { print(error?.localizedDescription ?? "") }else { print("success") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
SwiftUI Popover
SwiftUI Popover
// // ContentView.swift // Testapp // // Created by Cairocoders // import SwiftUI struct ContentView: View { @State var isPopoverPresented = false var body: some View { Button(action: { self.isPopoverPresented = true }) { Text("Show Popover") } .popover(isPresented: $isPopoverPresented) { Text("Popover is Presented") .font(.largeTitle) .frame(width: 500, height: 500) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Subscribe to:
Posts (Atom)