The leading alignment doesn't apply to the text SwiftUI - swift

I have the following
struct hScrollView: View {
#State private var meals = ["short", "long Text", "really long text"]
var body: some View {
VStack(alignment: .leading) {
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 30) {
ForEach(0 ..< meals.count) { count in
VStack(alignment: .leading) {
HStack(alignment: .center) { // .center is by default, so also remove
Text("\(count + 1) ")
.foregroundColor(Color.black)
.multilineTextAlignment(.leading)
.padding(.horizontal, 15)
.padding(.vertical, 5)
.background(
Capsule()
.fill(Color.black)
.opacity(0.20)
)
Spacer()
Text("\(self.meals[count]) ")
.foregroundColor(Color.black)
.multilineTextAlignment(.leading)
Spacer()
Button(action: {
print("Button was tapped")
}) {
Image(systemName: "pencil")
.foregroundColor(Color.yellow)
.font(.system(size: 25, weight: .bold))
.shadow(radius: 1)
}
}
}
.padding(.horizontal)
}
}
.frame(width: UIScreen.main.bounds.width) // set a fixed width
}
.frame(height: 500)
.frame(maxWidth: 400)
.padding(.top, 190)
}
}
}
If you noticed, the text is centered, I want it that way, but all beginning with .leading alignment so they all start at the same start point. What can I fix there? I tried putting the leading alignment in all the stacks :/
Thanks

Your view would be like
(1)|-------|short|-------|✏️
(2)|-----|long text|-----|✏️
(3)|-|really long text|-|✏️
so you should remove the Spacer() between the first Text and second instead of set text alignment.
HStack(alignment: .center) { // .center is by default, so also remove
Text("\(count + 1) ")
.foregroundColor(Color.black)
.multilineTextAlignment(.leading)
.padding(.horizontal, 15)
.padding(.vertical, 5)
.background(
Capsule()
.fill(Color.black)
.opacity(0.20)
)
// Spacer()
Text("\(self.meals[count]) ")
.foregroundColor(Color.black)
.multilineTextAlignment(.leading)
Spacer()
Button(action: {
print("Button was tapped")
}) {
Image(systemName: "pencil")
.foregroundColor(Color.yellow)
.font(.system(size: 25, weight: .bold))
.shadow(radius: 1)
}
}

Related

How to remove big blank space on my list pagination [SwiftUI]

I am new to SwiftUI and I trying to remove the blank space on my list pagination. Everytime when the list loaded the new page, a blank space is pop-up. how can I fix this?
You can see the problem by bellow attached image,
Screenshot
this is my list view
My List
List {
LazyVGrid(columns: setGridLayout(), spacing: 20) {
ForEach(viewModel.personPopularList, id: \.id) { person in
PeopleCardView(person: person)
.listRowBackground(Color.white)
.listRowSeparator(.hidden)
}
.id(UUID())
.frame(maxWidth: .infinity)
}
.listRowBackground(Color.white)
.listRowSeparator(.hidden)
}
.frame(maxWidth: .infinity)
.onAppear(perform: {
UITableView.appearance().contentInset.top = -20
UITableView.appearance().backgroundColor = UIColor.white
})
.listStyle(GroupedListStyle())
this is my cardview
My CardView
struct PeopleCardView: View {
#State var person: PersonPopularResult
var body: some View {
ZStack(alignment: .center) {
HStack(alignment: .center) {
WebImage(url: URL(string: Constant.POSTER_URL + (person.profilePath ?? "")))
.placeholder {
Image("placeholder")
}
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.mPurple, lineWidth: 3))
Spacer()
VStack(alignment: .leading) {
Text("\(person.name!)")
.fontWeight(.bold)
.lineLimit(1)
.font(.system(size: 21))
.font(.headline)
Text("Popolarity Rate: \(String(format: "%.3f", person.popularity!))")
.fontWeight(.bold)
.foregroundColor(.mPurple)
.lineLimit(1)
.font(.system(size: 14))
.padding(.top, -8)
Spacer()
}
.padding([.top, .leading], 10)
Spacer()
}
.frame(width: 300, height: 100, alignment: .center)
.padding()
.background(
RoundedRectangle(cornerRadius: 15, style: .continuous)
.fill(.white)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.mPurple, lineWidth: 3))
.shadow(radius: 7)
)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
thanks for anyone can help to my problem.

Why do the elements inside my VStack inside a HStack still go vertical

