UIViewRepresentable скрытый за SwiftUI View - PullRequest
0 голосов
/ 16 апреля 2020

Я недавно задал (и получил действительный ответ) вопрос, связанный с этой проблемой.

Как мне получить свой UIViewRepresentable для правильного размера его содержимого?

Как я упоминал в предыдущем посте, я хочу использовать удивительный MultiSegmentPicker, написанный Йонатом Шароном. в моем SwiftUI View.

https://github.com/yonat/MultiSelectSegmentedControl

Реализация ответа показала, что я еще не в лесу.

screenshot

Обратите внимание, что полоса находится за «нижним» текстовым представлением

В моем не демонстрационном представлении она полностью скрыта за другими представлениями - так что он вообще не виден.

Я понимаю, что это проблема с ограничениями, и отладка представления XCode полезно подтверждает:

runtime: Проблемы с компоновкой: Положение неоднозначно для MultiSelectSegmentedControl.

Где мне решить эту проблему? Это в UIViewRepresentable, который не ведет себя, как я ожидал? Поскольку пакет существует уже много лет, и чистый код UIKit не сталкивается с этой проблемой, я почти уверен, что проблема в коде UIViewRepresentable.

В init для MultiSelectSegmentedControl есть следующий код установки:

   private func setup() {
        addConstrainedSubview(borderView, constrain: .top, .bottom, .left, .right)
        addConstrainedSubview(stackView, constrain: .top, .bottom)
        constrain(stackView, at: .left, to: borderView, diff: 1)
        constrain(stackView, at: .right, to: borderView, diff: -1)
        clipsToBounds = true
        stackView.distribution = .fillEqually
        borderWidth = { borderWidth }()
        borderRadius = { borderRadius }()
        tintColorDidChange()
        borderView.isUserInteractionEnabled = false
        addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTap)))
        accessibilityIdentifier = "MultiSelectSegmentedControl"
    }

В MultiSegmentPicker: UIViewRepresentable init Я нахожу следующий код, связанный с ограничениями:

   public init(
        selectedSegmentIndexes: Binding<IndexSet>,
        items: [Any],
        allowsMultipleSelection: Bool? = nil,
        borderWidth: CGFloat? = nil,
        borderRadius: CGFloat? = nil,
        isVertical: Bool? = nil,
        isVerticalSegmentContents: Bool? = nil,
        selectedBackgroundColor: UIColor? = nil
    ) {
       _selectedSegmentIndexes = selectedSegmentIndexes
        uiView = MultiSelectSegmentedControl(items: items)
        uiView.translatesAutoresizingMaskIntoConstraints = false

        uiView.allowsMultipleSelection =? allowsMultipleSelection
        uiView.borderWidth =? borderWidth
        uiView.borderRadius =? borderRadius
        uiView.isVertical =? isVertical
        uiView.isVerticalSegmentContents =? isVerticalSegmentContents
        uiView.selectedBackgroundColor =? selectedBackgroundColor
       }

Кроме того, представления сегментов MultiSelectSegment: UIView используйте этот код:

    private func setup() {
    addConstrainedSubview(stackView, constrain: .topMargin, .bottomMargin, .leftMargin, .rightMargin)
    layoutMargins = UIEdgeInsets(top: 7, left: 7, bottom: 7, right: 7)
    stackView.spacing = layoutMargins.left
    stackView.isUserInteractionEnabled = false
    stackView.alignment = .center
    isAccessibilityElement = true
    accessibilityTraits = [.button]
    accessibilityIdentifier = "MultiSelectSegment"
}

Вот код, который демонстрирует проблему, показанную выше:

   var body: some View {
        VStack(alignment: .center) {
            Text("top")
            Spacer()
            MultiSegmentPicker(
                selectedSegmentIndexes: $selectedSegmentIndexes,
                items: ["First", "Second", "Third", "Done"]
            ).fixedSize()
            Text("bottom")
        }
    }
}

Что я ожидал от этого кода, так это то, что столбец с «First», «Second» и т. Д. c. будет располагаться по центру снизу, а не сдвигаться к задней кромке, и что он будет выше , а не позади в текстовом представлении, отображающем «низ»

=== РЕДАКТИРОВАТЬ === Вот вид со снятой проставкой и выравниванием .center.

Может быть полезно увидеть разницу ...

enter image description here

=== РЕДАКТИРОВАТЬ 2 ==

Я хочу показать немного более «неожиданное» поведение. Когда вы думаете об этом, это совсем не неожиданно. Мультиселектор был расположен правильно, но скрыт от большого взгляда. Когда после Multiselector я добавил обычный объект Picker (), мультиселектор заглядывает сквозь ... Но эти две картинки многое объясняют:

enter image description here

enter image description here

== Редактировать 3 ==

Йонат исправил эту ошибку, теперь она работает, как и ожидалось! (спасибо!)

enter image description here

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

Проблема, похоже, была с intrinsicContentSize. Я изменил в версии 2.3.3 элемента управления, и теперь fixedSize() отлично работает.

0 голосов
/ 16 апреля 2020

Выравнивание: .center центрирует передний край сборщика, удалите его из VSTack.

удалите Spacer (), и он не будет отставать, но, поскольку он настроен как stackView, SwiftUI не будет автоматически позиционировать его относительно других элементов.

...