Sheet Modal does not present whole View in SwiftUI - swift

I am pretty new to SwiftUI programming and ran into the following problem that I cannot find an answer to.
I want to open a sheet modal from my Main View and want to present a simple View with an Rect on it (for testing purposes).
.sheet(isPresented: $api.showDrawing) {
DrawingViewView()
}
My DrawingViewView looks like:
struct DrawingViewView: View {
var body: some View {
Rectangle()
.fill(Color.red)
.frame(width: 1500, height: 1000)
}
}
No matter how big I make the Rect it is never shown bigger than:
Is there a way to make the sheet bigger in width?
EDIT:
I also thought of using a fullScreenCover, but if I open a PKCanvasView in a fullScreenCover pencilKit is acting weird. The lines I draw do not correspond with the pencilInput
EDIT: Apperently the problem is the horizontal orientation. If I turn my iPad vertical I have no problems at all!
Thanks a lot!
Jakob

I think this is the easiest way to do it.
import SwiftUI
struct FullScreenModalView: View {
#Environment(\.presentationMode) var presentationMode
var body: some View {
ZStack {
Color.red.edgesIgnoringSafeArea(.all)
Button("Dismiss Modal") {
presentationMode.wrappedValue.dismiss()
}
}
}
}
struct ContentView: View {
#State private var isPresented = false
var body: some View {
Button("Present!") {
isPresented.toggle()
}
.fullScreenCover(isPresented: $isPresented, content: FullScreenModalView.init)
}
}
struct ex_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Hope is what you expected!

Related

Show DisclosureGroup view based on state

I'm fairly new to SwiftUI, and I'm having trouble wrapping my head around the following issue I ran into. I have a button which toggles a state property, and I'd like to display a DisclosureGroup when the button's state is toggle on. For some reason, I can display any sort of view with my code below, with the exception of a DisclosureGroup:
#Binding var showing : Bool
#Binding var revealDetails : Bool
var body: some View {
if showing {
VStack {
DisclosureGroup("Monday", isExpanded: $revealDetails){
Text("7PM - 10PM").frame(height: 100)
}
.frame(width: 150)
.buttonStyle(PlainButtonStyle()).accentColor(.black)
}
}
}
}
The above code does not work when I present in my ContentView, however, the strange thing is, if I add some sort of empty view above the DisclosureGroup, it does work. So for now, I'm including a Text("") inside the VStack. Any thoughts on why this is?
I think you're not passing correct values to your bindings, i can tell you clearly after seeing your code in ContentView as you haven't attached it in the question but you can copy paste below code and customise it depending on your needs.
ContentView
import SwiftUI
struct ContentView: View {
// MARK: - PROPERTIES
#State private var showDiscloureGroup = false
#State private var showDetails = false
// MARK: - BODY
var body: some View {
VStack{
Toggle("Show Disclosure Group", isOn: $showDiscloureGroup)
Toggle("Show Details", isOn: $showDetails)
MyDiscloureGroup(showing: $showDiscloureGroup, revealDetails: $showDetails)
}//: VSTACK
.padding()
}
}
// MARK: - PREVIEW
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
MyDiscloureGroupView
import SwiftUI
struct MyDiscloureGroupView: View {
#Binding var showing : Bool
#Binding var revealDetails : Bool
var body: some View {
if showing {
VStack {
DisclosureGroup("Monday", isExpanded: $revealDetails){
Text("7PM - 10PM").frame(height: 100)
}
.frame(width: 150)
.buttonStyle(PlainButtonStyle()).accentColor(.black)
}
}
}
}
struct MyDiscloureGroup_Previews: PreviewProvider {
static var previews: some View {
MyDiscloureGroupView(showing: .constant(true), revealDetails: .constant(true))
}
}

Left animation shift when using nested NavigationLink