So basically this is my code.
Text("Melbourne, Victoria")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.white)
.padding(.bottom, 30)
Image(systemName: "moon.fill")
.foregroundColor(Color.white)
.font(.system(size: 60))
Text("Today")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
Text("34°C")
.font(.title3)
.fontWeight(.medium)
.foregroundColor(Color.white)
Spacer()
HStack {
Image(systemName: "sun.max.fill")
.foregroundColor(Color.yellow)
.font(.system(size: 40))
.padding(.bottom, 550)
Text("Mon 34°C")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
.padding(.bottom, 550)
}
}
.background(
Image("night")
.ignoresSafeArea()
)
I want to make more of the days in this weather app each with it's on SF Symbol and everything is inside this VStack. And the days and SF symbols are inside a HStack to keep them horizontal. But if I want to put more of those the next time I do it they go next to each other but the symbol goes on top look at this.
This is the image with only 1 of those days
And this one is when I put more than 1 but its next to each other when I want them vertically aligned.
This is the one if I put them in another VStack which makes the SF symbol go above the text
IS there any solution to this?
The problem is your .padding(.bottom, 550).
Image(systemName: "sun.max.fill")
.foregroundColor(Color.yellow)
.font(.system(size: 40))
.padding(.bottom, 550) /// here!
It's currently attached to your first Image. As a result, the HStack is stretched vertically and it appears as though the first Image is higher up than second one.
To fix, move both .padding(.bottom, 550)s to outside your HStack.
You have quite a lot of arbitrary values for padding. You should have your layout adapt to various devices, rather than hard-coding that .bottom spacing for example.
Working example:
struct ContentView: View {
var body: some View {
VStack(spacing: 40) {
Text("Melbourne, Victoria")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.white)
VStack {
Image(systemName: "moon.fill")
.foregroundColor(Color.white)
.font(.system(size: 60))
Text("Today")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
Text("34°C")
.font(.title3)
.fontWeight(.medium)
.foregroundColor(Color.white)
}
VStack(spacing: 10) {
HStack {
Image(systemName: "sun.max.fill")
.renderingMode(.original)
.font(.system(size: 40))
Text("Mon 34°C")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
}
HStack {
Image(systemName: "cloud.sun.fill")
.renderingMode(.original)
.font(.system(size: 40))
Text("Tue 28°C")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
}
}
Spacer()
}
.frame(maxWidth: .infinity)
.background(
Color(red: 0.34, green: 0.36, blue: 0.71)//Image("night")
.ignoresSafeArea()
)
}
}
Result:
Although there is already an outer VStack, they are nested VStacks because they have different amounts of padding. Multiple views are grouped together, and then those are grouped together with larger paddings to separate them.
Bonus
SF Symbols colors
Use:
.renderingMode(.original)
Rather than:
.foregroundColor(Color.yellow)
To color the SF Symbols with the default colors, as shown in the above example.
Align days
You can align the days across each HStack with a custom alignment guide. Use the following:
extension HorizontalAlignment {
struct LeadingDay: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
context[.leading]
}
}
static let leadingDay = HorizontalAlignment(LeadingDay.self)
}
Making the other following changes:
VStack(alignment: .leadingDay, spacing: 10) { // <- HERE
HStack {
Image(systemName: "sun.max.fill")
.renderingMode(.original)
.font(.system(size: 40))
Text("Mon 34°C")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
.alignmentGuide(.leadingDay) { d in // <- HERE
d[.leading]
}
}
HStack {
Image(systemName: "cloud.sun.fill")
.renderingMode(.original)
.font(.system(size: 40))
Text("Tue 28°C")
.font(.title)
.fontWeight(.medium)
.foregroundColor(Color.white)
.alignmentGuide(.leadingDay) { d in // <- HERE
d[.leading]
}
}
}
Result:

SWIFT - Transparent Button

I want to place button at the bottom of the screen and also want to make it little transparent.
Here I am sharing my code with image. Can please any one suggest me like how to make button transparent and how to change the position.
card.swift
//
// testCard.swift
// demoApp
//
// Created by ZAREEN NAUSHAD on 17/01/21.
//
import SwiftUI
struct testCard: View {
var testItem : testCourse
var body: some View {
ZStack{
Image(testItem.testImage)
VStack{
Text(testItem.testName)
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
Text("Marks: " + testItem.testMarks)
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Text("Minute: " + testItem.testTime)
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Text("Question: " + testItem.testQuestion)
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(Color.white)
}.offset(y : -160)
Button(action: ({
print("Button Clicked")
}), label: {
HStack{
Text("Take Test Now")
.fontWeight(.heavy)
.foregroundColor(Color("LCOdarkpink"))
Image(systemName: "arrow.right.square")
.accentColor(Color("LCOdarkpink"))
}
.padding(.horizontal, 40)
.padding(.vertical, 10)
.background(Color.white)
.clipShape(Capsule())
}).offset(y : 0) // here i am trying to change the position of button but its not moving
}
.frame(width: 280, height: 430)
.background(testItem.testColor)
.cornerRadius(18)
}
}
struct testCard_Previews: PreviewProvider {
static var previews: some View {
testCard(testItem: testList[1])
.previewLayout(.sizeThatFits)
}
}
Instead of using offsets to change the position of your elements you can use a Spacer() inside a VStack(). To change the transparency of the button you can use the .opacity() modifier.
You could try something like this:
struct ContentView: View {
var body: some View {
ZStack{
//Image(testItem.testImage)
RoundedRectangle(cornerRadius: 15)
.fill(Color(.blue))
VStack {
Text("testItem.testName")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
Text("Marks: " + "testItem.testMarks")
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Text("Minute: " + "testItem.testTime")
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Text("Question: " + "testItem.testQuestion")
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(Color.white)
Spacer() // <-- 1. Spacer instead of offset
Button(action: ({
print("Button Clicked")
}), label: {
HStack{
Text("Take Test Now")
.fontWeight(.heavy)
.foregroundColor(Color(.black))
Image(systemName: "arrow.right.square")
.accentColor(Color(.black))
}
.padding(.horizontal, 40)
.padding(.vertical, 10)
.background(Color.white
.opacity(0.8)) // <-- 2. Change transperancy of button here
.clipShape(Capsule())
})
}.padding()
}
.frame(width: 280, height: 430)
.background(testItem.testColor)
.cornerRadius(18)
}
}

