Skip to content

Commit

Permalink
Modularized root view in iOS application.
Browse files Browse the repository at this point in the history
  • Loading branch information
elsong86 committed Jan 18, 2025
1 parent a7318a7 commit 6734318
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 150 deletions.
52 changes: 52 additions & 0 deletions ios/taco-about-it-ios/View/ActionButtonsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import SwiftUI

struct ActionButtonsView: View {
@ObservedObject var viewModel: ContentViewModel
@Binding var searchText: String
@Binding var destination: ContentView.Destination?

var body: some View {
VStack {
// Share Location Button
Button(action: {
viewModel.requestLocation()
print("Requesting location...")
}) {
Label("Share Location", systemImage: "location.fill")
.frame(maxWidth: .infinity)
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(color: .black.opacity(0.5), radius: 5, x: 2, y: 2)

Text("OR")
.foregroundColor(.black)
.padding(.vertical, 8)

// Search Bar
SearchBarView(
searchText: $searchText,
onSearch: { text in
print("Setting navigationTarget to .search with \(searchText)")
destination = .search(text)
}
)
.frame(maxWidth: .infinity) // Make search bar fill available width
.padding(.horizontal, 16)
.padding(.vertical, 8)
.background(Color.white)
.cornerRadius(8)
.shadow(color: .gray.opacity(0.5), radius: 5, x: 2, y: 2)
}
}
}

#Preview {
ActionButtonsView(
viewModel: ContentViewModel(),
searchText: .constant(""),
destination: .constant(nil)
)
}
169 changes: 51 additions & 118 deletions ios/taco-about-it-ios/View/ContentView.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import SwiftUI

