103

This is maybe related to the new (12.3) version of XCode that came out recently but I have a very simple SwiftUI View:

import SwiftUI

struct HomeView: View {
    var body: some View {
        NavigationView {
            Text("Text")
                .navigationBarTitle("My Title")
        }
    }
}

And I'm getting this warning in the console:

2020-12-15 18:25:06.506062-0800 Shopmatic[46177:9585655] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600003636d00 'BIB_Trailing_CB_Leading' H:[_UIModernBarButton:0x7faf15d0dc30]-(6)-[_UIModernBarButton:0x7faf15c17500'Your Lists']   (active)>",
    "<NSLayoutConstraint:0x600003636d50 'CB_Trailing_Trailing' _UIModernBarButton:0x7faf15c17500'Your Lists'.trailing <= _UIButtonBarButton:0x7faf15c16140.trailing   (active)>",
    "<NSLayoutConstraint:0x600003631e50 'UINav_static_button_horiz_position' _UIModernBarButton:0x7faf15d0dc30.leading == UILayoutGuide:0x600002c18ee0'UIViewLayoutMarginsGuide'.leading   (active)>",
    "<NSLayoutConstraint:0x600003631ea0 'UINavItemContentGuide-leading' H:[_UIButtonBarButton:0x7faf15c16140]-(0)-[UILayoutGuide:0x600002c18e00'UINavigationBarItemContentLayoutGuide']   (active)>",
    "<NSLayoutConstraint:0x600003617160 'UINavItemContentGuide-trailing' UILayoutGuide:0x600002c18e00'UINavigationBarItemContentLayoutGuide'.trailing == _UINavigationBarContentView:0x7faf15e10000.trailing   (active)>",
    "<NSLayoutConstraint:0x600003632580 'UIView-Encapsulated-Layout-Width' _UINavigationBarContentView:0x7faf15e10000.width == 0   (active)>",
    "<NSLayoutConstraint:0x600003617520 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x600002c18ee0'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':_UINavigationBarContentView:0x7faf15e10000 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600003636d00 'BIB_Trailing_CB_Leading' H:[_UIModernBarButton:0x7faf15d0dc30]-(6)-[_UIModernBarButton:0x7faf15c17500'Your Lists']   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

This simple example looks fine but when I do something a bit more complex:

import SwiftUI

struct ListDetailView: View {
    var list: List
    
    var body: some View {
        NavigationView {
            Text("Detail View")
            .navigationBarTitle("Detail View Title")
            .navigationBarTitleDisplayMode(.large)
            .navigationBarItems(
                trailing:
                    Button(action: {
                        print("Button Pressed")
                    }) {
                        Image(systemName: "ellipsis")
                }
            )
        }
    }
}

The Navigation Title areas layout is all screwed up:

enter image description here

goddamnyouryan
  • 6,854
  • 15
  • 56
  • 105
  • 1
    I have the same problem and I don't have any idea about constraint in swiftui, i was thinking that we finally got ride of this constraint problems, and here we go again lol maybe @asperi has an idea – Cod3rMax Dec 16 '20 at 02:37
  • 4
    The .navigationBar methods are being deprecated. In 14.3 that will likely be the source of a lot of issues. https://developer.apple.com/documentation/swiftui/view/navigationbaritems(leading:trailing:) – lorem ipsum Dec 16 '20 at 02:44
  • @loremipsum but if you check the code and try it, it is not! the problem is in navigationBarTitle – Cod3rMax Dec 16 '20 at 02:49
  • @loremipsum huh I had no idea! I'll try toolbar out and see if that helps. – goddamnyouryan Dec 16 '20 at 02:49
  • 2
    @goddamnyouryan i did try it, not working try to delete the navigationBarTitle you will see that the problem is gone, so the problem is in navigationBarTitle – Cod3rMax Dec 16 '20 at 02:51
  • 1
    BarTitle is leaving too. https://developer.apple.com/documentation/swiftui/view/navigationbartitle(_:)-6p1k7 – lorem ipsum Dec 16 '20 at 02:52
  • @loremipsum I am still seeing a layout issue when I use .toolbar { ToolbarItem(placement: .principal) { Text("Title") } } – goddamnyouryan Dec 16 '20 at 03:00
  • Hmm, removing the NavigationView wrapper from the detail view might have fixed it? – goddamnyouryan Dec 16 '20 at 03:04
  • Xcode 14.2 era comment: Gives you an idea why navigationview was deprecated in favor of navigationstack – Anton Tropashko Dec 27 '22 at 12:41

