How to align views inside of Hstack to opposing sides? - ios

I've been trying to make a SwiftUI view and have trouble doing something that could be easily done with constraints.
My view should look like this
and it looks like this
How do I align them to the sides without the constraints?
Here is my code for this view
private var toolsBottomView: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 20) {
ForEach(0..<AppTools.allCases.count) { index in
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: 16)
.frame(height: 116)
.foregroundColor(Color(#colorLiteral(red: 0.1294117647, green: 0.137254902, blue: 0.1882352941, alpha: 1)))
HStack(alignment: .center, spacing: 0) {
Spacer().frame(width: 20)
VStack(alignment: .leading) {
Image("\(AppTools.allCases[index])").resizable().frame(width: 27, height: 27)
Text(AppTools.allCases[index].rawValue)
.font(.custom("AvenirNextCyr-Demi", size: 24))
Text(AppTools.allCases[index].subtitles)
.font(.custom("AvenirNextCyr-Demi", size: 12))
.foregroundColor(Color(#colorLiteral(red: 0.4823529412, green: 0.4980392157, blue: 0.6196078431, alpha: 1)))
}.foregroundColor(.white)
Button("+", action: {
self.currentSelectedTool = AppTools.allCases[index]
self.showToolView.toggle()
})
.font(.custom("AvenirNextCyr-Demi", size: 20))
.frame(width: 48, height: 48)
.background(Color(#colorLiteral(red: 1, green: 0.6745098039, blue: 0.1882352941, alpha: 1)).cornerRadius(24))
.foregroundColor(Color(#colorLiteral(red: 0.1294117647, green: 0.137254902, blue: 0.1882352941, alpha: 1)))
}
.frame(minWidth: 0, maxWidth: .infinity)
}
}
Spacer()
}
}.offset(y: 15).padding()
}

Put Spacer in between elements you want keep aside, like
HStack(alignment: .center, spacing: 0) {
VStack(alignment: .leading) {
Image("\(AppTools.allCases[index])").resizable().frame(width: 27, height: 27)
Text(AppTools.allCases[index].rawValue)
.font(.custom("AvenirNextCyr-Demi", size: 24))
Text(AppTools.allCases[index].subtitles)
.font(.custom("AvenirNextCyr-Demi", size: 12))
.foregroundColor(Color(#colorLiteral(red: 0.4823529412, green: 0.4980392157, blue: 0.6196078431, alpha: 1)))
}.foregroundColor(.white)
.padding(.leading)
Spacer() // << here !!
Button("+", action: {
self.currentSelectedTool = AppTools.allCases[index]
self.showToolView.toggle()
})
.font(.custom("AvenirNextCyr-Demi", size: 20))
.frame(width: 48, height: 48)
.background(Color(#colorLiteral(red: 1, green: 0.6745098039, blue: 0.1882352941, alpha: 1)).cornerRadius(24))
.foregroundColor(Color(#colorLiteral(red: 0.1294117647, green: 0.137254902, blue: 0.1882352941, alpha: 1)))
.padding(.trailing)
}

Related

Can't see the back button in Navigation View

For some reason I can't see the back button in the Navigation View.
I don't know if there is some extra code that I need to add in the child view but I don't know. I more or less copied the code from the tutorial, but I can't see the back button in the child view.
var body: some View {
VStack {
//Rectangle 12
Rectangle()
.fill(Color(#colorLiteral(red: 0.7137255072593689, green: 0.10196077823638916, blue: 0.10196077823638916, alpha: 1)))
.frame(width: .infinity, height: 50)
.padding(.bottom, 0.0)
NavigationView {
ZStack{
Color(red: 0.9, green: 0.9, blue: 0.9).edgesIgnoringSafeArea(.all)
ScrollView(.vertical, showsIndicators: true) {
HStack{
Text("Marketplace").font(.custom("Arial", size: 35))
.fontWeight(.medium)
.foregroundColor(Color(red: 0.1, green: 0.1, blue: 0.1))
.padding(EdgeInsets(top: 15, leading: 20, bottom: -2, trailing: 0))
Spacer()
}
ForEach(produitsdfsdf, id: \.id ) { product in
NavigationLink(destination: TempView()) {
LandingPresets.listItem(name: product.name, description: product.price, rate: product.category)
}
}
}
.navigationBarHidden(true)
}
}
.padding(.top, -8.0)
}.ignoresSafeArea(edges: .top)
.onAppear {
ProductAPI().getAllProducts {(productArr) in
self.produitsdfsdf = productArr
}
}
}
It is because of you use .navigationBarHidden(true) in main View.
You could add .navigationBarTitleDisplayMode(.inline) to your TempView().
If you give code of TempView, I'll be able to show to which part of code.

Confusion with passing data to another view. SwiftUI

I'm building this project, and I have two views: MenuView and CreateBoardView.
What I want to achieve is to be able to create a new board on the menu screen, and so that the data I'd enter (board name and description) would be shown in the new created box. But I'm really confused about how to make it.
Here's the code for my MenuView:
import Foundation
import SwiftUI
struct MenuView: View {
#EnvironmentObject var AboutBoard: BoardModel
var body: some View {
ZStack {
VStack {
HStack(spacing: 80) {
VStack(alignment: .leading, spacing: 10) {
Text("Hey,")
.font(Font.custom("Montserrat", size: 25))
Text("username")
.font(Font.custom("Montserrat-Bold", size: 30))
}
Image("Profile")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100, alignment: .trailing)
}
.padding(.top, 30)
HStack(alignment: .top, spacing: 30) {
VStack(alignment: .leading) {
Text("New board")
.font(Font.custom("Montserrat-Bold", size: 25))
.foregroundColor(.white)
Text("Create with your friends")
.font(Font.custom("Montserrat", size: 18))
.foregroundColor(.white)
.padding(.bottom, 10)
NavigationLink(destination: CreateBoardView()) {
Text("Create board")
}.padding(15)
.frame(width: 180, height: 50, alignment:.center)
.background(LinearGradient(gradient: Gradient(colors: [(Color.init(red: 0.58, green: 0.12, blue: 0.68)), (Color.init(red: 0.58, green: 0.12, blue: 0.68))]), startPoint: .topLeading, endPoint: .bottomTrailing), in: RoundedRectangle(cornerRadius: 20))
.foregroundColor(.white)
.scaledToFill()
.font(Font.custom("Montserrat-Bold", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 5, x: 0, y: 7)
.navigationBarBackButtonHidden(true)
.navigationBarTitleDisplayMode(.inline)
}
Image("Forum")
.resizable()
.scaledToFit()
.frame(width: 50, height: 50)
}
.frame(width: 350, height: 180, alignment: .center)
.background(LinearGradient(gradient: Gradient(colors: [(Color.init(red: 0.88, green: 0.33, blue: 1.00)), (Color.init(red: 0.69, green: 0.05, blue: 1.00))]), startPoint: .topLeading, endPoint: .bottomTrailing), in: RoundedRectangle(cornerRadius: 30))
HStack(spacing: 150) {
Text("Your boards")
.font(Font.custom("Montserrat-Bold", size: 20))
Text("See all")
.font(Font.custom("Montserrat", size: 15))
}.padding(.top, 20)
HStack(spacing: 30) {
ForEach(0..<10) {_ in
Text(AboutBoard.BoardName)
.font(Font.custom("Montserrat", size: 20))
Text(AboutBoard.BoardDescription)
.font(Font.custom("Montserrat", size: 20))
}
.frame(width: 250, height: 210)
.background(
Image("Board-Holder")
.resizable()
.scaledToFit()
.frame(width: 250, height: 210)
)
}
Spacer()
}
}
.environmentObject(BoardModel())
}
}
struct MenuPagePreview: PreviewProvider {
static var previews: some View {
MenuView()
}
}
And my CreateBoardView:
import Foundation
import SwiftUI
struct CreateBoardView: View {
#StateObject var BoardInfo = BoardModel()
#State private var SetDeadline = false
#State private var ShowMenu = false
var body: some View {
ZStack {
VStack {
Text("Create a new board")
.font(Font.custom("Montserrat-Medium", size: 30))
.padding(.bottom, 50)
.padding(.top, 50)
Text("Enter your board's name")
.font(Font.custom("Montserrat", size: 20))
.padding(.bottom, 30)
TextField("Board name", text: $BoardInfo.BoardName)
.padding(15)
.frame(width: 350, height: 60, alignment:.center)
.background(RoundedRectangle(cornerRadius: 20).fill(.white))
.scaledToFill()
.font(Font.custom("Montserrat", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 15, x: 0, y: 7)
.padding(.bottom, 25)
.disableAutocorrection(true)
Text("Add board description")
.font(Font.custom("Montserrat", size: 20))
.padding(.bottom, 30)
TextField("Board description", text: $BoardInfo.BoardDescription)
.padding(15)
.frame(width: 350, height: 60, alignment:.center)
.background(RoundedRectangle(cornerRadius: 20).fill(.white))
.scaledToFill()
.font(Font.custom("Montserrat", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 15, x: 0, y: 7)
.padding(.bottom, 25)
.disableAutocorrection(true)
NavigationLink(destination: MenuView()) {
Text("Create board")
}
.padding(15)
.frame(width: 350, height: 60, alignment:.center)
.background(LinearGradient(gradient: Gradient(colors: [(Color.init(red: 0.72, green: 0.26, blue: 0.67)), (Color.init(red: 0.47, green: 0.16, blue: 0.74))]), startPoint: .topLeading, endPoint: .bottomTrailing), in: RoundedRectangle(cornerRadius: 20))
.foregroundColor(.white)
.scaledToFill()
.font(Font.custom("Montserrat-Bold", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 15, x: 0, y: 7)
.padding(.bottom, 25)
.sheet(isPresented: $ShowMenu){
MenuView()
}
}
}
}
}
struct CreateBoardPreview: PreviewProvider {
static var previews: some View {
CreateBoardView()
}
}
I also have this BoardModel but I don't know if I'm even doing it right.
import Foundation
import SwiftUI
class BoardModel: ObservableObject {
static let shared = BoardModel()
#Published var BoardName: String = ""
#Published var BoardDescription: String = ""
}
So how to make it such way so that the CreateBoardView would take the input and then have it stored and shown in the menu?
Thanks.

Xcode Preview canvas different then Simulator

I am currently developing an app, and I am trying to setup the Views to be accurate for different screen sizes. I get the design to what I would like in the preview, but then when I run it in the simulator some things are a little off. To note not all screens do this, just a few. Any reason why this may be?
Screenshot for reference: Xcode/Simulator Screenshot
ContentView:
struct ContentView: View {
//Removed variables for checking log ins and loading screen animation
var body: some View {
VStack{
//Check if logged in and not first time
if status && !firstTime{
ZStack{
NavigationView{
TabView(){
Tab1View()
.environmentObject(ContentViewModel())
Tab2View()
.environmentObject(ContentViewModel())
}
.navigationBarHidden(true)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
ZStack{
//LoadingScreen
}
.ignoresSafeArea(edges: .all)
.onAppear(perform: animateSplash)
.opacity(endSplash ? 0 : 1)
}
}
//Check if logged and first time
else if status && firstTime{
ZStack{
NavigationView{
if role == "owner"{
WelcomeView()
} else {
WelcomeEmployeeView()
}
}
}
} else {
NavigationView{
//View in the screenshot
CreateView()
}
}
}
CreateView:
import SwiftUI
import FirebaseAuth
struct CreateView: View {
#EnvironmentObject var model: ContentViewModel
#State var companyName = ""
#State var employeeName = ""
#State var phoneNumber = ""
#State var show = false
#State var message = ""
#State var alert = false
#State var ID = ""
#State var test = ""
#State var role = "owner"
var body: some View {
ZStack{
ZStack(alignment: .topTrailing){
Path{ path in
path.move(to: CGPoint(x: 500, y: 0))
path.addLine(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 0, y: 80))
path.addLine(to: CGPoint(x:500, y: 180))
}
.fill(LinearGradient(gradient:Gradient(colors: [Color(#colorLiteral(red: 0.6470588235, green: 0.8196078431, blue: 0.7450980392, alpha: 1)), Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)), .white, .green]), startPoint: .topLeading, endPoint: .bottomTrailing))
.edgesIgnoringSafeArea(.top)
Image("icon-white")
.resizable()
.frame(width: 50, height: 60)
.padding(.top)
.padding(.trailing, 30)
}
VStack(alignment: .leading){
Text("Create a")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Medium", size: 30))
Text("Company Account")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Medium", size: 30))
.padding(.bottom, 30)
Text("Company Name")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Semibold", size: 16))
TextField("", text: $companyName)
.frame(width: 290)
.padding(14)
.overlay(RoundedRectangle(cornerRadius: 5.0).strokeBorder(Color.black, style: StrokeStyle(lineWidth: 0.5)))
.padding(.bottom)
Text("Employee Name")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Semibold", size: 16))
TextField("", text: $employeeName)
.frame(width: 290)
.padding(14)
.overlay(RoundedRectangle(cornerRadius: 5.0).strokeBorder(Color.black, style: StrokeStyle(lineWidth: 0.5)))
.padding(.bottom)
Text("Phone Number")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Semibold", size: 16))
TextField("", text: $phoneNumber)
.frame(width: 290)
.padding(14)
.overlay(RoundedRectangle(cornerRadius: 5.0).strokeBorder(Color.black, style: StrokeStyle(lineWidth: 0.5)))
.padding(.bottom)
VStack(alignment: .center){
NavigationLink(
destination: VerifcationView(show: $show, ID: $ID, name: $employeeName, companyName: $companyName, phoneNumber: $phoneNumber, hasCode: $test, role: $role), isActive: $show){
ZStack{
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.frame(width: 315,height: 50)
Button(action: {
PhoneAuthProvider.provider().verifyPhoneNumber( "+"+self.phoneNumber, uiDelegate:nil){ (ID, error) in
if error != nil {
self.message = (error?.localizedDescription)!
self.alert.toggle()
return
}
self.ID = ID!
self.show.toggle()
}
}, label: {
Text("Create Account")
.font(.custom("Poppins-Medium", size: 18))
.foregroundColor(.white)
})
}
}
NavigationLink(
destination: JoinView()){
Text("Join as Employee")
.foregroundColor(Color(red: 141/255, green: 141/255, blue: 141/255))
.underline(/*#START_MENU_TOKEN#*/true/*#END_MENU_TOKEN#*/, color: Color(red: 141/255, green: 141/255, blue: 141/255))
}
}
.padding(.top)
}
.padding(.top)
}
.navigationBarBackButtonHidden(true)
}
}
For SwiftUI previews, you just preview a single view - CreateView. This is the only view that gets previewed. Meanwhile, your simulator runs the entire app, starting all the way back from your ContentView.
Note that inside ContentView, you're wrapping CreateView in a NavigationView.
NavigationView{
// View in the screenshot
CreateView()
}
This will add a gap at the top of the screen, pushing everything else down (resulting in the difference that you see). Even the icon-white image is pushed down into the white part of the screen, which is why you can't see it in the simulator.

How to make last index as initial in Hstack scrollview swiftUI

I write the following code and display my days array into Hstack scrollview.
I want to scroll with button actions for that using scrollProxy by using ScrollViewReader
I implemented as follows
when I make a left and right button actions it works as expected
But when I come into screen initially shows the last index but it's not working for me
Anyone gives an idea what the correct place to move the last index.
var body: some View {
ScrollViewReader { scrollProxy in
ZStack{
VStack {
Button(action:{
scrollProxy.scrollTo(selectedDay) //<---- Working
})
.padding(.leading, 10)
Spacer()
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20) {
ForEach(days.indices, id: \.self) { i in
CalendarView(
number: self.days[i].number,
days: self.days[i].weekday,
color: self.days[i].isToday ? #colorLiteral(red: 0.9060331583, green: 0.2547450066, blue: 0.3359550834, alpha: 1) : #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
textcolor: self.days[i].isToday ? #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) : #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
)
.onTapGesture{
print(self.days[i])
// this is just for replacing the current selection
for j in self.days.indices { self.days[j].isToday = false }
self.days[i].isToday = true
}
}}
.padding(.leading,10)
.padding(.bottom, 10)
.shadow(radius: 3, x: 3, y: 3)
}
Spacer()
Button(action:{
scrollProxy.scrollTo(selectedDay) //<-- Working
})
.padding(.leading)
Spacer()
}
}
.onAppear {
self.getCurrentWeekdays()
scrollProxy.scrollTo(days.count - 1) //<-- Here it is not Work.
}
}
}

Align Text with padding SwiftUI

I am creating a view that looks like this -
I am struggling to align the summary text with the text inside the image overlay.
I would like the leading edge of Research to align with the leading edge of My experience.
At the moment my view is rendering as
As you can see text view is too close to the leading edge.
I have tried adding .padding() but the view changes to
How can I properly inset the text so these 2 components line up?
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
FeaturedContentCard()
.frame(minHeight: 100)
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct FeaturedContentCard: View {
var body: some View {
VStack {
ImageWithTextOverlayView(image: "featured_image", text: "My experience with EAP and Income Protection")
ContentCardSummary(text: "Research shows that our social enviroment significantly impacts our biology")
.padding(.all)
ContentCardMetaView(readTime: "10 min read", name: "Jessica Bell")
}
.padding(.bottom, 16)
.background(Color.white)
.feedItemContainer()
}
}
struct ImageWithTextOverlayView: View {
private(set) var image: String
private(set) var text: String
var body: some View {
Image(image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(minWidth: 0, maxWidth: .infinity)
.overlay(LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.6536279966)), Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 0))]), startPoint: .bottom, endPoint: .top))
.overlay(
Text(text)
.foregroundColor(Color.white)
.font(.title)
.padding(),
alignment: .bottomLeading
)
}
}
struct ContentCardSummary: View {
private(set) var text: String
var body: some View {
Text(text)
.frame(alignment: .leading)
.foregroundColor(Color(#colorLiteral(red: 0.2901960784, green: 0.2901960784, blue: 0.2901960784, alpha: 1)))
}
}
struct FeedItemContainer: ViewModifier {
func body(content: Content) -> some View {
content
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
.customShadow()
}
}
struct BenefexShadow: ViewModifier {
func body(content: Content) -> some View {
content
.shadow(color: Color(.init(red: 0.18, green: 0.18, blue: 0.18, alpha: 0.16)).opacity(1), radius: 4, x: 0, y: 1)
.shadow(color: Color(.init(red: 0.18, green: 0.18, blue: 0.18, alpha: 0.1)).opacity(1), radius: 60, x: 0, y: 4)
.shadow(color: Color(.init(red: 0.18, green: 0.18, blue: 0.18, alpha: 0.16)).opacity(1), radius: 4, x: 0, y: 1)
}
}
extension View {
func customShadow() -> some View {
self.modifier(BenefexShadow())
}
func feedItemContainer() -> some View {
self.modifier(FeedItemContainer())
}
}
struct AvatarView: View {
var body: some View {
Image("profile_pic")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 40, height: 40)
.clipShape(Circle())
.overlay(
Circle()
.stroke(Color.white, lineWidth: 2)
)
.customShadow()
}
}
struct ContentCardMetaView: View {
private(set) var readTime: String
private(set) var name: String
var body: some View {
HStack(spacing: 8) {
AvatarView()
VStack(alignment: .leading) {
Text(readTime)
.font(.subheadline)
.foregroundColor(Color(#colorLiteral(red: 0.2901960784, green: 0.2901960784, blue: 0.2901960784, alpha: 1)))
Text(name)
.fontWeight(.medium)
.foregroundColor(Color(#colorLiteral(red: 0.2980392157, green: 0.1843137255, blue: 0.737254902, alpha: 1)))
}
Spacer()
Button(action: { }) {
Image(systemName: "ellipsis")
.font(.system(size: 24))
.foregroundColor(Color(#colorLiteral(red: 0.7803921569, green: 0.7803921569, blue: 0.7803921569, alpha: 1)))
.rotationEffect(.degrees(-90))
}
}
}
}
Here is fix. Tested with Xcode 11.4 / iOS 13.4
1) Remove padding at top layer, so
ImageWithTextOverlayView(image: "large_image", text: "My experience with EAP and Income Protection")
ContentCardSummary(text: "Research shows that our social enviroment significantly impacts our biology")
ContentCardMetaView(readTime: "10 min read", name: "Jessica Bell")
2) Correct alignment of summary, as
struct ContentCardSummary: View {
private(set) var text: String
var body: some View {
Text(text)
.frame(maxWidth: .infinity, alignment: .leading) // << full width
.padding() // << same padding as above text
.foregroundColor(Color(#colorLiteral(red: 0.2901960784, green: 0.2901960784, blue: 0.2901960784, alpha: 1)))
}
}

Resources