ContentView.swift
//
// ContentView.swift
// swiftuidev
//
// Created by Cairocoders
//
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
MainView()
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}
AllPosts()
.tabItem {
Image(systemName: "list.dash")
Text("See all")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Creating the data model BlogPosts.swift
//
// BlogPosts.swift
// swiftuidev
//
// Created by Cairocoders
//
import Foundation
struct BlogPosts : Identifiable {
var id : Int
var name : String
var image : String
var details : String
}
var latestpost = [
BlogPosts(id: 0, name: "Bistek Tagalog", image: "0", details: "A dish made of strips of salted and peppered sirloin beef, usually flattened with a meat tenderizing tool, slowly cooked in soy sauce, calamansi juice, garlic and onions, a specialty of the Tagalog region"),
BlogPosts(id: 1, name: "Boogie flight", image: "1", details: "A boodle fight is a meal that dispenses with cutlery and dishes. Diners instead practice kamayan, Filipino for eating with the hands"),
BlogPosts(id: 2, name: "Sinigang Na Baboy", image: "2", details: "Sinigang na baboy with Gabi is a Filipino pork soup with taro cooked in a sour broth."),
BlogPosts(id: 3, name: "Ginisang Togue", image: "3", details: "Ginisang Togue is basically Sauteed Mung Bean Sprout with carrots, bell pepper, shrimp, and tofu."),
BlogPosts(id: 4, name: "Ginisang Munggo (Monggo)", image: "4", details: "Munggo or Mung bean (or even green bean to some) is a seed of Vigna radiata, a plant native to India and Pakistan. Since the plant originated in Asia, it was easy to spread along the nearby countries. This seed became a hit when it reached the Philippines."),
BlogPosts(id: 5, name: "Pork Estofado (Sweet Pork Stew)", image: "5", details: "Pork Estofado with saba bananas, carrots, Chinese sausage, and a sweet and savory sauce. Perfect with steamed rice!"),
BlogPosts(id: 6, name: "Pata Tim", image: "6", details: "Brimming in a pork stew infused with aromatic peppercorn, sesame oil and soy sauce, Pata Tim is a classic Filipino dish with traces in Chinese cuisine"),
BlogPosts(id: 7, name: "Pancit Palabok", image: "7", details: "Pancit Palabok is a noodle dish with shrimp sauce and topped with several ingredients such as cooked shrimp, boiled pork, crushed chicharon, tinapa flakes, fried tofu, scallions, and fried garlic. "),
]
var featuredpost = [
BlogPosts(id: 0, name: "Adobong Manok", image: "0", details: "A dish made of strips of salted and peppered sirloin beef, usually flattened with a meat tenderizing tool, slowly cooked in soy sauce, calamansi juice, garlic and onions, a specialty of the Tagalog region"),
BlogPosts(id: 1, name: "Boogie flight", image: "1", details: "A boodle fight is a meal that dispenses with cutlery and dishes. Diners instead practice kamayan, Filipino for eating with the hands"),
]
MainView.swift
//
// MainView.swift
// swiftuidev
//
// Created by Cairocoders
//
import SwiftUI
struct MainView: View {
var body: some View {
NavigationView {
ScrollView {
// featured article
VStack {
HStack {
Text("Featured posts")
.font(.title.bold())
Spacer()
}
LazyVStack {
ForEach(featuredpost){post in
//Text(store.name)
NavigationLink(destination: BlogPostView(blogPost: post)) {
BlogPostCardMain(blogPost: post)
}
}
}
}
.padding(.horizontal, 15)
.padding(.vertical, 30)
// latest articles
VStack {
HStack {
Text("Latest posts")
.font(.title.bold())
Spacer()
}
.padding(.horizontal, 15)
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 15) {
if latestpost.count >= 3 {
ForEach(latestpost[0...2]) { post in
NavigationLink(destination: BlogPostView(blogPost: post)) {
BlogPostCardMain(blogPost: post)
}
}
}else {
ForEach(latestpost[0..<latestpost.count]) { post in
NavigationLink(destination: BlogPostView(blogPost: post)) {
BlogPostCardMain(blogPost: post)
}
}
}
}
.padding(.leading, 15)
.padding(.trailing, 30)
}
.frame(height: 420)
Spacer()
}
.padding(.bottom, 40)
}
.navigationBarTitle("Home")
.navigationBarItems(
trailing: Button(action: {}) { Image(systemName: "arrow.clockwise.circle.fill")
.resizable()
.frame(width: 30, height: 30)
})
}
}
}
BlogPostCardMain.swift
//
// BlogPostCardMain.swift
// swiftuidev
//
// Created by Cairocoders
//
import SwiftUI
struct BlogPostCardMain: View {
@Environment(\.colorScheme) var colorScheme
var blogPost: BlogPosts
var body: some View {
VStack(alignment: .leading) {
Image(blogPost.image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 220)
.frame(maxWidth: UIScreen.main.bounds.width - 80)
.clipped()
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
VStack(spacing: 6) {
HStack {
Text(blogPost.name)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.lineLimit(3)
.font(Font.title2.bold())
.foregroundColor(.primary)
Spacer()
}
HStack {
Text(blogPost.details)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.lineLimit(3)
.font(.subheadline)
.foregroundColor(.secondary)
Spacer()
}
}
.frame(height: 110)
}
.padding(15)
.background(colorScheme == .dark ? Color(hex: "#121212") : Color.white)
.frame(maxWidth: UIScreen.main.bounds.width - 50, alignment: .leading)
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
.shadow(color: colorScheme == .dark ? .white.opacity(0.01) : .black.opacity(0.1), radius: 15, x: 0, y: 5)
}
}
struct BlogPostCardMain_Previews: PreviewProvider {
static var previews: some View {
BlogPostCardMain(blogPost: BlogPosts(id: 1, name: "Adobo", image: "1", details: "sample"))
}
}
AllPosts.swift
//
// AllPosts.swift
// swiftuidev
//
// Created by Cairocoders
//
import SwiftUI
struct AllPosts: View {
var body: some View {
NavigationView {
List {
ForEach(latestpost) {post in
NavigationLink(destination: BlogPostView(blogPost: post)) {
BlogPostCardList(blogPost: post)
}
}
}
.navigationTitle("All blog posts")
.listStyle(InsetListStyle())
}
}
}
struct AllPosts_Previews: PreviewProvider {
static var previews: some View {
AllPosts()
}
}
BlogPostCardList.swift
//
// BlogPostCardList.swift
// swiftuidev
//
// Created by Cairocoders
//
import SwiftUI
struct BlogPostCardList: View {
var blogPost: BlogPosts
var body: some View {
VStack(alignment: .leading) {
Image(blogPost.image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(maxWidth: .infinity)
.frame(height: 180)
.frame(maxWidth: UIScreen.main.bounds.width - 60)
.clipped()
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
VStack(spacing: 6) {
HStack {
Text(blogPost.name)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.lineLimit(3)
.font(Font.title2.bold())
.foregroundColor(.primary)
Spacer()
}
HStack {
Text(blogPost.details)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.lineLimit(3)
.font(.subheadline)
.foregroundColor(.secondary)
Spacer()
}
}
}
.frame(maxWidth: UIScreen.main.bounds.width - 60, alignment: .leading)
.padding()
}
}
struct BlogPostCardList_Previews: PreviewProvider {
static var previews: some View {
BlogPostCardList(blogPost: BlogPosts(id: 1, name: "Adobo", image: "1", details: "Sample Details"))
}
}
BlogPostView.swift
//
// BlogPostView.swift
// swiftuidev
//
// Created by Cairocoders
//
import SwiftUI
struct BlogPostView: View {
var blogPost: BlogPosts
var body: some View {
ZStack {
ScrollView {
VStack {
Image(blogPost.image)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 310)
.frame(maxWidth: UIScreen.main.bounds.width)
.clipped()
VStack {
HStack {
Text(blogPost.name)
.font(.title3)
.fontWeight(.heavy)
.foregroundColor(.primary)
.lineLimit(3)
.padding(.vertical, 15)
Spacer()
}
.frame(maxWidth: .infinity)
Text(blogPost.details)
.multilineTextAlignment(.leading)
.font(.body)
.foregroundColor(Color.primary.opacity(0.9))
.padding(.bottom, 25)
.frame(maxWidth: .infinity)
}
.padding(.horizontal, 20)
Spacer()
}
.frame(maxWidth: .infinity)
}
.navigationBarTitleDisplayMode(.inline)
}
}
}
struct BlogPostView_Previews: PreviewProvider {
static var previews: some View {
BlogPostView(blogPost: BlogPosts(id: 1, name: "Adobo", image: "1", details: "Sample Details"))
}
}
HexColorExtension.swift
//
// HexColorExtension.swift
// swiftuidev
//
// Created by Cairocoders
//
import Foundation
import SwiftUI
extension Color {
init(hex: String) {
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int: UInt64 = 0
Scanner(string: hex).scanHexInt64(&int)
let a, r, g, b: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(a, r, g, b) = (1, 1, 1, 0)
}
self.init(
.sRGB,
red: Double(r) / 255,
green: Double(g) / 255,
blue: Double(b) / 255,
opacity: Double(a) / 255
)
}
}