How to change background color and image when it's tapped to the button in swift UI?

I want to change background color and add an okay button image to the selection point when I tap to that point. How can I do that ? I do know how to change the background color but I'm not sure how can I add confirmation image in. Should I use ZStack for this or is there any other way to do so ?
HStack {
Button(action: {
self.tap1.toggle()
}) {
Text("")
.padding(.horizontal, 10)
.padding(.vertical, 5)
.background((self.tap1) ? Color(.gray) : Color(.blue)
.cornerRadius(4)
.padding(.leading, 40)
}
Spacer()
Text("Diyabet")
.font(.system(size: 20, weight: .regular, design: .rounded))
.padding(.trailing, 200)
Spacer()
}.padding(.bottom, 20)
HStack {
Button(action: {
self.tap2.toggle()
}) {
Text("")
.padding(.horizontal, 10)
.padding(.vertical, 5)
.background(self.tap2 ? Color(.gray) : Color(.blue)
.cornerRadius(4)
.padding(.leading, 40)
}
Spacer()
Text("Yüksek Tansiyon")
.font(.system(size: 20, weight: .regular, design: .rounded))
.padding(.trailing, 130)
Spacer()
}.padding(.bottom, 20)
HStack {
Button(action: {
self.tap3.toggle()
}) {
Text("")
.padding(.horizontal, 10)
.padding(.vertical, 5)
.background(self.tap3 ? Color(.gray) : Color(.blue)
.cornerRadius(4)
.padding(.leading, 40)
}
Spacer()
Text("Kalp ve Damar Hastalıkları")
.font(.system(size: 20, weight: .regular, design: .rounded))
.padding(.trailing, 45)
Spacer()
}.padding(.bottom, 20)
#State private var pressed = false
var body: some View {
ZStack {
Button(action: {
self.pressed.toggle()
}) {
ZStack {
Rectangle().fill(self.pressed ? Color.blue : Color.gray)
if self.pressed {
Image(systemName: "checkmark")
}
}
}
}
}

Scrollview alignment

I have the following:
VStack(alignment: .leading) {
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 30) {
ForEach(0 ..< meals.count) { count in
HStack(alignment: .center,spacing: 120){
VStack{
Text("\(count + 1) ")
.foregroundColor(Color.black)
.padding(.horizontal, 8)
.padding(.vertical, 5)
.background(
Capsule()
.fill(Color.black)
.opacity(0.20)
)
}
VStack{
Text("\(self.meals[count]) ")
.foregroundColor(Color.black)
}
VStack{
Image(systemName: "pencil")
.foregroundColor(Color.black)
.font(.system(size: 20))
.background(Color.yellow)
}
}
}
}
.frame(width: UIScreen.main.bounds.width) // set a fixed width
// .background(Color.green)
}
.frame(height: 185)
.frame(maxWidth: 400)
.padding(.top, -200)
}
How can I make the pencil icon stay to the right? I tried putting alignment: .trailing on it but doesn't work.
I saw an example with geometry but then the scroll view gets weird, I need it with this. Also how can I make sure the width between the items stay the same across devices?
Instead of hardcoding spacing use Spacer() which like spring push subviews aside.
Note: You don't need VStack for only one subview, so it can be removed for simplicity.
Here is resulting row:
HStack { // .center is by default, so also remove
Text("\(count + 1) ")
.foregroundColor(Color.black)
.padding(.horizontal, 8)
.padding(.vertical, 5)
.background(
Capsule()
.fill(Color.black)
.opacity(0.20)
)
Spacer() // << here !!
Text("\(self.meals[count]) ")
.foregroundColor(Color.black)
Spacer() // << here !!
Image(systemName: "pencil")
.foregroundColor(Color.black)
.font(.system(size: 20))
.background(Color.yellow)
}