I am developing an application using SwiftUI (XCode 12.5.1) and every time one of my View appears after exactly two links of "NavigationLink" everything that is inside a Form is shifted slightly to the left, once the appearing animation is over. The following video shows whats going on : the first two times I open the view, everything is fine. The next two times, when the view is accessed from nested NavigationLink, a slight shift to the left is done once the appearing animation is over.
https://www.dropbox.com/s/k3gjc42xlqp2auf/leftShift.mov?dl=0
I have the same problem on both the simulator and a real device (an iPhone). Here is the project: https://www.dropbox.com/s/l8r5hktg6lz69ob/Bug.zip?dl=0 . The main code is available below.
Here is the main view ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: PersonView()) {
Text("Person")
}
NavigationLink(destination: IndirectView()) {
Text("Indirect")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Here is the indirect view, IndirectView.swift
import SwiftUI
struct IndirectView: View {
var body: some View {
List {
NavigationLink(destination: PersonView()) {
Text("Person")
}
}
}
}
and the person view, PersonView.swift
import SwiftUI
struct PersonView: View {
var body: some View {
Form {
VStack(alignment: .leading, spacing: 5) {
Text("Last Name")
.font(.system(.subheadline))
.foregroundColor(.secondary)
Text("Fayard")
}
}
}
}
Do you have any idea on what's causing this shift?
Thanks for your help
Francois
Frankly saying I have not idea what causes the problem, but here is the fix: add this line of code no your NavigaitonView
NavigationView {
// everything else
}.navigationViewStyle(StackNavigationViewStyle())

SwiftUI sheet gets dismissed the first time it is presented

This bug is driving me insane. Sometimes (well most of the time) presented sheet gets dismissed first time it is opened. This is happening only on a device and only the first time the app is launched. Here is how it looks on iPhone 11 running iOS 14.1 built using Xcode 12.1 (can be reproduced on iPhone 7 Plus running iOS 14.0.1 as well):
Steps in the video:
I open app
Swiftly navigate to Details view
Open Sheet
Red Sheed gets dismissed by the system???
I open sheet again and it remains on the screen as expected.
This is SwitUI App project (using UIKIt App Delegate) and deployment iOS 14. Code:
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailsView()) {
Text("Open Details View")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct DetailsView: View {
#State var sheetIsPresented: Bool = false
var body: some View {
VStack {
Button("Open") {
sheetIsPresented.toggle()
}
}.sheet(isPresented: $sheetIsPresented, content: {
SheetView()
})
}
}
struct SheetView: View {
var body: some View {
Color.red
}
}
I was able to fix this problem by removing line .navigationViewStyle(StackNavigationViewStyle()), but I need StackNavigationViewStyle in my project. Any help will be appreciated.
Updated: There is a similar post on Apple forum with sheet view acting randomly weird.
One solution that I found is to move sheet to the root view outside NavigationLink (that would be ContentView in my example), but that is not ideal solution.
I had the same problem in an app. After a great deal of research, I found that making the variable an observed object fixed the problem in SwiftUI 1, and it seems to be in SwiftUI 2. I do remember that it was an intermittent problem on an actual device, but it always happened in the simulator. I wish I could remember why, maybe when the sheet appears it resets the bound variable?, but this code fixes the problem:
import SwiftUI
import Combine
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailsView()) {
Text("Open Details View")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct DetailsView: View {
#ObservedObject var sheetIsPresented = SheetIsPresented.shared
var body: some View {
VStack {
Button("Open") {
sheetIsPresented.value.toggle()
}
}.sheet(isPresented: $sheetIsPresented.value, content: {
SheetView()
})
}
}
struct SheetView: View {
var body: some View {
Color.red
}
}
final class SheetIsPresented: NSObject, ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
static let shared = SheetIsPresented()
#Published var value: Bool = false {
willSet {
objectWillChange.send()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Tested on Xcode 12.1, iOS 14.1 in simulator.
Just add your NavigationView view to bellow code line
.navigationViewStyle(StackNavigationViewStyle())
Example :
NavigationView { }.navigationViewStyle(StackNavigationViewStyle())
Problem will be solved (same issues I was faced)

SwiftUI - Presenting a View on top of the current View from AppDelegate

I am working on a project that at some point it receives a notification. When that happens, I need to show a View. I am not able to catch notification from any View so I am looking for a way to change to control it from outside of View structs. After the View's purpose is done, I need to dismiss it where the app left off. Think like the native behaviour when there is an active call.
I thought I could use sheet however I could not find any way to trigger it for every View that could be active when the notifications come. Or maybe trying to extend native View class would work but again, no luck finding a tutorial.
Any help will be appreciated.
Just update your model based on notification. There is not necessary to define .sheet (modal view) everywhere in your view hierarchy. Doing it in root view should be enough.
To demonstrate that (copy - paste - run) I create small project where I mimic notification with SwiftUI Toggle.
import SwiftUI
class Model: ObservableObject {
#Published var show = false
}
struct SubView: View {
#EnvironmentObject var model: Model
var tag: Int
var body: some View {
VStack {
NavigationLink(destination: SubView(tag: tag + 1).environmentObject(model)) {
Text("subview \(tag)")
}
if tag == 2 {
Toggle(isOn: $model.show) {
Text("toggle")
}.padding()
}
}.navigationBarTitle("subview \(tag)")
}
}
struct ContentView: View {
#ObservedObject var model = Model()
var body: some View {
NavigationView {
SubView(tag: 0).environmentObject(model)
}.sheet(isPresented: $model.show) {
Text("sheet")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
with the result

SwiftUI: NavigationLink not working if not in a List

I guess it might be a bug in beta 3 as the NavigationView is all broken. But a view like that:
struct GenreBadge : View {
#EnvironmentObject var store: Store<AppState>
let genre: Genre
var body: some View {
NavigationLink(destination: MoviesGenreList(genre: genre).environmentObject(store)) {
RoundedBadge(text: genre.name)
}
}
}
is not triggering any push in the navigation stack. The view doens't seems interactive at all. If anyone found a workaround would be good, unless Apple is documenting this behaviour I would consider it broken until beta 4.
There seems to be a bug with the navigation link in Xcode version 11.3(11C29) which I have reported to Apple.
Note: This problem only appears in simulator. It works fine on a real device. Thanks to #djr
The below code works as expect the first time you use the navigation link. Unfortunately it becomes unresponsive the second time around.
import SwiftUI
struct ContentView : View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SomeView()) {
Text("Hello!")
}
}
}
}
}
struct SomeView: View {
var body: some View {
Text("Detailed View")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Are you actually inside a NavigationView? The following works. But if I missed your point, maybe you can share a little more code.
import SwiftUI
struct ContentView : View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SomeView()) {
Text("Go!")
}
}
}
}
}
struct SomeView: View {
var body: some View {
Text("Detailed View Here!")
}
}
NavigationLink
A button that triggers a navigation presentation when pressed. This is a replacement for pushViewController
NavigationView {
NavigationLink(destination:
Text("Detail")
.navigationBarTitle(Text("Detail"))
) {
Text("Push")
}.navigationBarTitle(Text("Master"))
}
Or make it more readable by use group destination into it own view DetailView
NavigationView {
NavigationLink(destination: DetailView()) {
Text("Push")
}.navigationBarTitle(Text("Master"))
}
In Xcode 11.3.1, I experienced the same issue but I just had to quit xcode and restart my computer. This apparently fixed an issue (of course its 2021 right now) but I was able to follow apple's swiftui tutorial without any issues. I copied this code and tried it out... worked fine for me. Maybe the issue is your "play" button on the bottom right of your screen was toggled.
Try this:
VStack{
NavigationLink(destination: DetailView()) {
Text("Push")
}.navigationBarTitle(Text("Your Text")).isDetailLink(false)
}
Try this:-
var body: some View {
NavigationView {
NavigationLink(destination: YourView()) {
Text("Go!")
}
}
}