修复来自 DatePicker 的数百行警告重新布局约束

Con*_*ers 10 datepicker suppress-warnings swiftui

在 SwiftUI 中使用新的 (iOS 14) 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.
Run Code Online (Sandbox Code Playgroud)

但是,正如下面的代码所示,我不限制任何小于 300 点的内容。而且,一切都显示正常。

从我的角度来看,两种解决方案中的任何一种都可以正常工作:

  • 禁止所有警告,或
  • 向代码添加任何修复以消除警告

弹出日期选择器的代码,一旦点击控件就会生成所有警告:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

struct是从这里调用的:

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

Run Code Online (Sandbox Code Playgroud)

警告的第一部分:

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.
Run Code Online (Sandbox Code Playgroud)

接下来是多次重复基本相同的警告(减去在每次连续迭代中刚刚打破的约束)。

在数百行警告的最后是以下内容:

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.
Run Code Online (Sandbox Code Playgroud)

有没有办法让 DatePicker 开心并使它不让这些警告充斥输出窗口,无论是通过修复事物还是抑制警告?

小智 0

如果您使用 GraphicalDatePickerStyle,请尝试:

DatePicker("", ....)
   .datePickerStyle(GraphicalDatePickerStyle())
   .padding()  // this line solves the problem.
Run Code Online (Sandbox Code Playgroud)

我使用 CompactDatePickerStyle ,不幸的是问题仍然存在。