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

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.

Related

Pagination is not working on LazyVGrid layout but without LazyVGrid the pagination is working properly. How can i fix this?

Pagination is not working on LazyVGrid layout, but without LazyVGrid the pagination is working properly. I really need to use LazyVGrid for my list. How can I fix this?
My code
VStack(alignment: .center) {
List {
LazyVGrid(columns: gridItemLayout, spacing: 20) {
ForEach(viewModel.tvShowList, id: \.id) { tvShow in
VStack {
KFImage.url(URL(string: Constant.POSTER_URL + tvShow.posterPath)!)
.placeholder {
Image("placeholder")
.scaledToFill()
.frame(width: 160, height: 100, alignment: .center)
.clipped()
}
.resizable()
.shadow(radius: 10)
.padding(.trailing, 20)
.scaledToFit()
.frame(width: 160, alignment: .center)
Text("\(tvShow.name)")
.multilineTextAlignment(.center)
.lineLimit(1)
.frame(maxWidth: .infinity)
.font(.system(size: 14))
.font(.headline)
}
.listRowBackground(Color.white)
.listRowSeparator(.hidden)
}
.id(UUID())
.frame(maxWidth: .infinity)
if (viewModel.page < viewModel.totalPage) {
HStack {
Spacer()
ProgressView()
.onAppear {
viewModel.page += 1
viewModel.getTvShowTopRated()
}
Spacer()
}
}
}
}
.listStyle(GroupedListStyle())
.padding([.leading, .trailing], 15) }

Autolayout in SwiftUI

Good afternoon community,
Any way to autolayout in swiftui so that my view looks good both in portrait and landscape?
I've already tried everything with geometry render and frame (.infinity) but I can't get it.
someone who has managed to be able to have his ap in both modes with swuftui?
I attach my code and a couple of images.
import SwiftUI
struct OnBoardingView: View {
var ImageOnTop:some View{
Image("headerPicture")
.resizable()
}
var Title:some View {
Text("Hey You")
.font(.custom("Montserrat-Medium", size: 48))
.foregroundColor(.white)
}
var subTitle:some View{
Text("Out With A Porpuse ")
.font(.custom("Montserrat-SemiBold", size: 16))
.foregroundColor(.white)
}
var secondSubtitle:some View{
Text("Find and build communities with people in your area. \n #GoodbyeCatfish \n #HellowConnections")
.font(.custom("Montserrat-Regular", size: 16))
.foregroundColor(.white)
.multilineTextAlignment(.center)
}
var navigatinButton:some View{
VStack(alignment:.center){
NavigationLink(
destination: CreateAccountView(),
label: {
Text("Create Account")
})
.font(.custom("Montserrat-Medium", size: 18))
.foregroundColor(.white)
.frame(width: 230, height: 42, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 18)
.stroke(Color.yellow, lineWidth: 1.8))
HStack{
Text("Already have an account?")
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.white)
.multilineTextAlignment(.leading)
NavigationLink(
destination: LoginView(LoginViewM: LoginViewModel()),
label: {
Text("Log In")
})
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.yellow)
}
}
}
var lastString: some View{
HStack{
Text("By using this app you agree with the")
.foregroundColor(.white)
.font(.custom("Montserrat-Medium", size: 11))
Text("terms of services")
.underline(true, color: .yellow)
.foregroundColor(.yellow)
.font(.custom("Montserrat-Medium", size: 11))
}
.padding(30)
}
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack(spacing:40){
VStack(alignment: .center,spacing:15){
ImageOnTop
.frame(width: geometry.size.width, height: 270)
Title
subTitle
}
.frame(width: geometry.size.width, height: 270)
secondSubtitle
.frame(width: geometry.size.width, height: 75, alignment: .center)
.padding(30)
navigatinButton
Spacer(minLength: 14)
lastString
Spacer().frame(height:20)
}
.edgesIgnoringSafeArea(.all)
.background(Color.black)
}
.frame(width: geometry.size.width, height: geometry.size.height)
.navigationBarBackButtonHidden(true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
OnBoardingView()
.previewDevice(PreviewDevice(rawValue: "iPhone 12"))
.previewDisplayName("iPhone 12")
}
}
Here is a version of your code that works for all screen sizes and positions. Less is more in SwiftUI. The more the hardcoded values the harder it is for SwiftUI to do the adjusting.
struct OnBoardingView: View {
var ImageOnTop:some View{
//Just to simulate,I switched to a system image you will have to adjust for your own
Image(systemName: "square")
.resizable()
.foregroundColor(.blue)
}
var Title:some View {
Text("Hey You")
.font(.custom("Montserrat-Medium", size: 48))
.foregroundColor(.white)
}
var subTitle:some View{
Text("Out With A Porpuse ")
.font(.custom("Montserrat-SemiBold", size: 16))
.foregroundColor(.white)
}
var secondSubtitle:some View{
VStack{
Text("Find and build communities with people in your area.")
.lineLimit(1)
Text("#GoodbyeCatfish \n #HellowConnections")
}
.font(.custom("Montserrat-Regular", size: 16))
.foregroundColor(.white)
.multilineTextAlignment(.center)
.minimumScaleFactor(0.5)
}
var navigatinButton:some View{
VStack(alignment:.center){
NavigationLink(
destination: Text("CreateAccountView()"),
label: {
Text("Create Account")
})
.font(.custom("Montserrat-Medium", size: 18))
.foregroundColor(.white)
//Don't fix the size or thre won't be any differences between devices
.frame(minWidth: 0, idealWidth: 230, maxWidth: 230, minHeight: 0, idealHeight: 42, maxHeight: 42, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 18)
.stroke(Color.yellow, lineWidth: 1.8))
HStack{
Text("Already have an account?")
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.white)
.multilineTextAlignment(.leading)
NavigationLink(
destination: Text("LoginView(LoginViewM: LoginViewModel()"),
label: {
Text("Log In")
})
.font(.custom("Montserrat-Regular", size: 12))
.foregroundColor(.yellow)
}
}
}
var lastString: some View{
HStack{
Text("By using this app you agree with the")
.foregroundColor(.white)
.font(.custom("Montserrat-Medium", size: 11))
Text("terms of services")
.underline(true, color: .yellow)
.foregroundColor(.yellow)
.font(.custom("Montserrat-Medium", size: 11))
}
.padding(30)
}
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack{
ImageOnTop
.frame(height: geometry.size.height * 0.2)
VStack{
Title
subTitle
}.frame(height: geometry.size.height * 0.25)
Spacer()
secondSubtitle
//You can give spaces more weight by addign spacers
//This makes the space above the button twice as wide as the bottom
Spacer()
Spacer()
navigatinButton
Spacer()
lastString
}
.background(Color.black)
.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
}
.navigationBarBackButtonHidden(true)
}
}
}