14 Answers14

145

It had nothing to do with NavigationBarTitle. .navigationTitle is not deprecated. Seems the whole issue is mainly with the new Xcode 12.4 update, even for simple code:

var body: some View {
    NavigationView{
        Text("Hopefully will work this time")
            .navigationTitle("Error with constains")
    }
}

adding .navigationViewStyle(StackNavigationViewStyle()) fixes problem

var body: some View {
    NavigationView{
        Text("Yes it does!")
            .navigationTitle("Wow it works")
    }
    .navigationViewStyle(StackNavigationViewStyle())
}
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
Kamran Maximoff
  • 1,459
  • 1
  • 4
  • 4
  • 12
    Dude, this is the answer! And I've been searching for this for a few weeks now and none of the other questions have this answer. Most just say it's a bug and can't be fixed. To add to your answer the navigationViewStyle can be placed at the top level: `ContentView().navigationViewStyle(StackNavigationViewStyle())` this fixes all the views! – 23inhouse Mar 01 '21 at 08:44
  • 11
    almost there - the .navigationViewStyle(StackNavigationViewStyle()) needs to be at the end of the NavigationView closure, not the body. Otherwise does the trick - many thanks. – eklektek Mar 02 '21 at 15:14
  • 6
    This is a bit more elegant — ```.navigationViewStyle(.stack)``` – Vinod Madigeri Feb 16 '22 at 19:29
  • I wonder why the error and why it's fixed by doing this??? – Heuristic Jul 07 '22 at 12:37
77

NavigationBarTitle is deprecated from iOS 14.3. However if you still wish to use it, try to add .navigationViewStyle(StackNavigationViewStyle()) on the navigationView that will fix the warning.

       struct ContentView: View {
        var body: some View {
            NavigationView {
                VStack {
                    Text("Hello, world!")
                        .padding()
                    Spacer()
                }
                .navigationBarTitle("Hey there", displayMode: .inline)
            }
            .navigationViewStyle(StackNavigationViewStyle())
        }
    }

The new way:

.navigationBarTitleDisplayMode(.inline)
.toolbar(content: {
     ToolbarItem(placement: .principal, content: {
     Text("Title")
  })})    
Hezy Ziv
  • 3,652
  • 2
  • 14
  • 8
  • 17
    navigationTitle is not deprecated. https://developer.apple.com/documentation/swiftui/view/navigationtitle(_:)-43srq – Hamer Feb 11 '21 at 04:54
  • it dose fixed the warning , but if its deprecated what is the new solution ? – Kodr.F Mar 26 '21 at 11:08
  • @Khodour.F it's not deprecated – Nik Mar 27 '21 at 21:26
  • @Hezy your solution put the `title` `inline`, what about if you want it `.large` and on scroll inline!? I tried with `.large` in the `.navigationBarTitleDisplayMode(.large)` but it gives the same result as using `.inline`!? – Learn2Code Apr 15 '21 at 20:14
  • 1
    How does someone use the `new` `.navigationBarTitleDisplayMode(.large)`!? Where do I assign the title of the list of items!? – Learn2Code Apr 15 '21 at 20:34
  • 8
    This is no good if you want to support split view on iPad. Fixing the problem by enforcing `StackNavigationViewStyle` is not a good fix imho. – koleS Apr 27 '21 at 19:00
  • What about using `#if os(iOS)` together with `.navigationViewStyle(StackNavigationViewStyle())`? Maybe this way we can avoid the error and still have split view on iPad? – mallow Apr 29 '21 at 04:29
  • Agreed with @koleS. On iOS 14.7 I never saw this error. On updating to iOS 15 I'm seeing it now. This looks like a regression. We shouldn't have to use `StackNavigationViewStyle` or `.toolbar` to avoid this annoying console output. – user2619824 Oct 09 '21 at 19:36
  • @Hamer Sure, ```.navigationTitle``` is used to replace ```.navigationBarTitle```. However, this is still not fixing this issue. If you get constraints warnings when using ```.navigationTitle``` with ```.toolbar```, then you should use __Hezy's__ solution and make your title a ```ToolbarItem```. Don't know why though. – RoyRao Nov 26 '21 at 09:28
