Why does ScrollView randomly push my views content downwards? - swift

Here is my code:
import SwiftUI
struct TrendingView : View {
#State var selectedTab: Tabs = .hot
#State private var searchText = ""
var body: some View {
NavigationView {
VStack {
HStack {
Text(" Trending")
.font(.largeTitle)
.frame(width: 175, height: 50, alignment: .leading)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(.black, lineWidth: 2)
)
.italic()
.fontWeight(.heavy)
.foregroundColor(Color(hue: 1.0, saturation: 0.977, brightness: 0.985))
.offset(x: -75, y: -25)
.padding(.bottom, -20)
NavigationLink(destination: testT()) {
Image(systemName: "magnifyingglass.circle.fill")
.resizable()
.scaledToFit()
.frame(width: 40, height: 40)
.foregroundColor(.black)
.padding(.bottom, -20)
}
.offset(x: 50, y: -25)
.padding(.leading, 5.0)
}
ScrollView {
VStack {
Text("Hot Items 🔥")
.bold()
.italic()
.offset(x: 5)
.frame(width: 120, height: 25, alignment: .leading)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(.black, lineWidth: 2)
)
.background(.yellow)
.offset(x: -130, y: 5)
ScrollView(.horizontal) {
HStack {
NavigationLink(destination: ImageTest()) {
Image("testpic1")
.resizable()
.frame(width: 200, height: 200)
}
NavigationLink(destination: ImageTest()) {
Image("testpic3")
.resizable()
.frame(width: 200, height: 200)
}
}.offset(y: 30)
}
}
}
There seems to be some error with scrollview above my vstack as it randomly causes all the content on this view to shift downwards when switching to and from other views.Ive tried removing the scrollview and the error disappears and also tried changing it around in other places but I still get the error Can anybody point me in the right direction? Thanks

Fixed, added to the bottom of my code and it seems like the issue is solved
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarHidden(true)

Related

SwiftUI - How to position Images with NavigationLink

I'm trying to make a converter app using SwiftUI. I added navigationlinks on the Home Screen these buttons go to the right places,no problem until here. However, I couldn't position it.
Currently, when I position them with .position, they appear in different places on different devices.
How should I do the positioning here?
I want to provide an image that will be the same on all devices as in the screenshot.
Thanks for your help.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
VStack() {
// WEIGHT * MASS
NavigationLink(destination: UnitView()) {
Image(systemName: "scalemass")
.font(.system(size: 60))
.padding()
.frame(width: 150, height: 150, alignment: .center)
.background(Rectangle().fill(Color.purple.opacity(0.5))
.shadow(radius: 3)).cornerRadius(20)
.foregroundColor(.black)
.overlay(Text("Mass")
.foregroundColor(.black)
.padding()
.font(.system(size: 22)),
alignment: .bottom )}
.position(x:110, y:100)
//DISTANCE *
NavigationLink(destination: DistanceView()) {
Image(systemName: "figure.walk")
.font(.system(size: 60))
.padding()
.frame(width: 150, height: 150, alignment: .center)
.background(Rectangle().fill(Color.orange.opacity(0.5))
.shadow(radius: 3)).cornerRadius(20)
.foregroundColor(.black)
.overlay(Text("Distance")
.foregroundColor(.black)
.padding()
.font(.system(size: 22)),
alignment: .bottom )}
.position(x:110, y:100)
//TEMPERATURE *
NavigationLink(destination: TemperatureView()) {
Image(systemName: "thermometer.sun")
.font(.system(size: 56))
.padding()
.frame(width: 150, height: 150, alignment: .center)
.background(Rectangle().fill(Color.yellow.opacity(0.5))
.shadow(radius: 3)).cornerRadius(20)
.foregroundColor(.black)
.overlay(Text("Temperature")
.foregroundColor(.black)
.padding()
.font(.system(size: 21)),
alignment: .bottom )}
.position(x:280, y:-84)
// TIME *
NavigationLink(destination: TimeView()) {
Image(systemName: "clock")
.font(.system(size: 60))
.padding()
.frame(width: 150, height: 150, alignment: .center)
.background(Rectangle().fill(Color.blue.opacity(0.5))
.shadow(radius: 3)).cornerRadius(20)
.foregroundColor(.black)
.overlay(Text("Time")
.foregroundColor(.black)
.padding()
.font(.system(size: 21)),
alignment: .bottom ) }
.position(x:280, y:-444)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sample
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Image("example-image")
.resizable()
.frame(width: 100, height: 100)
.cornerRadius(10)
NavigationLink(destination: DetailView()) {
Text("View Details")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
.padding(.top, 20)
}
}
}
}
struct DetailView: View {
var body: some View {
Text("Details View")
}
}
In this example, we use a VStack to position an image and a NavigationLink. The image is resized to 100x100 and given a corner radius of 10 using the frame and cornerRadius modifiers. The NavigationLink leads to a DetailView that simply displays the text "Details View". The text inside the NavigationLink is styled to have white foreground color, padding, a blue background color, and a corner radius of 10. The .padding(.top, 20) adds some space between the image and the link.

