代码之家  ›  专栏  ›  技术社区  ›  Jan Erik Schlorf DavidLio

在更新到swift 5和xcode 10.0兼容性后未调用ScrollView委托方法

  •  0
  • Jan Erik Schlorf DavidLio  · 技术社区  · 7 年前

    在将Xcode10.1更新为Xcode10.2之后,我看到了许多奇怪的行为,这两种代码都使用了Swift4和Swift5代码基。

    其中一个问题是,在一个视图控制器上,不再调用ScrollView委托方法。简化的视图层次结构如下:

    | ScrollView (ParentScrollView)
    | -- Stack View
    | ---- ScrollView (ChildScrollView)
    | ---- ScrollView (ChildScrollView)
    | ---- ScrollView (ChildScrollView)
    

    它作为一个包含多个页面的视图: ParentScrollView 可以水平滚动, ChildScrollView 垂直方向。

    viewController是所有滚动视图(在情节提要中设置)的委托,但委托方法(如 scrollViewDidEndDecelerating )在滚动任何视图(ParentScrollView或ChildScrollView)时不调用。这个 基本类 属于 ViewController 符合 UIScrollViewDelegate .

    我试过用代码设置代理,但我不知道我可能做错了什么。转换并没有更改类中的任何代码,但是在更新之前,一切都工作得很好。我也无法在 Swift 5 Release Notes .

    这似乎是Swift5编译器的一个错误。此外,有时它确实工作,有时它不工作-所有没有更改任何代码或项目设置。

    为什么这不再有效?其他人也有过类似的行为吗?

    0 回复  |  直到 7 年前
        1
  •  13
  •   Jan Erik Schlorf DavidLio    7 年前

    我发现了这个问题,下面是如何复制它。

    class A: UIViewController, UIScrollViewDelegate {
        // ...does not implement 'scrollViewDidEndDecelerating'
    }
    
    class B: A {
        func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            // Will not be called!
        }
    }
    

    什么有用:

    class A: UIViewController, UIScrollViewDelegate {
        func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            // Probably empty
        }
    }
    
    class B: A {
        override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            // Will be called!
        }
    }
    

    编译器似乎认为,如果基类没有实现委托方法,则不会实现该方法。如果只有子类实现它,它就找不到它。

    我仍然无法解释为什么这种行为会随着Swift5而改变,但至少我找到了解决办法。也许有人能提供进一步的见解?

        2
  •  2
  •   eito    7 年前

    看来这个问题早在2016年就存在了,而且已经解决了一个问题: https://bugs.swift.org/browse/SR-2919

        3
  •  1
  •   casey    7 年前

    在从4.2(Xcode10.1)更新到5.0(Xcode10.2)之后,我们也遇到了同样的问题。在我们的例子中,它是UITableViewDelegate。父类在UITableViewDelegate中实现与滚动相关的方法,但是,此委托的TableView相关方法(如Didselect Rowatindex)在子类中实现。在我们用swift 5更新到xcode 10.2之前,子类中的方法被无问题地调用。

    重写jan schlorf建议的子类中的委托方法解决了这个问题。

        4
  •  1
  •   ndis1    7 年前

    我们遇到了一个UITextViewDelegate

    另一个解决方法是添加 @objc 标记到超类中的方法

        5
  •  0
  •   Andrea    7 年前

    因为所有的 UIScrollViewDelegate 方法是选项,如果编译器认为您没有实现它们,那么您将永远不会看到来自编译器的错误,最可能的情况是Apple在Swift 5中(再次)更改了方法签名,并且由于某种原因迁移工具无法工作。
    检查方法名称以及 滚动视图委托 更新到uswift 5文档后,您将看到您的方法名称可能有所不同,只需更正它们,一切都将重新工作。