62

Xcode 13.0 Beta 1

This is still causing a contraint error unless you add the StackNavigationViewStyle modifier.

However, the documentation for StackNavigationViewStyle states:

Do not use this type directly. Instead, use stack.

var body: some View {
    NavigationView {
        Text("Text")
            .navigationTitle("Title")
    }
    .navigationViewStyle(.stack)
}
rbaldwin
  • 4,581
  • 27
  • 38
18

NavigationBarTitle is deprecated from iOS 14.3 https://developer.apple.com/documentation/swiftui/view/navigationbartitle(_:displaymode:)-8buvp

You can use NavigationTitle and .navigationViewStyle(StackNavigationViewStyle())

import SwiftUI

struct HomeView: View {
    var body: some View {
        NavigationView {
            Text("Text")
                .navigationBarTitle("Hey there", displayMode: .inline)
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}
Thiên Quang
  • 368
  • 3
  • 9
  • 2
    I still get the constraints error in my logs when using `.navigationTitle(Text("Foo"))` and `.navigationBarTitleDisplayMode(.large)` modifiers. – Martin Bean Dec 28 '20 at 13:03
  • @MartinBean you can use NavigationTitle in child views of Navigation. In NavigationView, I recommend you use the above method (a toolbar with ToolbarItem). – Thiên Quang Dec 30 '20 at 02:03
  • 7
    navigationBarTitle is deprecated but navigationTitle is not deprecated. https://developer.apple.com/documentation/swiftui/view/navigationtitle(_:)-5di1u. So those errors might be bug in Xcode version – Sai Durga Mahesh Dec 31 '20 at 07:06
  • 1
    Using StackNavigationViewStyle() is a no go if you're building an iPad app with sidebar navigation. Also, it doesn't seem to make the errors go away. – Jason Armstrong Mar 17 '21 at 19:31
13

All of the above answers are not quite complete, so I would like to add, because I have studied this question for a long time and this is what I came to. I think it will be useful:

One of the interesting things about Navigation View is how it also performs the split-screen function on large devices-usually iPhones and large iPads.

var body: some View {
        NavigationView {
            Text("Primary")
        }
    }

If you rotate to landscape orientation (Cmd + ->) of the iPhone 11 ProMax, you will see that the text view disappears.

SwiftUI automatically considers landscape navigation views and shows DetailView instead of main ("Primary").

You can solve the problem the way SwiftUI expects by providing two views inside your NavigationView, for instance:

var body: some View {
        NavigationView {
            Text("Primary")
            Text("Secondary")
        }
    }

Since I have little reputation, I can only post a photo with a link (If my post was useful, please rate it):

enter image description here

This is why the error "Unable to simultaneously satisfy constraints" is thrown if we add. navigation Bar Title(Text ("Today's Flavors"), displayMode:. inline)

Therefore, the solution is as follows:

  1. Add a second view to the Navigation View

Here, when you rotate the screen, screen # 2 - Text("Secondary") will be displayed.

    var body: some View {
            NavigationView {
                Text("Primary")
                Text("Secondary")
            .navigationBarTitle(Text("Today's Flavors"), displayMode: .inline)
            }
    }
  1. Modifier .navigationViewStyle(StackNavigationViewStyle())

However, if you want to explicitly specify that the first screen (Text("Primary")) is always displayed when you rotate, then you need to add the .navigationViewStyle(StackNavigationViewStyle) modifier()) , which allows you to always switch to Text ("Primary"), regardless of the screen.

var body: some View {
        NavigationView {
            Text("Primary")
            Text("Secondary")
        .navigationBarTitle(Text("Today's Flavors"), displayMode: .inline)
        }
        .navigationViewStyle(StackNavigationViewStyle())

Also, you can read, more about NavigationView here

Dan Bonachea
  • 2,408
  • 5
  • 16
  • 31
Eldar
  • 458
  • 3
  • 13
10
struct QuizView: View {
    var body: some View {

        NavigationView{
            Text("Hello, world!")
             .navigationBarTitle("Ripa", displayMode: .inline)
        }
        .navigationViewStyle(StackNavigationViewStyle()) /// add this line

    }
}
aheze
  • 24,434
  • 8
  • 68
  • 125
Amit Thakur
  • 1,081
  • 12
  • 14
5

I don't get the constraint notice when using this approach:

import SwiftUI

struct ConstraintIssue: View {
    var body: some View {
        NavigationView {
            Text("Detail View")
                .toolbar(content: {
                    ToolbarItem(placement: .principal, content: {
                        Text("Detail View Title")
                    })
                    ToolbarItem(placement: .navigationBarTrailing, content: {
                      Button(action: {
                        print("Button Pressed")
                      }) {
                        Image(systemName: "ellipsis")
                      })
                   }
                }
            )
        }
    }
}
B.T.
  • 610
  • 6
  • 20
lorem ipsum
  • 21,175
  • 5
  • 24
  • 48
  • 1
    nice! The only difference now from what I can tell is when you use `.navigationTitle` instead of `ToolbarItem(placement: .principal` with the `.large` `.navigationBarTitleDisplayMode` you get the nice scrolling behavior where the title is large and left aligned, then when you scroll down it get fixed to the center in the navigation bar and is smaller, if that makes sense. Basically the default old behavior with scrolling is different? – goddamnyouryan Dec 16 '20 at 03:15
4

Unfortunately, a lot of the solutions advising the use of StackNavigationViewStyle() won't work if you're building an iPad app which uses the sidebar.

Digging a little deeper, if you add this line:

UserDefaults.standard.set(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")

in either your AppDelegate or App instance will suppress the errors. You'll get a one line warning that you've disabled it. I believe this is acceptable, since by using SwiftUI we shouldn't have to worry about LayoutConstraints and hopefully Apple will suppress this stuff by default since we're using SwiftUI.

see this SO answer for more info

Jason Armstrong
  • 1,058
  • 9
  • 17
3

I also have these warnings after updating to Xcode 12.3 today with this simple view but it looks normal with no bugs. guess that is a bug of new Xcode version.

struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Hello World")
                .navigationTitle("Hello World")
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {},
                            label: {
                            Image(systemName: "plus.circle")
                        })
                    }
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: {},
                            label: {
                            Image(systemName: "plus.circle")
                        })
                    }
                }
        }
    }
}