How to put an Image on top of a Color View in SwiftUI

I have an image that needs to be put in the top center of my view. How can I do so?
struct MyTextField: View
{
#ObservedObject var model: TextFieldModel
var body: some View
{
VStack(alignment: .leading, spacing: -60)
{
Color.black.position(CGPoint(x: 200, y: -50)).frame(width: 417, height: 120,
alignment: .top)
.background(Image(("appIconLogo")).resizable().frame(width: 50, height: 50))
//Spacer(minLength: 5)
VStack(alignment: .leading, spacing: 30)
{
Text("Welcome!")
.font(.system(size: 60, design: .rounded))
.foregroundColor(.black)
iTextField("Search Your Ticker", text: $model.text, isEditing: $model.isEditing)
.foregroundColor(.black)
.showsClearButton(true)
.onReturn
{
print($model.text)
NotificationCenter.default.post(name: Notification.Name(rawValue:
"isValidTicker"), object: nil)
}
.foregroundColor(.black)
.style(height: 58, font: nil, paddingLeading: 25, cornerRadius: 6,
hasShadow: true, image: Image(systemName: "magnifyingglass"))
.foregroundColor(.black)
}
}
.position(CGPoint(x: 200.0, y: 150.0))
.padding()
}
}
But my View looks like this. How can I move my image to the top center of the page where the black color is?
Here is a demo of possible layout. Prepared with Xcode 12.1 / iOS 14.1.
struct MyTextField: View
{
var body: some View
{
VStack {
Color.black
.frame(height: 120)
.overlay(Image(("plant")).resizable().frame(width: 50, height: 50))
.edgesIgnoringSafeArea(.top)
VStack(alignment: .leading, spacing: 30)
{
Text("Welcome!")
.font(.system(size: 60, design: .rounded))
.foregroundColor(.black)
.padding(.leading)
// .. other code
}.frame(maxWidth: .infinity, alignment: .leading)
}.frame(maxHeight: .infinity, alignment: .top)
}
}
It's a little confusing what you are trying to do in your code, but I think this might get you started. I made a background layer that extends to the edge of the screen, and then put a Content layer on top of it, where you can put the Image at the top of the VStack.
You should try to avoid setting exact width/height/CGPoints whenever possible in SwiftUI.
var body: some View {
ZStack {
// Background
Color.white
.edgesIgnoringSafeArea(.all)
// Content
VStack(spacing: 20) {
Image(systemName: "heart.fill") // Image here
Text("Welcome!") // Title
.font(.system(size: 60, design: .rounded))
.frame(maxWidth: .infinity, alignment: .leading)
.foregroundColor(.black)
TextField("Search your ticker", text: $textFieldText) // Textfield
.frame(height: 50)
.background(Color.gray)
.cornerRadius(10)
Spacer()
}
.padding()
}
}

SwiftUI unable to align button with topLeading

