1

我在 Swift 中使用 iOS 上的 Mapbox 框架来创建自定义 NavigationViewController。我需要帮助以获取FloatingStackViewNavigationView.

我添加了一个额外的按钮(参见屏幕截图的左上角),我想将它锚定到右侧的 FloatingStackView 上,以便它随着顶部横幅的变化而上下移动(类似于 FloatingStackView 的行为)。问题是我似乎无法访问 FloatingStackView。从我在 Mapbox 源代码中看到的内容来看,这FloatingStackView是 a 的子视图,它是NavigationViewControllerNavigationView的视图。问题是我无法访问 mapViewController,因为它由于内部保护级别而无法访问。RouteMapViewControllermapViewController

这是我想做的一个例子:

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

如果我能获得对该 floatingStackView 的引用,我想我可以处理布局。

如何绕过is inaccessible due to 'internal' protection level错误或找到另一种访问浮动堆栈视图的方法?

截屏

来自 NavigationView 类源代码

导航视图类

4

1 回答 1

1

如果它被标记为内部,您将无法直接引用它。然而,有一种 hacky 方法可以访问任何视图并将其用于 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

如果你没有可以匹配的类型,你将不得不做一些更hacky的事情,比如匹配描述: .first{$0.description conatins "stack"}。或者甚至通过对 subView 数组进行索引来反复试验,直到获得所需的结果,然后希望视图的顺序始终相同!

您是否想在生产代码中冒这个风险只是您可以做出的决定,因为如果库更改它的 UI 设计,它会受到破坏。根据应用程序的用户群,我可能会冒险匹配类型,但可能不是其他方式!

请注意,为简洁起见,我已强制展开上面的视图 - 您也希望在生产代码中更加谨慎:-)

于 2019-11-07T15:09:52.193 回答