Random Error when using tabview

So I was coding so i get to learn Swift 5 and i want to make a TabView with multible Tabs.


Icodedt them everything went fine and I noticed i need one or two more so I added the code for them and then XCode tells me that error code "Argument passed to call that makes no arguments". As soon as I delete my lines the error disappears.


In Line 9 he tells me the error and underlines the T from .tabItem I only added line 33 to 36.


import SwiftUI

struct ContentView: View {
    
    var body: some View {
    
            TabView {
                   
                CharakterView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar4)
                    Text("Charakter")
                    
                }
                
                AttributView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar1)
                    Text("Attribute")
                        
                }
                
                FertigkeitenView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar2)
                    Text("Fertigkeiten")
                        
                }
                
                VorNachView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar1)
                    Text("Vor/Nachteile")
                        
                }
                
                ConnectionView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar3)
                    Text("Connections")
                }
                
                
                BioCyberView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar1)
                    Text("Bio/Cyberware")
                        
                }
                
                ZauberView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar1)
                    Text("Zauber")
                        
                }
                
                AusruestungView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar1)
                    Text("Ausrüstung")
                        
                }
                
                VehicleView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar1)
                    Text("Vehicle")
                        
                }
               
                KiView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar0)
                    Text("Ki-Kräfte")
                        
                }
               
                KomplexView().tabItem {
                    Image(systemName: Constant.TabBarImageName.tabBar0)
                    Text("Komplexe Form")
                        
                }
                
                
            }
    }
}
        
    

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().previewLayout(.fixed(width: 414, height: 896))
    }
}

Accepted Reply

For the UI aspect, you could reate a collection of buttons at the bottom (of course on several lines) each leading to the desired page.

It uses some screen real estate, but it is better than having to move to another page to see more tabs.


Or if you accept to switch to another view, just put all the tabs there, instead of 4 on the first screen and 15 on a second screen.


Or you could cluster your tabs and use longpress to see 4 or 5 options each time.

Here is a mockup with 20 options in 5 tabs:


let data = [
  "Test 1","Test 2","Test 3","Test 4","Test 5",
  "Test 6","Test 7","Test 8","Test 9","Test 10",
  "Test 11","Test 12","Test 13","Test 14","Test 15",
  "Test 16","Test 17","Test 18","Test 19","Test 20"
]

struct MyTabItem: View {
    @State var first: Int
    var body: some View {
        VStack {
            ForEach(first..<(first+4), id:\.self) {
                item in
                Button(action: {}) { Text(data[item]); Image(systemName: "globe") }
            }
        }
    }
}

struct ContentView: View
{
    var body: some View {
        VStack {
            Text("Hello")
                .font(.largeTitle)
            Spacer()
            HStack {
                Text("Test A")
                    .contextMenu
                    { MyTabItem(first: 0)
                }
                Spacer()
                Text("Test B")
                    .contextMenu
                    { MyTabItem(first: 4)
                }
                Spacer()
                Text("Test C")
                    .contextMenu
                    { MyTabItem(first: 8)
                }
                Spacer()
                Text("Test D")
                    .contextMenu
                    { MyTabItem(first: 12)
                }
                Spacer()
                Text("Test E")
                    .contextMenu
                    { MyTabItem(first: 16)
                }
            }.padding()
    }
  }
}



You could also have the first 4 as normal links and the 5th reading "More" with the remaining 16 options…

Replies

Did some test.


It seems there is a limit of 10 tabs.

Confirmed.

Same limit if iPad or iPhone.


I tested with the simplest tabView possible:


struct ContentView: View {
    
    var body: some View {
            TabView {
                Text("Hello1").tabItem {
                        Text("1")
                }
                Text("Hello2").tabItem {
                        Text("2")
                }
                Text("Hello3").tabItem {
                        Text("3")
                }
                Text("Hello4").tabItem {
                        Text("4")
                }
                Text("Hello5").tabItem {
                        Text("5")
                }
                Text("Hello6").tabItem {
                        Text("6")
                }
                Text("Hello7").tabItem {
                        Text("7")
                }
                Text("Hello8").tabItem {
                        Text("8")
                }
                Text("Hello9").tabItem {
                        Text("9")
                }
                Text("Hello10").tabItem {
                        Text("10")
                }
                Text("Hello11").tabItem {
                        Text("11")
                }
            }
    }
}


With 11 tabs, get the compile error on line 5 (which is probably considered as superfluous tab):


Argument passed to call that takes no arguments.


If i remove a tab, works OK.


Don't know if this is documented somewhere.


You should file a bug report (at least against documentation) and close the thread.

It is a known limitation of the current implementation of Swift UI.


`TabView`, as well as other SwiftUI views, utilizes `@ViewBuilder` which is a `@_functionBuilder`.

public struct TabView<SelectionValue, Content> : View where SelectionValue : Hashable, Content : View {

    /// Creates an instance that selects from content associated with
    /// `Selection` values.
    public init(selection: Binding<SelectionValue>?, @ViewBuilder content: () -> Content)

    //...
}

