WatchOS and iOS new .accessoryInline Widget does not display everything - ios

I'm trying to made an WatchOS extension with the new type .accessoryInlineBut I don"t understand why I cannot have more than one stack in the main horizontal stack.
See the invisible stack in the following commented code and in the WatchOS simulator
struct WidgetInlineView : View {
var entry: BurnoutTimelineEntry
var body: some View {
HStack(spacing: 5) {
HStack {
Image("widgetWork")
Text(entry.exchange.todayWork.durationString)
}
HStack {
Image("widgetPause")
Text(entry.exchange.todayPause.durationString)
}
}
}
}
struct WidgetInline: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "MyKind", provider: BurnoutTimelineProvider()) { entry in
WidgetInlineView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
.supportedFamilies([.accessoryInline])
}
}
struct WidgetInline_Previews: PreviewProvider {
static var previews: some View {
WidgetInlineView(entry: BurnoutTimelineEntry(date: Date()))
.previewContext(WidgetPreviewContext(family: .accessoryInline))
}
}

The inline widgets only display the first text item and the first image. Everything else is ignored and they ignore any styling, too. And to top it off, it's very picky about the image size (I have not found the exact limits yet): if your image is too large it won't get rendered, even if you marked it as resizable.

I come to the same conclusion as answered by #DarkDust
Regarding text, my work around is to use text concatenation. something like this...
Text("Hello") + Text("\(name) ") + Text(Image(systemName: "exclamationmark.circle.fill"))

Related

SwiftUI Picker greyed out in a List

