18

编辑:正如sunjr在这里指出的那样,这已得到修复,并将与下一个 Xcode/Swift 版本一起发布。


在使用 Swift 4 和 Swift 5 代码库将 Xcode 10.1 更新到 Xcode 10.2 后,我看到了很多奇怪的行为。

问题之一是在一个 ViewController 上不再调用 ScrollView 委托方法。简化的视图层次结构如下:

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

它充当具有多个页面的视图:ParentScrollView可以水平滚动,可以ChildScrollView垂直滚动。

ViewController 是所有 Scrollview 的委托(在 Storyboard 中设置),但scrollViewDidEndDecelerating在滚动任何视图(ParentScrollView 或 ChildScrollView)时不会调用委托方法(如 )。的ViewController符合UIScrollViewDelegate.

我曾尝试在代码中设置代表,除此之外我不知道我可能做错了什么。转换没有更改类中的任何代码,但在更新之前一切正常。我在Swift 5 Release Notes中也找不到对手势、代表或 ScrollViews 的一般更改。

这似乎是 Swift 5 编译器的一个错误。此外,有时它确实有效,有时则无效——所有这些都无需更改任何代码或项目设置。

为什么这不再起作用?有没有其他人经历过类似的行为?

4

6 回答 6

22

编辑:正如sunjr在这里指出的那样,这已得到修复,并将与下一个 Xcode/Swift 版本一起发布。


我找到了问题,这里是如何重现它。

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!
    }
}

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

我仍然无法解释为什么 Swift 5 会改变这种行为,但至少我找到了解决方案。也许有人可以提供进一步的见解?

于 2019-03-28T09:18:11.190 回答
4

我们使用 UITextViewDelegate 遇到了这个问题

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

于 2019-04-12T13:41:51.433 回答
3

看起来这个问题早在 2016 年也存在,并且在某一时刻得到了修复:https ://bugs.swift.org/browse/SR-2919

于 2019-04-17T17:31:04.663 回答
3

正如 Jan 指出的,这是 Swift 5 的回归。这在 Swift 的JIRA和雷达 (rdar://problem/49482328) 上进行了跟踪。这也已经修复(此处为 PR),但我们需要等待下一个 Xcode/Swift 版本。

编辑:从 Xcode 10.3 开始,我们观察到该错误已修复,但我们仍在监视它是否已永久修复。

于 2019-05-29T10:18:42.583 回答
1

升级到 Xcode 10.2 后,我仅在发布方案中遇到了同样的问题。我还测试了 Xcode 10.3,它的行为完全相同。

对于那些不想在委托实现中到处添加 @objc 的人。

快速的解决方案是在构建设置中禁用 Swift 5 编译器优化:

在此处输入图像描述

对于已经升级到 Xcode 10.3 的用户,这个构建设置选项似乎不再可见,但您仍然可以通过项目的 pbxproj 文件直接更改它,之后它应该会出现在 xcode UI 中。 SWIFT_COMPILATION_MODE = singlefile;

在此处输入图像描述

于 2019-07-30T05:59:35.157 回答
0

由于所有UIScrollViewDelegate方法都是可选的,如果编译器认为您没有实现它们,您将永远不会看到来自编译器的错误,最有可能发生的事情是 Apple (再次)更改了 Swift 5 中的方法签名,并且由于某种原因迁移工具没有不行。
检查方法名称以及UIScrollViewDelegate更新到 USwift 5 的文档,您会发现您的方法名称可能不同,只需更正它们,一切都会再次正常工作。

于 2019-03-28T08:52:17.443 回答