And `@ViewBuilder` parses the body of `content` and reconstruct a `View` using `buildBlock` method:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@_functionBuilder public struct ViewBuilder {

    /// Builds an empty view from an block containing no statements, `{ }`.
    public static func buildBlock() -> EmptyView

    /// Passes a single view written as a child view (e..g, `{ Text("Hello") }`) through
    /// unmodified.
    public static func buildBlock<Content>(_ content: Content) -> Content where Content : View
}

//...

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension ViewBuilder {

    public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View
}

There are several overloads of `buildBlock`, the maximum takes 10 arguments, which leads to the limitation you have found.

You can find the same limitation in most of the SwiftUI views, `VStack`, `HStack`, ...


By the way, it is not considered to be a good UI design having too many tabs in a tab view.

Thanks for the answers i also stumbled over the limitations in Hstack and Vstack before. The point is if you code it out like i did you run into the error and then I found this online.


import SwiftUI
struct MyTabView : View {
var body: some View {
TabView() {
// Loops 2 times to create 2 views with title and context text
            ForEach((1...20), id: \.self) { index in
TabContent(title:"Title \(index)", content: "This is the content in tab \(index)")
                   .tabItem {
Image(systemName: "\(index).circle")
Text("Tab \(index)")
                   }.tag(index)
            }
        }
    }
}
// Simple content with title and context text
struct TabContent: View {
@State var title: String
@State var content: String
var body: some View {
        VStack{
Text("\(title)")
                .font(.largeTitle)
                .fontWeight(.black)
                .multilineTextAlignment(.center)
                .scaledToFill()
                .padding()
Text("\(content)")
                .multilineTextAlignment(.center)
        }
    }
}


And it works fine and gives me 20 Tabs and more (maybe). And in the documentation there is no clear definition then you can only mache like 10 taps or 10 rows of a Vstack and so forth.


I don't know if this is a good UI design but it fit my needs ( I dont know a other good way) I want like a digital Character Sheet App ant with the Tabs I have the opportunity to quickly access the relavant information without opening a side bar or topdown menue. Later every tap should display soemthing diffrent even diffrent in style like ListView and so on.

Thanks for the information, I could not find it.


And you're right, in case of tabs, that's poor UI to have more than 5 or 6.


This being said, I understand they had to have a fixed number as they use Tuple. But having it so hard coded appears as a weakness.

That's even more with VStacks: one could have 15 items. Of course, we can make it hierarchical, but that another SwiftUI circumvolution.


And finally, probably the worse, the error message is awful !

It points to the first item, not the last.

It is totally meaningless "Argument passed to call that takes no arguments."


SwiftUI will imprive in the future (much needed).

For the UI aspect, you could reate a collection of buttons at the bottom (of course on several lines) each leading to the desired page.

It uses some screen real estate, but it is better than having to move to another page to see more tabs.


Or if you accept to switch to another view, just put all the tabs there, instead of 4 on the first screen and 15 on a second screen.


Or you could cluster your tabs and use longpress to see 4 or 5 options each time.

Here is a mockup with 20 options in 5 tabs:


let data = [
  "Test 1","Test 2","Test 3","Test 4","Test 5",
  "Test 6","Test 7","Test 8","Test 9","Test 10",
  "Test 11","Test 12","Test 13","Test 14","Test 15",
  "Test 16","Test 17","Test 18","Test 19","Test 20"
]

struct MyTabItem: View {
    @State var first: Int
    var body: some View {
        VStack {
            ForEach(first..<(first+4), id:\.self) {
                item in
                Button(action: {}) { Text(data[item]); Image(systemName: "globe") }
            }
        }
    }
}

struct ContentView: View
{
    var body: some View {
        VStack {
            Text("Hello")
                .font(.largeTitle)
            Spacer()
            HStack {
                Text("Test A")
                    .contextMenu
                    { MyTabItem(first: 0)
                }
                Spacer()
                Text("Test B")
                    .contextMenu
                    { MyTabItem(first: 4)
                }
                Spacer()
                Text("Test C")
                    .contextMenu
                    { MyTabItem(first: 8)
                }
                Spacer()
                Text("Test D")
                    .contextMenu
                    { MyTabItem(first: 12)
                }
                Spacer()
                Text("Test E")
                    .contextMenu
                    { MyTabItem(first: 16)
                }
            }.padding()
    }
  }
}



You could also have the first 4 as normal links and the 5th reading "More" with the remaining 16 options…

True, and I do agree.


This sort of poor diagnostics messages looks like a homework compiler of college students...


Hope all such things fixed and impoved soon.

Thank you very much for your response ! That is a really nice sugguestion with the 3D-Touch thanks didnt know this is possible inside apps.


I know its off topic but can you suggest me a way or page where i can read how I do like a Database inside my app. So basically the user adds a charcter and then edits the data for this individual. Do I create seperate files for each character(and if yes how inside an app) or what would be appropiate.

@T3chWarri0r

Hope that 3D touch will provide you a good solution.


For the other question, it would be better to start a new thread and detail the question there.

And close the present thread by marking the correct answer.

Ok thank you, there is only one short addition can I do it your war but have like in one Context menue 5 and the other 3 options ?

Hope all such things fixed and impoved soon.

Have you tried with the latest Swift 5.2 toolchain? This includes a major revamp of the diagnostics, which should help in situations like this. Certainly, a bunch of the bugs I filed about misleading diagnostics have come back to me as fixed.

You can learn more about this in New Diagnostic Architecture Overview.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"