I want to have a full screen image in the background. I have implemented this:
struct LoginView: View {
var body: some View {
VStack {
Spacer();
Text("Hallo");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Spacer();
}.background(Image("Background LaunchScreen")
.resizable()
.aspectRatio(UIImage(named: "Background LaunchScreen")!.size, contentMode: .fill)
.clipped())
.edgesIgnoringSafeArea(.all)
}
}
When I remove the spacers, the image is no longer displayed in full screen mode.
Surely that can be solved differently?
And if I turn the iPhone in the simulator to the side, I have left and right white stripes.
How can I change this?
Here's a possible solution using GeometryReader and ZStack:
import SwiftUI
struct LoginView: View {
var body: some View {
GeometryReader { geometry in
ZStack {
Image("LaunchImage")
.resizable()
.aspectRatio(geometry.size, contentMode: .fill)
.edgesIgnoringSafeArea(.all)
VStack {
ForEach (1...10, id: \.self) { _ in
Text("Hallo")
.foregroundColor(Color.white)
}
}
}
}
}
}
#if DEBUG
struct LoginView_Previews: PreviewProvider {
static var previews: some View {
LoginView()
}
}
#endif
Results
Related
I have a problem trying to determine the height of a view inside a ScrollView
struct ContentView: View {
var body: some View {
ScrollView{
GeometryReader { geometry in
VStack{
ForEach(0..<90) { index in
Text("test \(geometry.size.height)")
}
}
}
}
}
}
geometry.size.height is always 10.000.
how can i correct this unexpected result?
Thanks so much!
I'm not sure where you're going with this.
GeometryReader reads the size offered to the view, not the size of the view. You can find out how big the view is by putting a GeometryReader in an .overlay of the VStack, because by the time the overlay is created, the size of the VStack will have been established and that size will be offered to the overlay.
struct ContentView: View {
var body: some View {
ScrollView{
VStack{
ForEach(0..<90) { index in
Text("test 000000000000")
.opacity(0)
}
}
.overlay(
GeometryReader { geometry in
VStack {
ForEach(0..<90) { index in
Text("test \(geometry.size.height)")
}
}
}
)
}
}
}
I have a problem related on my List view. The question is simple: how can I get rid of that wierd gray rectangle showing on top of the TabBar? I didn't code that, I just implemented a controller with a List and NavigationBar and then it showed that thing.
For more clear explanation I post the images:
ItemRow.swift code:
import SwiftUI
struct ItemRow: View {
static let colors: [String: Color] = ["D": .purple, "G": .orange, "N": .red, "S": .yellow, "V": .pink]
var item: MenuItem
var body: some View {
NavigationLink(destination: Text(item.name)) {
HStack {
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle().stroke(Color("IkeaBlu"), lineWidth: 2))
VStack(alignment: .leading){
Text(item.name)
.font(.headline)
Text("€ \(item.price)")
}.layoutPriority(1)
Spacer()
ForEach(item.restrictions, id: \.self) { restriction in
Text(restriction)
.font(.caption)
.fontWeight(.black)
.padding(5)
.background(Self.colors[restriction, default: .black])
.clipShape(Circle())
.foregroundColor(.white)
}
}
}
}
}
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow(item: MenuItem.example)
}
}
thanks a lot for the help
Remove the marked part of hack from TabBar view and that glitch will go.
Tested with Xcode 11.4 / iOS 13.4
} .onAppear {
// UITabBar.appearance().isTranslucent = false // << this one !!
UITabBar.appearance().barTintColor = UIColor(named: "IkeaBlu")
}.accentColor(Color(.white))
I have a view sitting on top of a mapView (in a ZStack) and want to be able to have the green, upper view fade in and out with the .easeInOut animation modifier applied to the view's opacity. As you can see in the gif, it fades in nicely but disappears abruptly.
If I remove the mapView then all is good. If I replace the mapView with a simple Rectangle() then the problem returns so I believe it has something to do with the ZStack rather than the map. Funnily enough I'm actually using Mapbox rather than MapKit (as in the code below for simplicity) and the fade/abrupt disappear behaviour is reversed.
import SwiftUI
import MapKit
struct ContentView: View {
#State private var show = false
var body: some View {
VStack {
ZStack {
MapView()
if show {
LabelView()
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
}
}
Button("Animate") {
self.show.toggle()
}.padding(20)
}
}
}
struct MapView: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.mapType = .standard
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) { }
}
struct LabelView: View {
var body: some View {
Text("Hi there!")
.padding(10)
.font(.title)
.foregroundColor(.white)
.background(RoundedRectangle(cornerRadius: 8).fill(Color.green).shadow(color: .gray, radius: 3))
}
}
I have tried using alternative animation code, replacing the LabelView transition with:
.transition(.opacity)
and changing the button code to:
Button("Animate") {
withAnimation(.easeInOut(duration: 1.0)) {
self.show.toggle()
}
}
but the same behaviour appears each time. I'm guessing this is a SwiftUI bug but couldn't find any previous reference.
Here is working solution. Tested with Xcode 11.4 / iOS 13.4.
As it seen in demo presence of transparent label does not affect functionality of map view.
var body: some View {
VStack {
ZStack {
MapView()
LabelView().opacity(show ? 1 : 0) // here !!
}.animation(.easeInOut(duration: 1.0))
Button("Animate") {
self.show.toggle()
}.padding(20)
}
}
Another alternate, actually with the same visual effect is to embed LabelView into container and apply transition to it (it must be left something to render view disappearing)
var body: some View {
VStack {
ZStack {
MapView()
VStack { // << here !!
if show {
LabelView()
}
}.transition(.opacity).animation(.easeInOut(duration: 1.0))
}
Button("Animate") {
self.show.toggle()
}.padding(20)
}
}
try this: -> just added zIndex ...everything else the same
struct ContentView: View {
#State private var show = false
var body: some View {
VStack {
ZStack {
MapView().zIndex(0)
if show {
LabelView()
.zIndex(1)
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
}
}
Button("Animate") {
self.show.toggle()
}.padding(20)
}
}
}
and read this:
Transition animation not working in SwiftUI
I want to display a label in the centre of a view with a progress indicator to the right of the label. How can I do this in SwiftUI on macOS?
The code below aligns the HStack in the centre of the VStack but I want the text centered and the progress indicator aligned with the text's trailing edge. I guess I could replace the HStack with a ZStack but it's still not clear how one aligns two controls to each other or how one prevents the container from be centered by its container.
import SwiftUI
struct AlignmentTestView: View {
var body: some View {
VStack(alignment: .center, spacing: 4) {
HStack {
Text("Some text")
ActivityIndicator()
}
}.frame(width: 200, height: 200)
.background(Color.pink)
}
}
struct AlignmentTestView_Previews: PreviewProvider {
static var previews: some View {
AlignmentTestView()
}
}
Here is possible approach (tested replacing ActivityIndicator with just circle).
Used Xcode 11.4 / iOS 13.4 / macOS 10.15.4
var body: some View {
VStack {
HStack {
Text("Some text")
.alignmentGuide(.hAlignment) { $0.width / 2.0 }
ActivityIndicator()
}
}
.frame(width: 200, height: 200, alignment:
Alignment(horizontal: .hAlignment, vertical: VerticalAlignment.center))
.background(Color.pink)
}
extension HorizontalAlignment {
private enum HAlignment : AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[HorizontalAlignment.center]
}
}
static let hAlignment = HorizontalAlignment(HAlignment.self)
}
I’m creating an app where I have create first screen (it will be short description of application) and on the screen I have a next Button if I click on next button it should be dismiss otherwise it must not be dismiss either pull down.
If user pull down a sheet, it should be again re-position.
The problem is, that the user can dismiss the modal by swiping it down and application dashboard screen show that should be prevented.
How can we prevent to dismiss the Model by pull down.
struct ModalView : View {
#Environment(\.presentationMode) var presentationMode
var body: some View {
Rectangle()
.fill(Color.orange)
.frame(width: 400, height: 650)
.overlay(
VStack{
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
Text("Dismiss")
}.padding(10.0)
.overlay(
RoundedRectangle(cornerRadius: 10.0)
.stroke(lineWidth: 2.0)
)
}.accentColor(.white)
})
.border(Color.blue)
.gesture( DragGesture())
}
}
ContentView
struct ContentView: View {
//MARK: Properties
//isPresented:- Present's a Welcome Screen in the form of cards.
#State private var isPresented = true
var body: some View {
VStack{
DashboardView()
.sheet(isPresented: $isPresented){
//IntroductionView(isPresentingSheet: self.$isPresented)
ModalView()
}
}
}
}
DashboardView
struct DashboardView: View {
var body: some View {
Text("Hello SwiftUI")
}
}
You can try this solution:
struct ModalWrapper: View {
var body: some View {
ModalView().highPriorityGesture(DragGesture())
}
}
struct ModalView : View {
#Environment(\.presentationMode) var presentationMode
var body: some View {
Rectangle()
.fill(Color.orange)
.frame(width: 400, height: 650)
.overlay(
VStack{
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
Text("Dismiss")
}.padding(10.0)
.overlay(
RoundedRectangle(cornerRadius: 10.0)
.stroke(lineWidth: 2.0)
)
}.accentColor(.white)
})
.border(Color.blue)
.highPriorityGesture(DragGesture())
}
}
struct ContentView: View {
//MARK: Properties
//isPresented:- Present's a Welcome Screen in the form of cards.
#State private var isPresented = true
var body: some View {
VStack{
DashboardView()
.sheet(isPresented: $isPresented){
//IntroductionView(isPresentingSheet: self.$isPresented)
ModalWrapper()
}
}
}
}
struct DashboardView: View {
var body: some View {
Text("Hello SwiftUI")
}
}
Here I have added ModalWrapper for wrap the modal view Or else you will have to add highPriorityGesture(DragGesture()) to all subviews of the ModalView So it is better to keep one wrapper view.
Hope this will help you.