Make Text inside VStack take the whole width of the VStack

I'm trying to make two Text that are inside a VStack to take the whole width of the parent (the VStack).
I'm completely out of ideas.
This is what I have:
var body: some View {
VStack(alignment: .center, spacing: 0) {
Image("image")
.resizable()
.scaledToFill()
.frame(height: 190)
.clipped()
VStack(alignment: .leading, spacing: 8) {
Text(title)
.font(.title)
.background(Color.red)
.fixedSize(horizontal: false, vertical: true)
Text(subtitle)
.font(.subheadline)
.background(Color.yellow)
.fixedSize(horizontal: false, vertical: true)
}
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.green)
.padding(.top, 24)
.padding(.horizontal, 24)
Button(buttonTitle) { print("Something") }
.frame(maxWidth: .infinity, minHeight: 56)
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(56/2)
.padding(.top, 32)
.padding(.horizontal, 24)
.padding(.bottom, 20.0)
}.background(Color.blue)
.cornerRadius(38)
.frame(minWidth: 0, maxWidth: UIScreen.main.bounds.size.width - 48)
}
And this is how it looks:
I want the red and the yellow label to take the full width of the green VStack.
How can I achieve that?!
Remove the .fixedSize on both Text
Add .frame(minWidth: 0, maxWidth: .infinity) instead
In SwiftUI, it also matters the order of things, so you'll want to add the .background to after the .frame
Final result would be:
Text("title")
.font(.title)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.red)
To instead make it left aligned:
HStack {
Text("title")
.font(.title)
Spacer(minLength: 0)
}
.background(Color.red)
Here is possible solution
VStack(alignment: .leading, spacing: 8) {
Text(title)
.font(.title)
.frame(maxWidth: .infinity) // << here
.background(Color.red)
.fixedSize(horizontal: false, vertical: true)
Text(subtitle)
.font(.subheadline)
.frame(maxWidth: .infinity) // << here
.background(Color.yellow)
.fixedSize(horizontal: false, vertical: true)
}
.frame(maxWidth: .infinity) // << here

The leading alignment doesn't apply to the text SwiftUI

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)
}
}

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)
}