Does anyone have a fix for this? I have a Picker in my List that doesn't respond to any user input and is greyed out, but if I move it out of the List and into a VStack it functions normally.
The majority of answers I've found to this question all say that the Picker needs to be in a Form to work (which I don't understand since it works fine in a VStack), or that its a bug in which it only works on a physical device, which I've also tested on and gotten the same result.
I'll provide a screenshot as well as the code I'm using below
import SwiftUI
struct SettingsView: View {
#Binding var age : Int
var body: some View {
VStack(alignment: .leading){
List{
Picker("Your age", selection: $age) {
ForEach(1...100, id: \.self) { number in
Text("\(number)")
}
}
}
}
}
You must embed your List inside a NavigationView, so you can actually "navigate" from "Your age" to the list of Ints.
Just add one additional layer, as shown below:
var body: some View {
VStack(alignment: .leading){
NavigationView { // This is needed to navigate to the ForEach
List {
Picker("Your age", selection: $age) {
ForEach(1..<101) { number in
Text("\(number)")
}
}
}
}
}
}

SwiftUI prevent List in Sheet from inheriting parent Form styles

How can I prevent a view within a Sheet from inheriting components from its parents?
I believed a Sheet would create a whole new view hierarchy, but apparently it does not completely. As seen in the Gif below, the ListView inherits the Form when it is attached to the Button inside the Form. When placing it outside the form, the List behaves as expected. Is there a way to prevent this from happening? As you can see, the list with its sections becomes pretty useless when inheriting the Form. This almost seems like a bug to me.
Tested in an empty project using Xcode Version 12.5 (12E262) and iOS 14.5
import SwiftUI
struct ContentView: View {
#State var isSheetPresented: Bool = false
var body: some View {
NavigationView {
Form {
NavigationLink ("Link", destination: ListView())
Button("Sheet") {
isSheetPresented = true
}
.sheet(isPresented: $isSheetPresented, content: {
NavigationView {
ListView()
}
})
}
}
}
}
struct ListView: View {
var body: some View {
List {
Button("1") { }
Button("2") { }
Button("3") { }
Section(header: Text("one")) {
Button("4") { }
}
}
.navigationBarTitle("List")
}
}
Use DefaultListStyle()
ListView().listStyle(DefaultListStyle())

SwiftUI View Code is seemingly getting called twice. What is the issue here?

I have a view that is being called using .sheet in SwiftUI. However, when this sheet is presented, I'm getting the debug "Tapped" print in console followed by this error:
Warning: Attempt to present <_TtGC7SwiftUIP13$7fff2c9bdf5c22SheetHostingControllerVS_7AnyView_: 0x7f8f1d7400f0> on <_TtGC7SwiftUI19UIHostingControllerVVS_22_VariadicView_Children7Element_: 0x7f8f17e0dae0> which is already presenting (null)
I'm not exactly sure what is causing this error, but from what I understand it's due to the view getting called twice. I'm not sure how the view is being called twice, or even if it is, which is why I'm asking here. Below is the main view that actually houses the NavigationView in which my List is being housed view
struct AllTablesView: View {
#Environment(\.managedObjectContext) var managedObjectContext
#FetchRequest(fetchRequest: Table.getAllTables()) var tables: FetchedResults<Table>
#State private var tableTapped: Table = Table()
#State private var isModal = false
var body: some View {
NavigationView {
List {
ForEach(self.tables) { table in
tableCellView(tableNumber: table.number, clean: table.clean, inUse: table.inUse)
.onTapGesture {
self.tableTapped = table
self.isModal = true
print("tapped")
}
}
.onDelete { indexSet in
let deletedTable = self.tables[indexSet.first!]
self.managedObjectContext.delete(deletedTable)
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
}
.sheet(isPresented: $isModal){
TableStatusView(table: self.tableTapped)
.environment(\.managedObjectContext, self.managedObjectContext)
}
}
.navigationBarTitle("All Tables")
.navigationBarItems(leading: EditButton(), trailing:
HStack {
DeleteAllTablesButton()
AddTableButton()
})
}
}
}
And, if for whatever reason this is the issue, here is the code for my view titled "TableStatusView"
struct TableStatusView: View {
#Environment(\.managedObjectContext) var managedObjectContext
#FetchRequest(fetchRequest: Table.getAllTables()) var tables: FetchedResults<Table>
#State var table: Table
var body: some View {
VStack {
Form {
Section {
Text("Table \(table.number)")
}.padding(.all, 10.0)
Section {
Toggle(isOn: $table.inUse) {
Text("In Use")
}.padding(.all, 10.0)
Toggle (isOn: $table.clean) {
Text("Clean")
}.padding(.all, 10.0)
}
}
}
}
}
Is there a reason I'm getting this error, or why my view is being called twice? Is it actually that it's being called twice or am I doing something wrong here? I know certain parts of my code could probably be shrunk down or written better but this is just my first dive into SwiftUI, I haven't had much experience with it outside of basic stuff. Thanks!
I never did find a solution to the question, but I did solve the NavigationLink issue and swapped back to using that. I was using ".onTapGesture" to get a tap gesture and then generate a NavigationLink, thinking it was an action. NavigationLink, I've learned, is actually more or less a container to house content, so I replaced the .onTapGesture and TableCellView() function call with the following:
NavigationLink(destination: TableStatusView(table: table)) {
tableCellView(tableNumber: table.number, clean: table.clean, inUse: table.inUse)
}
And fixed the issue for me. I'm still seeing some errors but from some google-fu found out that they are current bugs of SwiftUI. SwiftUI 2.0 may fix some of these issues

SwiftUI Issue - Extraneous argument label 'perform:' in call (Xcode 11 Swift 5)

I am learning Swift and trying to implement the "Room" app demonstrated in the WWDC 2019 Session 204 . In my code below, which is exactly typed same as Jacob in the video but I run into the following error:
Line:
.onDelete(perform: deleteRoom)
Error:
"Extraneous argument label 'perform:' in call"
Can't figure out on my own...
Thanks in advance!
struct ContentView: View {
//var rooms: [Room] = []
// #ObservedObject var store = RoomStore()
var store = RoomStore()
var body: some View {
NavigationView {
List {
Section {
Button(action: addRoom) {
Text("Add")
}
}
Section {
ForEach(store.rooms) { room in
RoomCell(room: room)
}
/* HERE is the error */
.onDelete(perform: deleteRoom)
}
}
.navigationBarTitle(Text("Rooms"))
.listStyle(.grouped)
}
}
func addRoom() {
store.rooms.append(Room(name: "New Room", capacity: 20, hasVideo: true))
}
func deleteRoom(at offsets: IndexSet) {
store.rooms.remove(atOffsets: offsets)
}
}
Don't Trust Xcode:
Xcode is not very intelligent to tell you what is the real issue in SwiftUI enough (yet). So believing or not, the issue is with the listStyle.
You should change it to:
.listStyle(GroupedListStyle())
Don't forget to remove the . from .Text("Add") you accidentally typed in first section.
Some other useful notes (NOT related to the issue):
SwiftUI API is now more compatible with Strings, So you can set the Text value directly in some initializers for Views like Button and modifiers like navigationBarTitle:
Button("Add", action: addRoom) /* Instead of Button(action: addRoom) { Text("Add") } */
.navigationBarTitle("Rooms") /* Instead of .navigationBarTitle(Text("Rooms")) */

Why is SwiftUI picker in form repositioning after navigation?

After clicking the picker it navigates to the select view. The item list is rendered too far from the top, but snaps up after the animation is finished. Why is this happening?
Demo: https://gfycat.com/idioticdizzyazurevase
I already created a minimal example to rule out navigation bar titles and buttons, form sections and other details:
import SwiftUI
struct NewProjectView: View {
#State var name = ""
var body: some View {
NavigationView {
Form {
Picker("Client", selection: $name) {
Text("Client 1")
Text("Client 2")
}
}
}
}
}
struct NewProjectView_Previews: PreviewProvider {
static var previews: some View {
NewProjectView()
}
}
This happens in preview mode, simulator and on device (Xcode 11.2, iOS 13.2 in simulator, 13.3 beta 1 on device).
The obviously buggy behavior can be worked around when forcing the navigation view style to stacked:
NavigationView {
…
}.navigationViewStyle(StackNavigationViewStyle())
This is a solution to my problem, but I won‘t mark this as accepted answer (yet).
It seems to be a bug, even if it may be triggered by special circumstances.
My solution won‘t work if you need another navigation view style.
Additionally, it won‘t fix the horizontal repositioning mentioned by DogCoffee in the comments.
In my opinion, it has something to do with the navigation bar. In default (no mention of .navigationBarTitle extension), the navigation display mode is set to .automatic, this should be amend to .inline. I came across another post similar to this and use their solution to combine with yours, by using .navigationBarTitle("", displayMode: .inline) should help.
import SwiftUI
struct NewProjectView: View {
#State var name = ""
var body: some View {
NavigationView {
Form {
Picker("Client", selection: $name) {
Text("Client 1")
Text("Client 2")
}
}
.navigationBarTitle("", displayMode: .inline)
}
}
}
struct NewProjectView_Previews: PreviewProvider {
static var previews: some View {
NewProjectView()
}
}
Until this bug is resolved another way to work around this issue while retaining the DoubleColumnNavigationViewStyle for iPads would be to conditionally set that style:
let navView = NavigationView {
…
}
if UIDevice.current.userInterfaceIdiom == .pad {
return AnyView(navView.navigationViewStyle(DoubleColumnNavigationViewStyle()))
} else {
return AnyView(navView.navigationViewStyle(StackNavigationViewStyle()))
}
Thanks for this thread everyone! Really helped me understand things more and get a hold of one of my problems. To share with others, I was having this problem to but I was also having this problem when I set a section to appear in a if/else statement set on a section with a toggle. When the toggle was activated it would shift the section header horizontally a few pixels.
The following is how I fixed it
Section(header: Text("Subject Identified").listRowInsets(EdgeInsets()).padding(.leading)) {
Picker(selection: $subIndex, label: Text("Test")) {
ForEach(0 ..< subIdentified.count) {
Text(self.subIdentified[$0]).tag($0)
}
}
.labelsHidden()
.pickerStyle(SegmentedPickerStyle())
I'm still having horizontal shift on my picker selection view and not sure how to fix. I created another thread to received input. Thanks again! SwiftUI Shift Picker Text Horizontal

Resources