Here are the warnings

2020-12-16 14:25:05.897555+0800 TestingSwiftUI[76909:541649] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600002847020 'BIB_Trailing_CB_Leading' H:[_UIModernBarButton:0x7f7f7fc19680]-(6)-[_UIModernBarButton:0x7f7f8200ff20'HelloWorld']   (active)>",
    "<NSLayoutConstraint:0x600002847070 'CB_Trailing_Trailing' _UIModernBarButton:0x7f7f8200ff20'HelloWorld'.trailing <= _UIButtonBarButton:0x7f7f7fc18740.trailing   (active)>",
    "<NSLayoutConstraint:0x600002847de0 'UINav_static_button_horiz_position' _UIModernBarButton:0x7f7f7fc19680.leading == UILayoutGuide:0x6000032689a0'UIViewLayoutMarginsGuide'.leading   (active)>",
    "<NSLayoutConstraint:0x600002847ed0 'UINavItemContentGuide-leading' H:[_UIButtonBarButton:0x7f7f7fc18740]-(0)-[UILayoutGuide:0x6000032688c0'UINavigationBarItemContentLayoutGuide']   (active)>",
    "<NSLayoutConstraint:0x60000286a440 'UINavItemContentGuide-trailing' UILayoutGuide:0x6000032688c0'UINavigationBarItemContentLayoutGuide'.trailing == _UINavigationBarContentView:0x7f7f8200e2c0.trailing   (active)>",
    "<NSLayoutConstraint:0x60000285c410 'UIView-Encapsulated-Layout-Width' _UINavigationBarContentView:0x7f7f8200e2c0.width == 0   (active)>",
    "<NSLayoutConstraint:0x60000286a800 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x6000032689a0'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':_UINavigationBarContentView:0x7f7f8200e2c0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600002847020 'BIB_Trailing_CB_Leading' H:[_UIModernBarButton:0x7f7f7fc19680]-(6)-[_UIModernBarButton:0x7f7f8200ff20'HelloWorld']   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