I have a button which I am unable to align to the top left with topLeading.
What I hope to accomplish:
my code:
var body: some View {
ZStack {
ZStack(alignment: .topLeading) {
Button(action: { self.show.toggle() }) {
HStack {
Spacer()
Image(systemName: "list.dash")
.foregroundColor(.black)
}
.padding(.trailing, 20)
.frame(width: 90, height: 60)
.background(Color.white)
.cornerRadius(30)
.shadow(color: Color("buttonShadow"), radius: 10, x: 0, y: 10)
}
Spacer()
}
}
}
But I get this:
The issue is that your wrapping views (two ZStacks) by default will take up only the space of their content, which is only the button. If you add a frame to allow the wrapper to expand you'll see the alignment working as you expect.
var body: some View {
ZStack {
ZStack {
Button(action: { self.show.toggle() }) {
HStack {
Spacer()
Image(systemName: "list.dash")
.foregroundColor(.black)
}
.padding(.trailing, 20)
.frame(width: 90, height: 60)
.background(Color.white)
.cornerRadius(30)
.shadow(color: Color.gray, radius: 10, x: 0, y: 10)
}
Spacer()
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: Alignment.topLeading
)
}
}
Add background space consumer, like below (tested with Xcode 11.4)
ZStack(alignment: .topLeading) {
Color.clear // << here !!
Button(action: { self.show.toggle() }) {

Align rectangle to be within certain distance of safe area bottom edge SWIFTUI

I am used to Interface Builder and layout constraints but now I want to convert my app to Swift UI. What I am trying to do right now is align the top edge of the view marked with a 1 to be within a certain distance of the safe area bottom edge (marked with a 2) so that the top edge that is now at 1 will then be at position 3. I tried using spacers but then it will look different on smaller devices such as an iPhone 8. In IB I could have used a simple layout constraint. How does this work in Swift UI? I have attached the relevant code and an image. Thank you for your help.
struct ContentView: View {
init() {
UINavigationBar.appearance().backgroundColor = .orange
}
var body: some View {
NavigationView {
VStack{
Spacer()
ZStack{
Rectangle()
.fill(Color(hue: 0, saturation: 0, brightness: 0, opacity: 0.1))
Image("")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100, height: 150)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
}.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width, alignment: .center)
Spacer(minLength: 100)
ZStack(alignment: .bottom){
ExtractedView()
.edgesIgnoringSafeArea(.bottom)
}
}
.navigationBarTitle(Text("You See"))
.navigationBarHidden(false)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewDevice("iPhone")
}
}
struct ExtractedView: View {
#State private var name: String = ""
var body: some View {
VStack{
ZStack(alignment: .top){
VStack{
RoundedRectangle(cornerRadius: 50)
.frame(width: 60, height: 7)
.padding(.top)
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/) {
Text("Start advertising")
.font(.headline)
.foregroundColor(Color.black)
}.padding(.top)
TextField("Test", text: $name)
.padding(.all)
.background(Color.white.cornerRadius(20))
.padding()
}
RoundedRectangle(cornerRadius: 30)
.fill(Color(hue: 0, saturation: 0, brightness: 0, opacity: 0.1))
.zIndex(-5)
}
}
}
}
Ok, so I was able to solve my problem. The trick is to create two VStacks with different frame alignments. The outer VStack has top alignment so that the Discover view can be at the top. The inner VStack has a bottom alignment so that the sheet can be pulled up from the bottom. Space will be filled from the bottom up in this case.
VStack{
Discover()
.padding(.top, 60.0)
VStack{
Text("Recent Messages:")
.font(.headline)
DetailSheet()
.offset(x: 0, y: 0)
}.frame(width: g.size.width, height: (g.size.height - g.size.width - 80 + 200), alignment: .bottom)
}
.frame(width: g.size.width, height: g.size.height, alignment: .top)
you can try this:
offset -10 is just your offset you want to have....
i hope i understood you right, i am not so sure...
var body: some View {
VStack{
// ZStack(alignment: .top){
VStack{
RoundedRectangle(cornerRadius: 50)
.frame(width: 60, height: 7)
.padding(.top)
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/) {
Text("Start advertising")
.font(.headline)
.foregroundColor(Color.black)
}.padding(.top)
TextField("Test", text: $name)
.padding(.all)
.background(Color.white.cornerRadius(20))
.padding()
}.background(RoundedRectangle(cornerRadius: 30)
.fill(Color(hue: 0, saturation: 0, brightness: 0, opacity: 0.1))
).offset(y:-10)
}
// }

SwiftUi bottom left button dont show

I have some SwiftUI function. I want to show my button in bottom left, but it shows top left.
struct NewRecordButton: View {
var body: some View {
ZStack (alignment: .bottomTrailing) {
HStack (alignment: .bottom) {
Spacer()
Button(action: { },
label: {
Text("⌂")
.font(.system(.largeTitle))
.frame(width: 35, height: 30)
.foregroundColor(Color.white)
.padding(.bottom,4)
}) .background(Color.black)
.cornerRadius(10)
.shadow(color: Color.black.opacity(0.3),
radius: 3,
x: 3,
y: 3)
}
}
}
}
Any ideas?
Here is possible variant
ZStack (alignment: .bottomTrailing) {
Rectangle().fill(Color.clear)
HStack (alignment: .bottom){
Button(action: {
}, label: {
Text("⌂")
.font(.system(.largeTitle))
.frame(width: 35, height: 30)
.foregroundColor(Color.white)
.padding(.bottom,4)
})
.background(Color.black)
.cornerRadius(10)
.shadow(color: Color.black.opacity(0.3),
radius: 3,
x: 3,
y: 3)
Spacer()
}
}
Although it's possible, but you should try NOT to use dummy views to arrange other views!
For pushing a view down, you should use a VStack and a Spacer together
VStack {
Spacer()
// bottomView
}
So it should be like:
ZStack {
VStack {
Spacer() // This will push it down, since it is in a `VStack`
HStack {
Button("⌂") {}
.font(.largeTitle)
.frame(width: 35, height: 30)
.foregroundColor(.white)
.padding(.bottom, 4)
.background(Color.black)
.cornerRadius(10)
.shadow(color: Color.black.opacity(0.3), radius: 3, x: 3, y: 3)
Spacer() // This will push it left, since it is in a `HStack`
}
}
}