Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

swiftui - Fix hundreds of lines of warnings re layout constraints from DatePicker

Using the new (iOS 14) DatePicker in SwiftUI, it works as expected and looks fine in the simulator & on the device, BUT as soon as the calendar pops up, I get a few HUNDRED lines of warning in the output window. Which is a little annoying!

While the logs are posted below, the seemingly relevant content seems to be:

    UIDatePicker 0x7fbd66fc49f0 is being laid out below its minimum width of 280. This may not look like expected, especially with larger than normal font sizes.

But, as the code below shows, I'm not constraining anything narrower than 300 points. And, everything shows up fine.

Either of two solutions would work fine from my standpoint:

  • suppress all warnings, or
  • add whatever fixes to the code to eliminate the warnings

The code that pops up the Date Picker, which generates all the warnings as soon as the control is tapped:

struct MyCustomDatePicker : View {
    var doSomething : (Date) -> ()
    @State var title: String
    @State var ignoreSelStart : Bool
    @State var ignoreSelEnd : Bool
    @State var selectedDate : Date
    @ObservedObject var limits : DateRangeLimits
     
    var body: some View {
        VStack {
            DatePicker(
                "(title)", selection: $selectedDate,
                in: ((ignoreSelStart ? limits.hardStart : limits.selectedStart)...(ignoreSelEnd ? limits.hardEnd : limits.selectedEnd)), displayedComponents: [.date]
                )
            .onChange(of: selectedDate, perform: { value in
                doSomething(selectedDate)
            })
        }
        .frame(width: 400, height: 100, alignment: .center)
        .background(Color.white)
    }
}

This struct is called from here:

struct FlexChoice : View {     
    @ObservedObject var limits = DateRangeLimits()

    func setStart(d: Date) {
        // stuff
    }
    func setEnd(d: Date) {
        // stuff
    }
 
    var body: some View {
        VStack(spacing: 0) {
            if customDateRangePossible {
                HStack {
                    MyCustomDatePicker(doSomething: self.setStart, title: "Begin ",
                                    ignoreSelStart: true, ignoreSelEnd: false,
                                    selectedDate: limits.selectedStart, limits: limits)
                    MyCustomDatePicker(doSomething: self.setEnd, title: "Finish ",
                                    ignoreSelStart: false, ignoreSelEnd: true,
                                    selectedDate: limits.selectedEnd, limits: limits)
                }       // closes HStack               
            }       // closes "if customDateRangePossible..."           
        }       // closes VStack
    }       // closes body
}       // closes struct

The first bit of the warnings:

