UIViewControllerRepresentable height слишком велик
Я пытаюсь добавить контекстное меню UIKit в представление SwiftUI, потому что контекстное меню SwiftUI довольно ограничено. Мне это удалось, но UIViewControllerRepresentable занимает больше места, чем нужно. Как я могу изменить его размер, чтобы он соответствовал содержимому внутри него? Вот мой код.
Код SwiftUI
struct TrackerCard: View {
var tracker: Tracker
var body: some View {
HStack {
HStack {
...
}
.padding()
.background(Color("Wrapper"))
.cornerRadius(15)
}
.padding(.horizontal)
}
}
struct TrackerCardView: View {
var tracker: Tracker
var body: some View {
ContextMenuView(card: TrackerCard(tracker: tracker))
}
}
Код UIKit
class ContextMenuController : UIViewController, UIContextMenuInteractionDelegate {
var card: TrackerCard?
var hostingViewController: UIHostingController<TrackerCard>?
func setViewController(_ controller : UIHostingController<TrackerCard>) {
hostingViewController = controller
self.addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .init(white: 1, alpha: 1)
view.addSubview(controller.view)
controller.didMove(toParent: self)
controller.view.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
}
func setInteraction() {
let interaction = UIContextMenuInteraction(delegate: self)
hostingViewController?.view.addInteraction(interaction)
}
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
return ...
}
struct ContextMenuView: UIViewControllerRepresentable {
typealias UIViewControllerType = ContextMenuController
var card: TrackerCard
var controller : UIViewControllerType? = nil
func makeUIViewController(context: Context) -> ContextMenuController {
let contextMenuController = controller ?? ContextMenuController()
contextMenuController.card = card
return contextMenuController
}
func updateUIViewController(_ contextMenuController: ContextMenuController, context: Context) {
contextMenuController.setViewController(UIHostingController(rootView: card))
contextMenuController.setInteraction()
}
}
1 ответ
Попробуй это. Во-первых, добавьте
.fixedSize
в ваше представление SwiftUI:
ContextMenuView(card: TrackerCard(tracker: tracker))
.fixedSize(horizontal: false, vertical: true)
При этом представление не должно быть ограничено по горизонтали, но занимать столько места, сколько ему нужно по вертикали, в зависимости от его предпочтительного размера.
Но вы можете заметить, что с текущим макетом высота сжимается (вплоть до 0).
Чтобы исправить это, нам нужно установить
preferredContentSize
вот так в
UIViewController
:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let targetSize = CGSize(width: view.bounds.width, height: UIView.layoutFittingCompressedSize.height)
self.preferredContentSize = view.systemLayoutSizeFitting(targetSize)
}
Дополнительную информацию об этом см. в сообщении блога Самоопределение дочерних представлений .
Но высота все еще может быть установлена на 0. В моем случае мне пришлось добавить ограничение на высоту, чтобы предпочтительная высота вычислялась по желанию (не 0).
controller.view.heightAnchor.constraint(lessThanOrEqualTo: view.heightAnchor).isActive = true
Надеюсь, это поможет. Если нет, было бы хорошо, если бы вы отредактировали свой ответ, включив в него минимальный рабочий пример с предварительным просмотром, показывающим проблему.