编辑:正如sunshinejr指出的here,此问题已修复,将与下一个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中设置)的委托,但是在滚动任何视图(ParentScrollView或ChildScrollView)时不会调用委托方法(例如scrollViewDidEndDecelerating
)。 ViewController
的基类符合UIScrollViewDelegate
。
我尝试在代码中设置委托,但我不知道自己可能做错了什么。该转换未更改该类中的任何代码,但是在更新之前一切正常。在Swift 5 Release Notes中,我通常也找不到手势,委托或ScrollView的任何更改。
这似乎是Swift 5编译器的错误。此外,有时它确实可以工作,有时却不起作用-全部都无需更改任何代码或项目设置。
为什么这不再起作用?还有其他人经历过类似的行为吗?
答案 0 :(得分:14)
编辑:正如sunshinejr指出的here,此问题已修复,将与下一个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会改变这种行为,但是至少我找到了解决方案。也许有人可以提供进一步的见解?
答案 1 :(得分:2)
类似的问题看起来也早在2016年就已存在,并已解决在某一点:https://bugs.swift.org/browse/SR-2919
答案 2 :(得分:1)
从4.2(Xcode 10.1)更新到5.0(Xcode 10.2)后,我们也遇到同样的问题。在我们的例子中,它是UITableViewDelegate。父类在UITableViewDelegate中实现与滚动相关的方法,但是,在子类中实现此委托与表视图相关的方法(例如DidSelect RowAtIndex)。在我们使用Swift 5更新到XCode 10.2之前,没有问题地调用了子类中的方法。
由Jan Schlorf建议在子类中重写委托方法可以解决此问题。
答案 3 :(得分:1)
我们遇到了一个UITextViewDelegate
另一种解决方法是将@objc
标记添加到超类中的方法
答案 4 :(得分:1)
正如Jan所指出的,这是Swift 5回归。可以在Swift的JIRA和雷达(rdar:// problem / 49482328)上进行跟踪。该问题也已经修复(PR here),但是我们需要等待下一个Xcode / Swift版本。
答案 5 :(得分:1)
在升级到Xcode 10.2之后,我仅在发布方案上遇到了相同的问题。我还测试了Xcode 10.3,它的行为完全相同。
对于那些不想在委托实现中到处添加@objc的人。
快速的解决方案是在构建设置中禁用Swift 5编译器优化:
对于那些已经升级到Xcode 10.3的人来说,似乎不再可以看到此构建设置选项,但是您仍然可以直接通过项目的pbxproj文件对其进行更改,并且此后应在xcode UI中显示。
SWIFT_COMPILATION_MODE = singlefile;
答案 6 :(得分:0)
由于所有UIScrollViewDelegate
方法都是可选的,因此如果编译器认为您没有实现它们,则永远不会看到编译器的错误,最有可能发生的是Apple在Swift 5中再次更改了方法签名(再次)出于某种原因迁移工具无法使用。
检查方法名称以及更新到USwift 5文档的UIScrollViewDelegate
,您会发现您的方法名称可能不同,只需更正它们,一切便会再次正常工作。