import SwiftUI
import MapKit
struct SearchView: View {
#StateObject var locationManager: LocationManager = .init()
#State var navigationTag: String?
var body: some View {
VStack{
HStack(spacing: 15){
Button{
}label: {
Image(systemName: "chevron.left")
.font(.title3)
.foregroundColor(Color("New Pink"))
}
Text("Search your place")
.font(.title3)
.fontWeight(.semibold)
}
.frame(maxWidth: .infinity,alignment: .leading)
HStack(spacing: 10){
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
TextField("type your places",text: $locationManager.searchText)
}
.padding(.vertical, 12)
.padding(.horizontal)
.background{
RoundedRectangle(cornerRadius: 10, style: .continuous)
.strokeBorder(.gray)
}
.padding(.vertical,10)
if let places = locationManager.fetchedPlaces,!places.isEmpty{
List{
ForEach(places,id: \.self){place in
Button{
if let coordinate = locationManager.userLocation?.coordinate{
locationManager.pickedLocation = .init(latitude: coordinate.latitude, longitude: coordinate.longitude)
locationManager.mapView.region = .init(center: coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000)
locationManager.addDraggablePin(coordinate: coordinate)
locationManager.updatePlacemark(location: .init(latitude: coordinate.latitude, longitude: coordinate.longitude))
}
navigationTag = "MAPVIEW"
} label:{
HStack(spacing: 15){
Image(systemName: "mappin.circle.fill")
.font(.title2)
.foregroundColor(.gray)
VStack(alignment: .leading, spacing: 6){
Text(place.name ?? "")
.font(.title3.bold())
.foregroundColor(.primary)
Text(place.locality ?? "")
.font(.caption)
.foregroundColor(.gray)
}
}
}
}
}
.listStyle(.plain)
}else{
Button{
if let coordinate = locationManager.userLocation?.coordinate{
locationManager.mapView.region = .init(center: coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000)
locationManager.addDraggablePin(coordinate: coordinate)
locationManager.updatePlacemark(location: .init(latitude: coordinate.latitude, longitude: coordinate.longitude))
navigationTag = "MAPVIEW"
}
} label:{
Label{
Text("Use Current Location")
.font(.callout)
} icon: {
Image(systemName: "location.north.circle.fill")
}
.foregroundColor(.green)
}
.frame(maxWidth: .infinity,alignment: .leading)
}
}
.padding()
.frame(maxHeight: .infinity,alignment: .top)
.background{
NavigationLink(tag: "MAPVIEW", selection: $navigationTag){
MapViewSelection()
.environmentObject(locationManager)
.navigationBarHidden(true)
} label: {}
.labelsHidden()
}
}
}
struct SearchView_Previews: PreviewProvider {
static var previews: some View {
SearchView()
}
}
struct MapViewSelection: View{
#EnvironmentObject var locationManager: LocationManager
#Environment(\.dismiss) var dismiss
var body: some View{
ZStack{
MapViewHelper()
.environmentObject(locationManager)
.ignoresSafeArea()
Button {
dismiss()
} label: {
Image(systemName: "chevron.left")
.font(.title2.bold())
.foregroundColor(.primary)
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
if let place = locationManager.pickedPlaceMark{
VStack(spacing: 15){
Text("Confirm Location")
.font(.title2.bold())
HStack(spacing: 15){
Image(systemName: "mappin.circle.fill")
.font(.title2)
.foregroundColor(.gray)
VStack(alignment: .leading, spacing: 6){
Text(place.name ?? "")
.font(.title3.bold())
Text(place.locality ?? "")
.font(.caption)
.foregroundColor(.gray)
}
}
.frame(maxWidth: .infinity,alignment: .leading)
.padding(.vertical,10)
Button{
} label: {
Text("Confirm Location")
.fontWeight(.semibold)
.frame(maxWidth: .infinity)
.padding(.vertical,12)
.background{
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(.green)
}
.overlay(alignment: .trailing){
Image(systemName: "arrow.right")
.font(.title3.bold())
.padding(.trailing)
}.foregroundColor(.white)
}
}.padding()
.background{
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(.white)
.ignoresSafeArea()
}
.frame(maxHeight: .infinity, alignment: .bottom)
}
}.onDisappear{
locationManager.pickedLocation = nil
locationManager.pickedPlaceMark = nil
locationManager.mapView.removeAnnotations(locationManager.mapView.annotations)
}
}
}
struct MapViewHelper: UIViewRepresentable{
#EnvironmentObject var locationManager: LocationManager
func makeUIView(context: Context) -> MKMapView {
return locationManager.mapView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
I was trying to clone the swiftUI MapKit app
however there is an issue that In iOS 16.0 NavigationLink has been deprecated (SearchView - line 108ish) with a such warning as 'init(tag:selection:destination:label:)' was deprecated in iOS 16.0: use NavigationLink(value:label:) inside a List within a NavigationStack or NavigationSplitView
so how can i migrate the 'init(tag:selection:destination:label:)' to NavigationLink(value:label:) in this case
https://www.youtube.com/watch?v=fjZd1CwjlxQ&list=LL&index=3&t=1s check this video from 09:17 to 11:11
Related
when i pick an image using Image Picker from my Quick add View it kills all previous views and take me to the HomePage Tab which is Meal Planner View.Sometimes it works normal only on IOS device. It never works fine on simulator as i tried different simulators in Xcode. It also works fine in simulator and IOS device when i remove my TabBar and run directly from Meal Planner View.
kindly suggest something helpful.
import SwiftUI
struct QuickAddView: View {
#Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var viewName: String
#ObservedObject var vm = MealViewModel()
#State private var showPicker = false
#State private var selectedImage: UIImage?
#State var mealTitle: String = ""
#State var text: String = ""
// #State var descrption: String = ""
var body: some View {
VStack{
navBarView()
ScrollView(showsIndicators: false){
VStack {
VStack(alignment: .leading) {
Button {
self.showPicker.toggle()
} label: {
if selectedImage == nil {
ZStack {
Image("qorma")
.resizable()
.frame( height: 100)
HStack{
Text("+").font(.custom(Nunito.Bold.rawValue, size: 22))
.foregroundColor(.white)
Text("Attach a Photo").font(.custom(Nunito.Regular.rawValue, size: 20))
.foregroundColor(.white)
}
}
}
else {
ZStack {
Image(uiImage: selectedImage!)
.resizable()
.frame( height: 100)
HStack{
Text("+").font(.custom(Nunito.Bold.rawValue, size: 22))
.foregroundColor(.white)
Text("Attach a Photo").font(.custom(Nunito.Regular.rawValue, size: 20))
.foregroundColor(.white)
}
}
}
}
}
CustomTextField(text: $vm.title, placeHolder: "Name")
.background(.white)
.padding([.vertical],30)
fields()
TextEditor(text: $vm.description)
.textFieldStyle(.roundedBorder)
.colorMultiply(.white)
.frame( height: 199)
.border(.gray, width: 0.5)
.cornerRadius(10)
.shadow(radius: 1)
.foregroundColor(.gray)
.padding([.top],30)
addButton()
}
}
}.padding()
.sheet(isPresented: $showPicker) {
ImagePicker(image: $selectedImage)
}
}
}
extension QuickAddView {
func nutrientFields(nutrientTitle: String,amount: Binding<String>) -> some View {
VStack(alignment: .leading){
HStack(){
Text(nutrientTitle)
.font(.custom(Nunito.Semibold.rawValue, size: 24))
.foregroundColor(.gray)
Spacer()
HStack{
ZStack{
TextField("0", text: amount)
.font(Font.system(size: 30))
.background(Color.white)
.foregroundColor(Color(ColorName.appAqua.rawValue))
.frame(width: 70)
}
.background(
Rectangle()
.foregroundColor(Color.white)
.opacity(0.2)
)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color(ColorName.appAqua.rawValue), lineWidth: 2.5)
)
Text("(g)")
.font(.custom(Nunito.Semibold.rawValue, size: 30))
.foregroundColor(Color(ColorName.appAqua.rawValue))
}.padding([.horizontal])
// .font(.custom(Nunito.Semibold.rawValue, size: 20))
// .foregroundColor(Color(ColorName.appAqua.rawValue))
// .frame(width: 40, height: 30)
}
}
}
func calorieField (nutrientTitle: String,amount: Binding<String>) -> some View {
VStack(alignment: .leading){
HStack(){
Text(nutrientTitle)
.font(.custom(Nunito.Semibold.rawValue, size: 24))
.foregroundColor(.gray)
Spacer()
HStack{
ZStack{
TextField("0", text: amount)
.font(Font.system(size: 30))
.background(Color.white)
.foregroundColor(Color(ColorName.appAqua.rawValue))
.frame(width: 70)
}
.background(
Rectangle()
.foregroundColor(Color.white)
.opacity(0.2)
)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color(ColorName.appAqua.rawValue), lineWidth: 2.5)
)
}.padding([.horizontal],59)
}
}
}
func fields() -> some View {
VStack(spacing: 20){
calorieField(nutrientTitle: "Calories",amount: $vm.cals)
Rectangle()
.fill(.gray)
.frame( height: 1)
nutrientFields(nutrientTitle: "Carbohydrates",amount: $vm.carb)
Rectangle()
.fill(.gray)
.frame( height: 1)
nutrientFields(nutrientTitle: "Proteins",amount: $vm.aminos)
Rectangle()
.fill(.gray)
.frame( height: 1)
nutrientFields(nutrientTitle: "Fats",amount: $vm.lipids)
}
}
func navBarView() -> some View {
ZStack {
HStack{
Button ( action: { self.presentationMode.wrappedValue.dismiss() },
label: {
Image(systemName: "arrow.backward").frame(width: 16, height: 16)
.foregroundColor(Color(ColorName.appAqua.rawValue))
})
Spacer()
}
Text("Quick Add")
.font(.custom(Nunito.Bold.rawValue, size: 22.5))
.foregroundColor(Color(ColorName.appAqua.rawValue))
}
}
func addButton() -> some View {
// NavigationLink(
// destination: BreakFastMainView(viewName: viewName, firebaseId: UserDefaults.standard.value(forKey: "FireBaseId") as! String) .navigationBarTitle("")
// .navigationBarHidden(true)
// ,
Button {
vm.addMealData(category: viewName, image: selectedImage ?? UIImage(), name: vm.title, cals: vm.cals, carbs: vm.carb, protein: vm.aminos, fat: vm.lipids, description: vm.description, firebaseId: UserDefaults.standard.value(forKey: "FireBaseId") as? String ?? "12345", action: {
self.presentationMode.wrappedValue.dismiss()
})
}
label: {
ZStack {
RoundedRectangle(cornerRadius: 10)
.frame(height: 50)
.foregroundColor(Color("btnBlue"))
Text("Add")
.font(.custom("Nunito-Bold", size: 20))
.foregroundColor(.white)
}.padding([.top], 32)
}
}
func data(_ name: String, _ amount: String) -> some View {
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: 5)
.stroke( .gray, lineWidth: 0.5)
.frame(height: 56)
HStack {
Text(name)
.foregroundColor( .gray)
.font(.custom(Nunito.Semibold.rawValue, size: 20))
Spacer()
Text(amount)
.foregroundColor( Color(ColorName.appAqua.rawValue))
.font(.custom(Nunito.Semibold.rawValue, size: 20))
Text("g")
.foregroundColor( Color(ColorName.appAqua.rawValue))
.font(.custom(Nunito.Semibold.rawValue, size: 20))
}.padding()
}
}
}
struct QuickAddView_Previews: PreviewProvider {
static var previews: some View {
QuickAddView( viewName: "dfd")
}
}
I have a View stack as Expanded white part and I have given the corner radius to it, I need to give radius to only top left and top right
My Code
struct loginView: View {
#State private var stringOfTextField: String = String()
var body: some View {
ZStack {
LinearGradient(colors: [Color("primarycolor"), Color("secondarycolor")],
startPoint: .top,
endPoint: .center).ignoresSafeArea()
VStack() {
Text("Login").foregroundColor(.white).font(
.system(size: 18)
)
Image("logo")
Spacer()
}
VStack {
Spacer(minLength: 230)
VStack{
HStack {
Image(systemName: "person").foregroundColor(.gray)
TextField("Enter Email", text: $stringOfTextField)
} .padding()
.overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.gray, style: StrokeStyle(lineWidth: 1.0)))
.padding(.bottom)
TextField("Enter Password", text: $stringOfTextField)
.padding()
.overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.gray, style: StrokeStyle(lineWidth: 1.0)))
.padding(.bottom)
Text("Forgot Password ?")
.frame(maxWidth: .infinity, alignment: .trailing)
.padding(.bottom)
Button(action: {
print("sign up bin tapped")
}) {
Text("SIGN IN")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.system(size: 18))
.padding()
.foregroundColor(.white)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color("secondarycolor"), lineWidth: 1)
)
}
.background(Color("secondarycolor"))
.cornerRadius(25)
Spacer()
}
.padding(.vertical, 60)
.padding(.horizontal, 20)
.background(Color.white)
.cornerRadius(30)
}
}
.ignoresSafeArea(edges: [.bottom])
}
}
Preview
You can see on the end it's showing white border because border is given to all sides, I need to give it to top 2 sides only. I try by Roundedcorner, but that was not working.
You can try like this
struct ContentView: View {
var body: some View {
VStack{
//....
//your content
//.....
}
.clipShape(CustomCorner(corners: [.topLeft, .topRight], radius: 25))
}
}
struct CustomCorner: Shape {
var corners : UIRectCorner
var radius : CGFloat
func path(in rect: CGRect)->Path{
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
How can I make sure that my UI looks good on different devices such as the iPhone 13 and the iPhone 8?
Here is my code that is unresponsive
It is just a simple layout
import SwiftUI
let grey = Color(red: 0.928, green: 0.928, blue: 0.928)
let i = 0
var columns: [GridItem] =
Array(repeating: .init(.flexible()), count: 3)
let categories: [Category] = [
.init(name: "Pasta", imageName: "square.and.arrow.up"),
.init(name: "Asian", imageName: "square.and.arrow.down.fill"),
.init(name: "Main", imageName: "rectangle.portrait.and.arrow.right"),
.init(name: "Quick", imageName: "pencil.slash"),
.init(name: "Veg", imageName: "scribble.variable"),
.init(name: "Dessert", imageName: "pencil.circle.fill"),
]
struct SearchView: View {
var body: some View {
VStack{
Text("Search For Recipes")
.font(.system(size: 35))
.padding(.top, 80)
.padding(.horizontal, -70)
.frame(width: 200, height: 10, alignment: .leading)
Spacer()
SearchBox()
.padding(.top, 50)
Spacer()
Recomend()
.padding(.top)
.padding(.leading, -100)
Spacer()
LazyVGrid(columns: columns){
ForEach((0...5), id: \.self) { _ in
MenuChoice()
}
}
.padding(20)
.padding(.bottom, 100)
.padding(.top)
.frame(maxWidth: .infinity)
.frame(height:500)
}
}
}
struct SearchBox: View {
var body: some View{
VStack{
HStack{
Image(systemName: "magnifyingglass")
Text("Search for recipes")
}
.frame(width: 200, height: 10, alignment: .leading)
.padding(.trailing, 60)
}
.frame(width: 300, height: 50)
.background(grey)
.cornerRadius(8)
.padding(.trailing, 50)
}
}
struct MenuChoice: View{
var body: some View{
ZStack{
ForEach(categories, id: \.self) { category in
VStack{
Spacer()
.frame(width: 100, height: 100)
.background(Color(red: 50, green: 207, blue: 255))
.cornerRadius(5)
.shadow(color: .init(.sRGB, white: 0.7, opacity: 1), radius: 4, x: 0.0, y: 2)
.padding(.bottom)
.overlay(
VStack(spacing: 8) {
Image(systemName: category.imageName)
.padding(.top, -10)
.font(.system(size: 30))
Text(category.name)
.foregroundColor(.black)
.font(.system(size: 20))
.padding(.top, 5)
}
)
}
}
}
}
}
struct Recomend: View{
var body: some View{
Button {
print("Image tapped!")
} label: {
ZStack{
RoundedRectangle(cornerRadius: 8)
.frame(width: 250, height: 50)
.foregroundColor(grey)
Text("See All Recomended Recipes")
.foregroundColor(Color.black)
}
}
}
}
struct SearchView_Previews: PreviewProvider {
static var previews: some View {
SearchView()
.previewDevice(PreviewDevice(rawValue: "iPhone 13"))
SearchView()
.previewDevice(PreviewDevice(rawValue: "iPhone 8"))
}
}
On the iPhone 13 it looks good but on the iPhone 8 it looks squashed and not good.
How can i make my code responsive for different screen heights/widths?
Following the comments you could go in this direction:
This adapts nicely and also is a lot less code.
struct ContentView: View {
var body: some View {
VStack{
Text("Search For Recipes")
.font(.system(size: 35))
.frame(maxWidth: .infinity, alignment: .leading)
SearchBox()
.padding(.bottom)
.padding(.bottom)
Recomend()
Spacer()
LazyVGrid(columns: columns, spacing: 18){
ForEach(categories) { category in
MenuChoice(category: category)
}
}
Spacer()
}
.padding()
}
}
struct SearchBox: View {
var body: some View{
VStack {
HStack{
Image(systemName: "magnifyingglass")
Text("Search for recipes")
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
.background(grey)
.cornerRadius(8)
}
}
struct MenuChoice: View{
let category: Category
var body: some View{
VStack(spacing: 8) {
Image(systemName: category.imageName)
.padding(.top)
.font(.system(size: 30))
Text(category.name)
.foregroundColor(.black)
.font(.system(size: 20))
.padding(.bottom)
}
.frame(width: 100, height: 100)
.background(Color(red: 50, green: 207, blue: 255))
.cornerRadius(5)
.shadow(color: .init(.sRGB, white: 0.7, opacity: 1), radius: 4, x: 0.0, y: 2)
}
}
struct Recomend: View{
var body: some View{
Button {
print("Image tapped!")
} label: {
Text("See All Recomended Recipes")
.padding()
.foregroundColor(Color.black)
.frame(maxWidth: .infinity, alignment: .leading)
.background(grey)
.cornerRadius(8)
}
}
}
NavigationView {
ScrollView{
.navigationTitle("Home")
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
VStack{
HStack{
NavigationLink(
destination: Home(),
label: {
Image(systemName: "house")
.resizable()
.frame(width: 25.0, height: 20.0)
.foregroundColor(.blue)
.padding()
})
}
}
I cant use NavigationLink(destination : Text("Go home page"),label:{}
It is menu bar I want to freeze this menu bar when I scroll down or up
Thank you so much
import SwiftUI
struct HomeNav: View {
#State var isActiveHome: Bool = false
var body: some View {
NavigationView {
ScrollView{
Text("Main")
NavigationLink(
destination: Text("Home").navigationTitle("Home"),
isActive: $isActiveHome,
label: {
Image(systemName: "house")
.resizable()
.frame(width: 25.0, height: 20.0)
.foregroundColor(.blue)
.padding()
}).hidden().frame(width: 0, height: 0, alignment: .center)
.navigationTitle("Main")
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
VStack{
HStack{
Button(action: {
isActiveHome = true
}, label: {
Image(systemName: "house")
.resizable()
.frame(width: 25.0, height: 20.0)
.foregroundColor(.blue)
.padding()
})
}
}
}
}
}
}
}
}
Why can SwiftUI not just load the view it shouldn't b e this hard to do something that could be done in UIKit in one stupid line. the button should simply load what its told to load in this case VideoList(viewModel: .init()) there should be no problem.
import Foundation
import SwiftUI
struct SwiftUIView: View {
#State private var isLinkActive = false
let layout = [
GridItem(.adaptive(minimum: 150))
]
var body: some View {
///Top Bar layout
ZStack {
HStack {
Button(action: {
}, label: {
Image("Home")
.resizable()
.frame(width: CGFloat(30), height: CGFloat(30), alignment: .leading)
}).padding(.leading, CGFloat(20))
.padding(.top, 15)
Spacer()
}
HStack {
Text("app")
.frame(alignment: .center)
.font(.title3)
.foregroundColor(Color("Menu"))
.multilineTextAlignment(.center)
.padding(.top, 15)
}
}
///Setup app FEED LINE
HStack{
Text("app FEED")
.padding(.leading, 20.0)
.padding(.top, 100.0)
.font(.largeTitle)
.foregroundColor(Color("Menu"))
Spacer()
}
///Setup Welcom messages
HStack{
Text("Good morning")
.padding(.bottom, 20)
.padding(.leading, 20.0)
.font(.subheadline)
.foregroundColor(Color("Menu"))
Spacer()
Text("...")
.foregroundColor(/*#START_MENU_TOKEN#*/.blue/*#END_MENU_TOKEN#*/)
.font(.largeTitle)
.padding(.trailing, 20.0)
.padding(.bottom, 20)
}
/// Setup navigation home
ScrollView {
LazyVGrid(columns: layout, spacing: 5) {
Button(action: {
print("Button action")
}) {
Image("app")
}
.padding(.vertical, 2.5)
.padding(.horizontal, 2.5)
Button(action: {
print("Button action")
}) {
Image("app")
}
.padding(.vertical, 2.5)
.padding(.horizontal, 2.5)
Button(action: {
self.isLinkActive = true
}) {
Image("app")
}
.padding(.vertical, 2.5)
.padding(.horizontal, 2.5)
Button(action: {
print("Button action")
}) {
Image("app")
}
Button(action: {
print("Button action")
}) {
Image("app")
}
.padding(.vertical, 2.5)
.padding(.horizontal, 2.5)
Button(action: {
print("Button action")
}) {
Image("app")
}
//Add correct images Direction and Contact us
Button(action: {
print("Button action")
}) {
Image("app")
}
Button(action: {
print("Button action")
}) {
Image("app")
}
.padding(.vertical, 2.5)
.padding(.horizontal, 2.5)
}
}
.padding(.horizontal, 2.5)
.padding(.vertical, 2.5)
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(true)
.background(
NavigationLink(destination: VideoList(viewModel: .init()), isActive: $isLinkActive) {
EmptyView()
}
.hidden()
)
}
}
struct VideoList: View {
#Environment(\.presentationMode) private var presentationMode
#ObservedObject private(set) var viewModel: ViewModel
#State private var isRefreshing = false
var body: some View {
NavigationView {
List(viewModel.videos.sorted { $0.id > $1.id}, id: \.id) { video in
NavigationLink(
destination: VideoDetails(viewModel: VideoDetails.ViewModel(video: video))) {
VideoRow(video: video)
}
}
.onPullToRefresh(isRefreshing: $isRefreshing, perform: {
self.viewModel.fetchVideos()
})
.onReceive(viewModel.$videos, perform: { _ in
self.isRefreshing = false
})
.navigationBarTitle(viewModel.navigationBarTitle)
}
.onAppear(perform: viewModel.fetchVideos)
}
}
#if DEBUG
struct VideoList_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
VideoList(viewModel: .init())
}
}
}
#endif
The button on line 109 does not load the VideoList(viewModel: .init()) ViewModel when requested to do so.
NavigationView {} was forgotten however the UI is still messed up currently
and adding an HStack fixed.... ugh hope this helps the next guy not have to spend 3 days on it