Show part of next item in TabView - swiftui

I want to show part of next item in tabview as following design
I managed to show one item per page but I couldn't show part of next one. Here's my code
GeometryReader { proxy in
TabView(selection: $viewModel.selectedTabIndex) {
ForEach(self.viewModel.data?.perspective ?? []) { item in
HStack(spacing: 20) {
Image("icon")
.resizable()
.scaledToFit()
.frame(width: 24, height: 24, alignment: .center)
Text(item.name)
.font(.system(size: 16, weight: .medium))
.foregroundColor(Color.white)
.tag(item.id)
Spacer()
}
.frame(width: proxy.size.width - 70, height: 40, alignment: .center)
.padding(.horizontal)
.background(.red)
.cornerRadius(5)
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
}
.frame(height: 40, alignment: .center)

Related

SWIFTUI : Wide space appear on top as switch between tabs

Basically, I am working on a project in which there is a navigation process, therefore, I have to implement navigationview with tabview. As app loads, initial screen appear(homeview) normal, but an issue arises as soon I switch between tab option, wide space appears. So can anyone guide me in it? I am adding code with this query.
Even I have tried to add navigationView on individual tabitem and on it wide space issue gets resolve but new issue appear that tabbar doesnot hides on navigationlink even i have implemented "uitabbar.appearance.ishidden = true" on respective view
'''
import SwiftUI
struct TabBarView: View {
#State private var selection = 0
var body: some View {
NavigationView{
TabView(selection: $selection) {
HomeView()
.tabItem {
Image("tab_icon1")
.resizable()
.frame(width: 10, height: 10, alignment: .center)
}
.tag(0)
// Text("Search Tab")
SettingView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon2")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(1)
//tab_new
// Text("New Tab")
ActivityListView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_new")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(2)
HomeView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon3")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(3)
Text("Profile Tab")
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon4")
.resizable()
.frame(width: 50, height: 50, alignment: .center)
}
.tag(4)
}
.edgesIgnoringSafeArea(.top)
.accentColor(Color("Pink"))
.onAppear() {
UITabBar.appearance().barTintColor = UIColor(named: "DarkGray")
UITabBar.appearance().backgroundColor = UIColor(named: "DarkGray")
}
//
}
}
}
'''

ScrollView text alignment SwiftUI

I have a vertical ScrollView with a ForEach loop that has HStack's inside with Text, Image, and Two Text's. I'd like to keep each row's items in alignment with each other. I've attempted to wrap in a VStack with alignment .leading but did nothing. The issue I'm having is the text doesn't line up. Still very new to SwiftUI so any help would be appreciated.
ScrollView(.vertical) {
ForEach(self.daily.forecast, id: \.date) { forecast in
HStack (spacing : 10){
Text(forecast.date ?? "")
.fontWeight(.bold)
Spacer()
RequestImage(Url("IMAGE_URL"))
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30)
.clipped()
Spacer()
Text("\(forecast.maxTemp)")
.fontWeight(.bold)
Text("\(forecast.minTemp)")
.fontWeight(.bold)
}
}
}
.padding(.all, 15)
.onAppear() {
authorize {_ in
loadForecast()
}
}
UPDATED:
I was able to get a bit closer but things still aren't aligned to where I'd like them to be.
ScrollView(.vertical) {
ForEach(self.daily.forecast, id: \.date) { forecast in
HStack (spacing : 10){
Text(date)
.font(.title3)
.fontWeight(.bold)
.frame(minWidth: 45)
Spacer()
RequestImage(Url("IMAGE_URL"))
.aspectRatio(contentMode: .fit)
.frame(width: 35, height: 35)
.frame(minWidth: 50)
.clipped()
Spacer()
Text(maxTemp)
.font(.title3)
.fontWeight(.bold)
.frame(minWidth: 45)
Text(minTemp)
.font(.title3)
.fontWeight(.bold)
.foregroundColor(Color.secondary)
.frame(minWidth: 45)
}
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
}
}
.padding(.all, 15)
.onAppear() {
authorize {_ in
loadForecast()
}
}
Here is a demo of possible solution. Prepared with Xcode 12.4 / iOS 14.4
struct DemoWeatherLayout: View {
private var dayOfTheWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sut"]
var body: some View {
ScrollView {
VStack {
ForEach(dayOfTheWeek, id: \.self) {
WeatherRowView(day: $0,
icon: ["sun.max", "cloud.sun", "cloud", "cloud.snow"].randomElement()!,
low: Array(-5..<0).randomElement()!,
high: Array(1..<15).randomElement()!)
}
}.padding()
}
}
}
struct WeatherRowView: View {
var day: String
var icon: String
var low: Int
var high: Int
var body: some View {
HStack {
Text(day)
.frame(maxWidth: .infinity, alignment: .leading)
Image(systemName: icon)
.frame(maxWidth: .infinity, alignment: .leading)
HStack {
Text("+XXº").foregroundColor(.clear)
.overlay(Text(String(format: "%+d", low)), alignment: .leading)
Text("+XXº").foregroundColor(.clear)
.overlay(Text(String(format: "%+d", high)), alignment: .leading)
}
}
}
}
Three suggestions:
add alignment parameter to HStack:
HStack(alignment: .lastTextBaseline, spacing: 10) { ... //others options: .top, .center, .firstTextBaseline...
Add minLength parameter to Spacer:
Spacer(minLength: 0) but with spacing: 10 in HStack it is a bit redundant. You can remove spacing: 10 for Spacer(minLength: 10)
Add a Spacer(minLength: 0) at the end after Text("\(forecast.minTemp)").fontWeight(.bold)
I'm going to accept #Asperi answer as correct. The UI has indeed changed since to better fit said labels etc. Appreciate everyone's else. The code is very much ugly but works. Not sure if it's 100% correct.
HStack (spacing: 10){
Text(date)
.font(.title3)
.fontWeight(.bold)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
Spacer()
RequestImage(Url("IMAGE_URL_HERE"))
.aspectRatio(contentMode: .fit)
.frame(width: 35, height: 35)
.frame(minWidth: 55)
.clipped()
Spacer()
Text(maxTemp)
.font(.title3)
.fontWeight(.bold)
.frame(minWidth: 50)
.background(Color.orange)
.cornerRadius(5)
Text(minTemp)
.font(.title3)
.fontWeight(.bold)
.frame(minWidth: 50)
.background(Color.blue)
.cornerRadius(5)
}

VStack .leading alignment

I can't get rid of this "leading" padding inside one of my VStacks.
I set alignment to "leading" for its parent VStack but it still shows some spacing on the left (for the text and red rounded rectangle). They were supposed to be placed on the left next to the blue edge on screenshot.
Any ideas on why this padding appears there?
Here's the code:
import SwiftUI
struct RegisterView: View {
var body: some View {
VStack(spacing: 0) {
HStack(alignment: .top) {
Text("Register")
.font(.custom("NotoSans-Regular", size: 24))
.fontWeight(.bold)
.foregroundColor(Color.tertiaryTitleColor)
}
.frame(width: 299, height: 39)
.padding(.top, 78)
HStack(spacing: 13) {
BroviderButton(imageName: "googleLogo")
BroviderButton(imageName: "facebookLogo")
}
.padding(.top, 47)
VStack(alignment: .leading, spacing: 0) {
Text("Register with E-mail")
.font(.custom("NotoSans-Regular", size: 16))
RoundedRectangle(cornerRadius: 25)
.fill(Color.red)
.frame(width: 40, height: 20)
}
.frame(width: 279)
.padding(.top, 61)
Spacer()
}
.frame(maxHeight: /*#START_MENU_TOKEN#*/.infinity/*#END_MENU_TOKEN#*/)
.frame(maxWidth: /*#START_MENU_TOKEN#*/.infinity/*#END_MENU_TOKEN#*/)
.background(Color.loginBackgroundColor)
.ignoresSafeArea()
}
}
struct RegisterView_Previews: PreviewProvider {
static var previews: some View {
RegisterView()
}
}
struct BroviderButton: View {
var imageName: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 27.5)
.frame(width: 133, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.shadow(color: Color.dropShadowColor, radius: 1, x: 10, y: 20)
.offset(y: 15)
.opacity(0.2)
.blur(radius: 20)
.opacity(0.2)
VStack {
VStack {
Image(imageName)
.resizable()
.scaledToFit()
}
.frame(height: 28, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
}
.frame(width: 133, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.foregroundColor(/*#START_MENU_TOKEN#*/.blue/*#END_MENU_TOKEN#*/)
.background(Color.loginBackgroundColor)
.cornerRadius(27.5)
.opacity(1)
}
}
}
You need also apply alignment to frame of container, like
VStack(alignment: .leading, spacing: 0) {
Text("Register with E-mail")
.font(.custom("NotoSans-Regular", size: 16))
RoundedRectangle(cornerRadius: 25)
.fill(Color.red)
.frame(width: 40, height: 20)
}
.frame(width: 279) // << do you really need this? why?
.frame(maxWidth: .infinity, alignment: .leading) // << here !!
.padding(.top, 61)

SwiftUI Two Row NavigationBar

Is there a way using SwiftUI to get a two row NavigationBar like instagram has? Even better would be two rows with a fullwidth search bar like in the image.
ex.
Here you go an example close to the image, of course it can be redesigned to suit your needs I did it very quickly it doesn't look nice, but as I said it can be redesigned to look much nicer:
#State var testok = ""
var body: some View {
VStack {
VStack {
TextField("search here man", text: $testok)
.frame(maxWidth: .infinity)
.frame(height: 40)
.background(Color.red)
.cornerRadius(10)
.padding()
ScrollView(.horizontal){
HStack(spacing: 0) {
Text("ok")
.frame(width: 80, height: 50)
.background(Color.green)
.cornerRadius(8)
.padding(.horizontal, 10)
Text("yumyum")
.frame(width: 80, height: 50)
.background(Color.green)
.cornerRadius(8)
.padding(.horizontal, 10)
Text("lool")
.frame(width: 80, height: 50)
.background(Color.green)
.cornerRadius(8)
.padding(.horizontal, 10)
Text("pewpew")
.frame(width: 80, height: 50)
.background(Color.green)
.cornerRadius(8)
.padding(.horizontal, 10)
}
}
}
NavigationView {
NavigationLink(destination: Text("ok")) {
Text("ok")
.navigationTitle(Text("navigation title"))
}
}
}
}

SwiftUI: How to restrict view to only resizing in one direction?

How can I restrict the view to resize only downwards?
I am trying to add more buttons & have the view resize to accommodate the buttons without overlapping the red rectangle above.
This is the code I am currently using:
struct ContentView: View {
var body: some View {
VStack{
RoundedRectangle(cornerRadius: 20)
.frame(width: .infinity, height: 55)
.foregroundColor(.red)
HStack{
Spacer()
ZStack{
RoundedRectangle(cornerRadius: 20)
.foregroundColor(.green)
VStack{
Button(action: {}) {
Text("Test Button")
.foregroundColor(.white)
.font(.headline)
.frame(width: .infinity)
Spacer()
}.padding()
Button(action: {}) {
Text("Test Button")
.foregroundColor(.white)
.font(.headline)
.frame(width: .infinity)
Spacer()
}.padding()
Button(action: {}) {
Text("Test Button")
.foregroundColor(.white)
.font(.headline)
.frame(width: .infinity)
Spacer()
}.padding()
}
}.frame(width: 250, height: 100)
}
Spacer()
}
}
}
Change your .frame(width: 250, height: 100) to .frame(width: 250, height: 100, alignment: .top) Your original example defaults to .center, which is why it expands into the red rectangle.