Привязка пользовательских видов к существующему виду в Mapbox NavigationViewController в Swift - PullRequest
0 голосов
/ 07 ноября 2019

Я использую каркас Mapbox на iOS в Swift, чтобы создать собственный NavigationViewController. Мне нужна помощь в получении ссылки на FloatingStackView на NavigationView.

. Я добавил дополнительную кнопку (см. Верхний левый снимок экрана) и хочу привязать ее к FloatingStackView напрямо так, что он перемещается вверх и вниз при изменении верхнего баннера (аналогично поведению FloatingStackView). Проблема в том, что я не могу получить доступ к FloatingStackView. Из того, что я видел в исходном коде Mapbox, FloatingStackView является подпредставлением NavigationView, которое является представлением RouteMapViewController, которое является mapViewController NavigationViewController. Проблема в том, что я не могу получить доступ к mapViewController, так как он недоступен из-за уровня внутренней защиты.

Вот пример того, что я хотел бы сделать:

import UIKit
import MapboxNavigation

class DemoNavigationViewController: NavigationViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let mapVC = mapViewController
        // Do any additional setup after loading the view.
    }

}

Вот ошибка настрока let mapVC:

'mapViewController' is inaccessible due to 'internal' protection level

Моя конечная цель - получить доступ к FloatingStackView через что-то вроде этого:

let navigationView = mapViewController.view as? NavigationView
let floatingStackView = navigationView.floatingStackView

Если я смогу получить ссылку на этот плавающийStackView Iдумаю, я справлюсь с макетом.

Как обойти ошибку is inaccessible due to 'internal' protection level или найти другой способ доступа к представлению плавающего стека?

screenshot

Из исходного кода класса NavigationView

NavigationViewClass

1 Ответ

1 голос
/ 07 ноября 2019

Вы не сможете ссылаться на него напрямую, если он помечен как внутренний. Однако существует хакерский способ получить любой вид и использовать его для AutoLayout (при условии, что вид использует autoLayout и имеет привязки, которые вы можете использовать).

Поскольку каждое представление имеет массив subViews, который вы можете перебиратьподвиды, чтобы найти тот, который вы хотите. Все подпредставления видны, даже те, которые происходят из частных экземпляров. Хитрость заключается в определении того, что вам нужно.

Если определение типа доступно, вы можете сделать что-то вроде этого

let navView = viewController.subViews.first{$0 is NavigationView}!
let stackView = navView.subViews.first{$0 is UIStackView}!
floatingButton.topAnchor.constraint(equalTo: stackView.topAnchor).isActive  true

Если у вас нет типа, который можно сопоставить с вамиПридется сделать что-то еще более хакерское, например сопоставить с описанием: .first{$0.description conatins "stack"}. Или даже методом проб и ошибок, индексируя массив subView до тех пор, пока вы не получите желаемый результат, а затем надеетесь, что порядок представлений всегда одинаков!

Если вы хотите рискнуть этим в рабочем коде, это толькорешение, которое вы можете принять, поскольку оно может быть взломано, если библиотека изменит свой дизайн пользовательского интерфейса. В зависимости от пользовательской базы приложения, я могу рискнуть сопоставить данные с типом, но, вероятно, не с другими способами!

Примечание. Для краткости я развернул приведенные выше представления принудительно - вам нужно быть немного осторожнее впроизводственный код с этим тоже: -)

...