2021-01-23 10:06:35.707334-0600 MyAppName[28362:46367754] [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. 
(
    "<_UISystemBaselineConstraint:0x6000011979d0 H:[_UIDatePickerLinkedLabel:0x7fbd66ffda10]-(NSLayoutAnchorConstraintSpace(8))-[UILayoutGuide:0x6000008f4540'']   (active)>",
    "<_UISystemBaselineConstraint:0x600001196f30 H:[UILayoutGuide:0x6000008f4540'']-(>=NSLayoutAnchorConstraintSpace(8))-[_UIDatePickerTouchOutsetButton:0x7fbd66f8e9d0]   (active)>",
    "<NSLayoutConstraint:0x600001197070 _UIDatePickerLinkedLabel:0x7fbd66ffda10.leading == UILayoutGuide:0x6000008f41c0'UIViewLayoutMarginsGuide'.leading   (active)>",
    "<NSLayoutConstraint:0x600001194fa0 H:[_UIDatePickerTouchOutsetButton:0x7fbd66f8e9d0]-(28)-[_UIDatePickerTouchOutsetButton:0x7fbd72922e40]   (active)>",
    "<NSLayoutConstraint:0x600001197340 _UIDatePickerTouchOutsetButton:0x7fbd72922e40.trailing == UILayoutGuide:0x6000008f41c0'UIViewLayoutMarginsGuide'.trailing   (active)>",
    "<NSLayoutConstraint:0x6000011975c0 UILayoutGuide:0x6000008f4540''.width == UIImageView:0x7fbd66f8e800.width   (active)>",
    "<NSLayoutConstraint:0x60000125fca0 _UIDatePickerCalendarContentStackView:0x7fbd66f8ad40.width <= _UIDatePickerCalendarView:0x7fbd66fc49f0.width   (active)>",
    "<NSLayoutConstraint:0x6000011c2f30 H:|-(0)-[_UIDatePickerCalendarView:0x7fbd66fc49f0]   (active, names: '|':UIDatePicker:0x7fbd7298e840 )>",
    "<NSLayoutConstraint:0x6000011c0500 _UIDatePickerCalendarView:0x7fbd66fc49f0.trailing == UIDatePicker:0x7fbd7298e840.trailing   (active)>",
    "<NSLayoutConstraint:0x60000125ee90 H:|-(8)-[UIDatePicker:0x7fbd7298e840]   (active, names: '|':UIView:0x7fbd72d46870 )>",
    "<NSLayoutConstraint:0x6000012573e0 UIDatePicker:0x7fbd7298e840.trailing == UIView:0x7fbd72d46870.trailing - 8   (active)>",
    "<NSLayoutConstraint:0x6000011de120 'UISV-canvas-connection' _UIDatePickerCalendarContentStackView:0x7fbd66f8ad40.leading == _UIDatePickerCalendarHeaderView:0x7fbd66f8aed0.leading   (active)>",
    "<NSLayoutConstraint:0x6000011df390 'UISV-canvas-connection' H:[_UIDatePickerCalendarHeaderView:0x7fbd66f8aed0]-(0)-|   (active, names: '|':_UIDatePickerCalendarContentStackView:0x7fbd66f8ad40 )>",
    "<NSLayoutConstraint:0x6000011cfca0 'UIView-Encapsulated-Layout-Width' UIView:0x7fbd72d46870.width == 0   (active)>",
    "<NSLayoutConstraint:0x60000119cd20 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x6000008f41c0'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':_UIDatePickerCalendarHeaderView:0x7fbd66f8aed0 )>",
    "<NSLayoutConstraint:0x6000011977a0 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000008f41c0'UIViewLayoutMarginsGuide']-(8)-|(LTR)   (active, names: '|':_UIDatePickerCalendarHeaderView:0x7fbd66f8aed0 )>"
)

Will attempt to recover by breaking constraint 
<_UISystemBaselineConstraint:0x600001196f30 H:[UILayoutGuide:0x6000008f4540'']-(>=NSLayoutAnchorConstraintSpace(8))-[_UIDatePickerTouchOutsetButton:0x7fbd66f8e9d0]   (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.

What follows are many repetitions of basically that same warning (minus the constraint that was just broken on each successive iteration).

At the very end of the hundreds of lines of warning are the following:

2021-01-23 10:06:35.734386-0600 MyAppName[28362:46367754] [DatePicker] UIDatePicker 0x7fbd66fc49f0 is being laid out below its minimum width of 280. This may not look like expected, especially with larger than normal font sizes.
2021-01-23 10:06:35.740477-0600 MyAppName[28362:46367754] [DatePicker] UIDatePicker 0x7fbd66fc49f0 is being laid out below its minimum width of 280. This may not look like expected, especially with larger than normal font sizes.
2021-01-23 10:06:35.752360-0600 MyAppName[28362:46367754] [DatePicker] UIDatePicker 0x7fbd66fc49f0 is being laid out below its minimum width of 280. This may not look like expected, especially with larger than normal font sizes.

Is there a way to make the DatePicker happy & make it so that these warnings don't flood the output window, either by fixing things or suppressing the warnings?

question from:https://stackoverflow.com/questions/65861895/fix-hundreds-of-lines-of-warnings-re-layout-constraints-from-datepicker

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'm getting the same warnings and I'm doing all my constraints programmatically (below). I tried setting my constraints to lower priority (900), so that they wouldn't conflict with any system constraints that might be there but it didn't make any difference.

"V:[timePeriodControl]-(0@900)-[datePicker]"
"H:[datePicker]-(0@900)-|"

The compact picker displays the date fine at first. It's only when I tap on the compact picker and the _UIDatePickerIOSCompactViewController is created to display the calendar that the warnings occur. All the constraint warnings are on the calendar view, which is created by the SDK, not us.

In this screenshot from the debugger you can even see the compact date picker view is still in its right place and is the right size (blue box on right). I checked it's constraints and they are fine (you can print out a list from the debugger). So it's not the compact picker that's the problem, it's definitely the calendar view controller needs a radar. This is an iOS SDK bug.

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...