与后面的视图控制器交互

时间:2017-06-08 11:59:51

标签: ios swift uiviewcontroller

我知道SE上有几个与此问题相关的帖子,但我无法绕过他们找到适合我情况的解决方案。

我在视图控制器中有一个地图视图。我正在呈现另一个视图控制器,modalPresentationStyle设置为custom(将卡片视图容纳在地图视图VC顶部):

Location Card on Map View

对于这种情况,我想要的是,当位置卡视图与位置卡一起呈现时仍然能够识别触摸的地图视图仍然识别其内部的触摸。就像下面的列表视图一样,Apple Maps的功能就像。

我知道我无法通过视图控制器传递触摸但我无法在两者之间做出决定:

  • 将位置卡转储到我非常不喜欢的地图视图中,
  • 通过addChildViewController展示位置卡,我不太确定如何实现,以达到我想要的效果。

This SE question给出了一个详细的答案和一个关于模仿Apple Maps界面的小样本项目,尽管我仍然无法弄清楚如何解决我的问题。

2 个答案:

答案 0 :(得分:1)

我选择将位置卡视图转储到地图视图中。 但是我不喜欢它。

事情是,我不想在地图视图中找到位置卡的任何逻辑。但与此同时,iOS没有提供基础设施和视图控制器之间的触摸传输基本上是不可能的,建议的解决方案似乎很难实现。

首先,我将位置卡视图从视图控制器迁移到结构。

然后,我定义了一个名为LocationCardPresentable的协议,在扩展时,要求SelfMapVC类型。因此,在协议扩展中,我可以像在MapVC内部一样工作,但实际上并非如此。协议扩展有各种方法来显示和解除我可以从MapVC内部调用的位置卡。

答案 1 :(得分:0)

所以我刚刚通过结合使用 loadView() point(inside)来替换现有ViewController中的rootView来解决这个问题。

首先,创建一个UIView的子类,您将在任何ViewControllers中用作rootView,您希望在下面的ViewControllers上传递触摸:

<强> IgnoreTouchesView

import UIKit

类IgnoreTouchesView:UIView {

override init(frame: CGRect) {
    super.init(frame: frame)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    for view in self.subviews {
        if view.isKind(of: UIButton) {
            let foundButtonView = view

            if foundButtonView.isUserInteractionEnabled && !foundButtonView.isHidden && foundButtonView.point(inside: self.convert(point, to: foundButtonView), with: event) {
                return true
            }
        }
    }

    return false
}

点(内部)功能检查用户是否点击OverlayVC中的任何UIButton,在这种情况下仍应处理触摸。任何其他触摸都会传递给下面的VC。这可以通过忽略rootView来完成,但我还没有想出安静如何做到这一点。

然后,在要显示的VC中,添加以下内容:

let ignoreView: IgnoreTouchesView = {
    let view = IgnoreTouchesView(frame: .zero)
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

override func loadView() {
    view = ignoreView
}

现在将ViewControllers添加到原始ViewController:

lazy var overlayVC : OverlayVC = {
    let vc = SongOverlayVC()
    vc.view.translatesAutoresizingMaskIntoConstraints = false
    vc.delegate = self
    return vc
}()

viewDidLoad(){
    view.addSubview(songOverlayVC.view)
}

就是这样:)

如果您遇到任何问题,请告诉我。