when I delete

.navigationTitle("Hello World")

the warnings disappeared

so I'm gonna report this issue to Apple

this view looks normal

  • I see this too, but weirdly enough when I use `.navigationTitle` on the root page I still get the error, (but it looks fine) but if I use it in a sub view (a navigationLink-ed to view) I don’t get an error. – goddamnyouryan Dec 16 '20 at 18:24
2

I got the same warnings always, but everything works fine. Now like you said, I delete the .navigationtTitle(), and the warnings disappears, it looks like a bug .

2

Just replace the .navigationBarTitle("string") with .navigationTitle("string") is fine. And add .navigationViewStyle.

Beetroot
  • 91
  • 1
  • 5
2

I was running into similar issues with this:

var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: SettingsView()) {
                    Text("Settings")
                }

                NavigationLink(destination: SettingsView()) {
                    Text("Restore Purchases")
                }
                
            }.navigationTitle(Text("More"))
        }
    }

Bizarrely, moving the navigationTitle inside to anything inside the List fixes it e.g:

var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: SettingsView()) {
                    Text("Settings")
                }

                NavigationLink(destination: SettingsView()) {
                    Text("Restore Purchases")
                }
                .navigationTitle(Text("More"))
            }
        }
    }

I was previously under the impression that navigationTitle could be attached to any view as long as it was contained inside the NavigationView but apparently not. I have other instances of navigationTitle() being attached to the List view in my app working fine so no idea why this particular view was causing an error.

feraleyebrows
  • 155
  • 1
  • 5
1

a small note.. I am wrong or ADC code is wrong??

You can read:

.navigationBarTitle(Text("Today's Flavors", displayMode: .inline)

BUT is wrong: “Cannot infer contextual base in reference to member 'inline’”

They mis-placed a parenthesis:

Right code is:

.navigationBarTitle(Text("Today's Flavors"), displayMode: .inline)

complete code if You want to try...

import SwiftUI


struct ContentView: View {
    let items = ["Chocolate", "Vanilla", "Strawberry", "Mint Chip",
                    "Pistachio"]
       var body: some View {
            NavigationView {
                 List(items, id: \.self) {
                     Text($0)
                 }
                .navigationBarTitle(Text("Today's Flavors"), displayMode: .inline)
            }
        }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

PS

in MARCH 2021 Apple has fixed.. but you can try copies around with fake code... for example here:

https://gist.github.com/erica/6941e2adfce75807bcd64550b3669c26

ingconti
  • 10,876
  • 3
  • 61
  • 48
0

I had this issue with following view:

ScrollView(.vertical) {
    GeometryReader { proxy in
        LazyVGrid(
            columns: [GridItem(.flexible())],
            spacing: 8
        ) {
            ForEach(displayedTags, id: \.self) { tagName in
                LogTagView(
                    logger: logger,
                    name: tagName
                )
            }
        }
        .background(Color.clear)
    }
    .padding(.horizontal, 16)
}
.navigationTitle("Filter")

I found out that the issue only happens with small screen size (ex: iPhone SE 1st gen).

I needed to avoid the deprecated navigationViewStyle modifier, so getting inspired by this answer - from @eraleyebrows - I solved it by attaching navigationTitle("Filter") to ForEach:

ForEach(displayedTags, id: \.self) { tagName in
    LogTagView(
        logger: logger,
        name: tagName
    )
}
.navigationTitle("Filter")

Now I had one issue that the list might be empty, so I wrapped the ForEach inside Group view and still works:

Group {
    ForEach(displayedTags, id: \.self) { tagName in
        LogTagView(
            logger: logger,
            name: tagName
        )
    }
}
.navigationTitle("Filter")

This was tested on iPhone SE 1s gen for iOS 15.4, and iPhone 14 Pro Max for iOS 16.1

Ahmed Shendy
  • 1,424
  • 15
  • 28