玩Swift ..故事板Segues
《玩转周围》是一篇实验性文章,探讨了Swift中不同的处理方式。 在一个项目中表现出色的技术在下一个项目中可能并不理想,因此,这些文章将很少讨论什么是做事的最佳方法,而更多是关于做事的更好方法。
如果您使用情节提要,您可能会看到类似以下内容:
覆盖func prepare(用于segue:UIStoryboardSegue,发件人:任意?){
如果segue.identifier ==“ pushMovie” {
让电影=电影[tableView.indexPathForSelectedRow!.row]
让movieVC = segue.destination作为! MovieViewController
movieVC.movie =电影
}否则,如果segue.identifier ==“ addMovie” {
让movieFormNC = segue.destination作为! UINavigationController
让movieFormVC = movieFormNC.viewControllers.first作为! MovieFormViewController
movieFormVC.delegate =自我
}
}
这段代码确实还不错。 它可能会给我们的视图控制器增加不必要的膨胀? 并且可以肯定,我们会错误地复制segue标识符。 我们必须进行一些强制施法。 但是,任何错误都会在我们看到运行时错误后立即解决。
尽管进行了合理化,但让我们看看是否可以使其变得更好……
首先,让我们看看Google是否可以帮助我们。
这使我想到了2015年的Natasha The Robot博客文章(猜测我们来晚了),她在WWDC会话中进行了详细阐述(希望您单击该链接就使用Safari),以解决此问题。
此技术利用协议扩展。
- 创建一个类型以将我们的segue标识符表示为枚举
Segues协议{
relatedtype SegueIdentifier:RawRepresentable
}
2.扩展协议,限制它只能在UIViewController上使用
扩展Segues,其中Self:UIViewController,SegueIdentifier.RawValue ==字符串{
//方法来
}
3.添加一个接受我们的SegueIdentifier
类型的performSegue
方法,并将其rawValue
传递给默认的performSegue
方法
func performSegue(withIdentifier标识符:SegueIdentifier,发件人:任何?){
performSegue(withIdentifier:identifier.rawValue,发送者:发送者)
}
4.添加一个函数,该函数返回给定UIStoryboardSegue
SegueIdentifier
类型
func segueId(用于segue:UIStoryboardSegue)-> SegueIdentifier {
守护
让标识符= segue.identifier,
让segueIdentifier = SegueIdentifier(rawValue:标识符)
否则{fatalError()}
返回segueIdentifier
}
我们最终得到这样的结果:
现在让我们看看如何清理我们的视图控制器…
首先,我们将在表视图控制器上编写一个扩展并声明我们的命令。
扩展MoviesViewController:Segues {
枚举SegueIdentifier:字符串{
案例pushMovie,addMovie
}
}
调用performSegue
我们使用enum
而不是字符串。
performSegue(withIdentifier:.pushMovie,发送者:indexPath.row)
然后,在prepare:for
函数中,我们可以switch
从segueId:for
函数获得的segueId:for
。
我们的语法更好一些,编译器将确保我们处理所有segue情况。 但是,我们仍然需要强制转换,并且我们的视图控制器负责了解呈现的内容。
最好通过在枚举案例中获取视图控制器来消除强制转换( case .pushMovie(let movieVC)
),但是这给我带来了太多的实现头痛,因为它们无法消除糟糕as!
声明。 如果您实施了此操作,我将很乐意为您提供帮助。 🙏