struct ContentView: View {
@State private var searchText: String = "" // State for search bar input
@State private var readyToNavigateWithSearch: Bool = false // State to trigger navigation for search bar
@State private var selectedSearchString: String? // Holds the search string for navigation

@StateObject private var viewModel = ContentViewModel() // ViewModel for location handling
@State private var selectedLocation: GeoLocation?
@State private var readyToNavigateWithLocation: Bool = false // State to trigger navigation for location
@State private var searchText: String = ""
@StateObject private var viewModel = ContentViewModel()
@State private var destination: Destination?

enum Destination: Hashable {
case location(GeoLocation)
case search(String)
}

let tacoSpotCharacters: [(character: String, color: Color)] = [
("T", Color(hex: "#9F1239")), // Rose 800
("A", Color(hex: "#065F46")), // Emerald 800
("C", Color(hex: "#D97706")), // Yellow 600
("O", Color(hex: "#C2410C")), // Orange 700
(" ", .clear), // Space between words
("S", Color(hex: "#9F1239")), // Rose 800
("P", Color(hex: "#065F46")), // Emerald 800
("O", Color(hex: "#D97706")), // Yellow 600
Expand All @@ -23,128 +23,61 @@ struct ContentView: View {

var body: some View {
NavigationStack {
ZStack(alignment: .top) {
// Background Image
Image("hero")
.resizable()
.scaledToFill()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
.clipped()

LinearGradient(
gradient: Gradient(colors: [
Color.white.opacity(0.75),
Color.clear
]),
startPoint: .leading,
endPoint: .trailing
)
.edgesIgnoringSafeArea(.all)

Rectangle()
.fill(Color.white.opacity(0.65))
.edgesIgnoringSafeArea(.all)

VStack(spacing: 0) {
// Header
Header()
.frame(maxWidth: .infinity)
.background(Color.white.opacity(0.9))
.shadow(color: .gray.opacity(0.5), radius: 5, x: 0, y: 2)
.edgesIgnoringSafeArea(.top)
}

VStack(spacing: 16) {
Spacer()
.frame(height: 80)

Text("Anywhere, Anytime")
.font(Font.custom("ThirstyRoughReg", size: 20))
.foregroundColor(.black)

Text("Find Your New")
.font(Font.custom("BrothersRegular", size: 30))
.foregroundColor(.black)

Text("Favorite")
.font(Font.custom("BrothersRegular", size: 30))
.foregroundColor(.black)

HStack(spacing: 0) {
ForEach(tacoSpotCharacters, id: \.character) { item in
Text(item.character)
.foregroundColor(item.color)
.font(Font.custom("BrothersRegular", size: 50))
}
}

Text("Share or enter your location to get started")
.foregroundColor(.black)

Divider()

// Share Location Button
Button(action: {
viewModel.requestLocation()
print("Requesting location...")
}) {
Label("Share Location", systemImage: "location.fill")
VStack(spacing: 0) {
// Header
Header()
.padding(.bottom, 16) // Spacing below the header

// Main Content
ScrollView {
VStack(spacing: 16) {
Spacer()
.frame(height: 40) // Reduced height from 80 to 40

// Title Section
TitleSectionView(tacoSpotCharacters: tacoSpotCharacters)

// Instruction Text
Text("Share or enter your location to get started")
.foregroundColor(.black)
.multilineTextAlignment(.center)
.padding(.horizontal, 16)

Divider()

// Action Buttons
ActionButtonsView(
viewModel: viewModel,
searchText: $searchText,
destination: $destination
)
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(color: .black.opacity(0.5), radius: 5, x: 2, y: 2)

Text("OR")
.foregroundColor(.black)

// Search Bar
SearchBarView(
searchText: $searchText,
onSearch: {_ in
selectedSearchString = searchText // Set the search string
readyToNavigateWithSearch = true // Trigger navigation
}
)
.frame(maxWidth: UIScreen.main.bounds.width)
.padding(.horizontal, 16)
.padding(.vertical, 8)
.cornerRadius(8)
.shadow(color: .gray.opacity(0.5), radius: 5, x: 2, y: 2)
}
.padding()
}
// Navigation for Share Location
.onChange(of: viewModel.location) { oldValue, newValue in
.background(Color.white) // Optional: Set a background color if desired
.onChange(of: viewModel.location) { _, newValue in
if let location = newValue {
selectedLocation = location
readyToNavigateWithLocation = true
destination = .location(location)
}
}
.navigationDestination(isPresented: $readyToNavigateWithLocation) {
if let location = selectedLocation {
PlaceholderView(location: location)
.onDisappear {
readyToNavigateWithLocation = false
selectedLocation = nil
}
}
}
// Navigation for Search Bar
.navigationDestination(isPresented: $readyToNavigateWithSearch) {
if let searchString = selectedSearchString {
PlaceholderView(searchString: searchString)
.onDisappear {
readyToNavigateWithSearch = false
selectedSearchString = nil
}
.navigationDestination(item: $destination) { destination in
switch destination {
case .location(let loc):
PlaceholderView(location: loc, searchString: nil, onDisappear: {
viewModel.resetLocation()
})
case .search(let query):
PlaceholderView(location: nil, searchString: query, onDisappear: {
// If you have a separate state for search, reset it here
// For example: viewModel.resetSearch()
})
}
}
}
}
}

// MARK: - PreviewProvider
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Expand Down
45 changes: 24 additions & 21 deletions ios/taco-about-it-ios/View/Header.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,35 @@ struct Header: View {
]

var body: some View {
VStack { // Wrap the HStack in a VStack to add padding above
Spacer()
.frame(height: 20) // Add space above the content (adjust as needed)

HStack {
// Logo
Image("logo")
HStack {
// Logo
Image("logo")
.resizable()
.scaledToFit()
.frame(height: 40) // Adjust size as needed

// Title
HStack(spacing: 0) {
ForEach(title, id: \.character) { item in
Text(item.character)
.foregroundColor(item.color)
.font(Font.custom("HustlersRoughDemo", size: 30))
}
// Title
HStack(spacing: 0) {
ForEach(title, id: \.character) { item in
Text(item.character)
.foregroundColor(item.color)
.font(Font.custom("HustlersRoughDemo", size: 30))
}
}

Spacer() // Push the menu icon to the far right
Spacer() // Push the menu icon to the far right

// Menu Icon
Image(systemName: "line.3.horizontal")
}
.frame(maxWidth: UIScreen.main.bounds.width * 0.9) // Constrain to screen width
// Menu Icon
Image(systemName: "line.3.horizontal")
.resizable()
.scaledToFit()
.frame(width: 24, height: 24) // Adjust icon size
}
.frame(maxWidth: .infinity) // Ensure the header stretches to the full width
.padding(.top, 20) // Add padding at the top of the header (for additional space)
.padding(.horizontal)
.padding(.vertical, 8)
.background(Color.white.opacity(0.9)) // Apply background with opacity
.shadow(color: .gray.opacity(0.5), radius: 5, x: 0, y: 2) // Shadow
.frame(maxWidth: .infinity) // Stretch to the full width of the screen
}
}

Expand Down
25 changes: 18 additions & 7 deletions ios/taco-about-it-ios/View/PlaceholderView.swift
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import SwiftUI

struct PlaceholderView: View {
var location: GeoLocation? = nil
var searchString: String? = nil

var location: GeoLocation?
var searchString: String?
var onDisappear: () -> Void // Closure to reset location

var body: some View {
VStack {
if let location = location {
Text("Latitude: \(location.latitude)")
Text("Longitude: \(location.longitude)")
Text("Location: \(location.latitude), \(location.longitude)")
.font(.title)
.padding()
} else if let searchString = searchString {
Text("Search Query: \(searchString)")
.font(.title)
.padding()
} else {
Text("No data available.")
.font(.title)
.padding()
}
}
.padding()
.navigationTitle("Results")
.onDisappear {
onDisappear() // Call the closure when the view disappears
}
}
}

#Preview {
PlaceholderView(location: GeoLocation(latitude: 37.7749, longitude: -122.4194), searchString: nil, onDisappear: {})
}
Loading

0 comments on commit 6734318

Please sign in to comment.