从网络堆栈过渡到 iOS仙境,我发现很难理解如何重新构建我对MVC的想法并在iOS上有效地构建我的UI
考虑使用以下内容构建我的self.view
视图的最佳方式是什么?
UIView
类UIViewController
形式发布的视图,其关联的UIView
类。 UIViewController
UIView
视图
------------------------------
| A |
| |
| -------------------- |
| | B | |
| | | |
| | -------------- | |
| | | C | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | -------------- | |
| | | |
| -------------------- |
| |
------------------------------
A
可能[self addView:B_view]
(如果B只是UIView)A
也可能[self addView:B_viewController.view]
(如果B有视图控制器)A
也可能[B setChildView:C_view]
B_viewController.delegate = A
& C_viewController.delegate = A
B_viewController.delegate = A
& C_view.delegate = B
逻辑分散在委托,viewControllers和视图。
除了可以改善以上经验的“抽象井和关注点分离”。我相信它的viewController和viewController.view的组合很容易引起广泛的耦合。
这很快变得令人困惑,感觉就像意大利面,尽管付出了努力但很难控制。
那就是说,
答案 0 :(得分:3)
我没有在stackoverflow上提出类似的广泛问题 - 似乎社区偏爱更具体的技术问题。但我会试一试。请记住,以下所有内容都是我的意见,而不是硬性规定。
我觉得这是关于消息传递和设计模式的复合问题。在组件通信方面(无论是视图还是控制器),有很多方法可以实现,每个方法都有+
和-
(或者更确切地说是用例)。有:委托,响应链,块,通知,反应信号 - 仅举几例。
self.superview
或self.parentViewController
(有人说甚至是self.navigationController
)时,它可能违反了封装,并且有一个更好的方式。以下几项随机观察可能会导致您某处(或可能不会)。
在我看来,MVC对于小型项目来说是一个很好的模式(很容易从"简单到简单")。但是从个人经验来看,当你正在进行的屏幕的复杂性增加时,它很快就会失控。趋势是控制器处理从用户交互到网络的所有事情,它真的很快成为一个1k长的怪物。
令人遗憾的是,iOS架构中很多都依赖于UIViewController
。通常它不可避免地成为您的代码与操作系统的第一联系点,但它不必在内部处理所有内容。相反,它可以将责任转移到适当的组件,即
func loginButtonDidTap(_ sender: UIButton) {
loginManager.beginLogin(from: self)
analytics.reportLogin(with: sender)
// ...
}
我没有从你的描述中注意到,但如果你更喜欢使用MVC,那么组合控制器是一个完全有效的选择。在为iPad构建时这是一种非常常见的情况,但即使在iPhone上,每个屏幕都可以轻松地包含完全独立的部分,其中每个部分都是单独的ViewController
,那么您应该查看所谓的" ; UIViewController包含"。大多数情况下,它允许更好的分离和重用,但同样,并不能解决主要问题。
如果您正在阅读本文,那么您非常渴望学习。在这种情况下,我建议您不要停止使用MVC。有许多有趣的设计模式可能适合或不适合您的特定需求。 MVVM(是?)非常受欢迎。最近,单向流动似乎是新的热点。灵感来自JS的Redux。这与MVC非常不同,如果您有兴趣,我建议您检查此项目https://github.com/ReSwift/ReSwift。
可悲的是,任何建筑问题都没有对错 - 只有对你和你的团队有用的东西才有用。而且我喜欢在问题被关闭之前听到其他观点,因为太宽泛了#34;
很抱歉,如果这完全不符合您的要求,请告诉我您是否有任何特殊方面需要讨论。
答案 1 :(得分:3)
也许,你正在处理的是MVC - 大规模视图控制器的困境。这是一个有趣的读物,Marcus谈到通过将代码放在它所属的地方,网络层,持久层或表示层(理想情况下是viewcontroller)来有效地管理代码。
http://www.cimgf.com/2015/09/21/massive-view-controllers/
除了委托模式之外,我们还有基于块/闭包的方法,可能有助于清理代码。
总的来说,Robert C. Martin的清洁代码方法在这里可能会有所帮助。通过称为VIPER架构的方式实现它的方法。这是一个关于它的教程。
https://www.objc.io/issues/13-architecture/viper/
目标C,作为一种语言包含授权模式,并且将其用于大多数人的关注是一种标准做法。
欢迎使用iOS平台。
答案 2 :(得分:1)
您可以拥有一个ViewController
将UIViews分隔为ViewController。它不应该与viewController紧密结合。
让您的View登录自己的UIView类。创建自己的委托和协议。并在任何viewcontroller中使用它。
将viewcontroller添加到viewcontroller不是一个好的解决方案。
您也可以转移到MVVM,其中每个视图的视图模型都有其逻辑部分,但在开始时可能会让人感到困惑。
尝试将UIViews分隔为ViewControllers。
答案 3 :(得分:1)
作为一个已经完成了相当数量的iOS编程并且现在花费大量时间进行角度开发的人,这里有一些简单的想法:
UIView
代表基本的屏幕构建块;也就是说,它会破坏视图,某些数据以及在视图上呈现该数据的逻辑。因此,它可以用于绘制一些文本或图形,或者它可以包含任意数量的具有相同能力的子视图。在Angular世界中,UIView
将(某种程度上)等同于封装Component
,HTML
,CSS
等的JavaScript
,但也可能包含UILabel
其他组件。
如您所知,iOS提供了许多预构建的本机UIView,UIButton
,UITable
,UIViewController
等,这些适用于大量应用程序需要。
UIView
具有比UIView
更多的结构功能。它与导航框架集成,以便开发人员可以快速更改用户的上下文。它包含一个" main" UIView's
,作为上下文的基础平台,包含任意数量的本机和自定义UIViews
。其目的是在给定当前应用程序上下文的情况下帮助配置UIViewController
。
如果UIView
正在以不限于当前应用上下文的方式配置UIView
,那么NSNotification
可能应该扩展为自定义对象。这样它就可以自我管理,并且更容易在其他环境中重用。
另一件事:
代表在适当的时候很棒,但if [[ ! $value =~ ^\$ ]];
是一种简单,强大的方法来观察变化,同时避免对象依赖的意外。