ios - 使用 "dependencies"继承自定义 ViewController 的正确方法

标签 ios swift uiview uiviewcontroller

最近我写了一个只有一个场景和 ViewController 的应用程序。我必须为 View 设置自定义背景图片,由 ViewController 管理(即我的顶 View 包含 UIImageView)。后来我不得不在 ViewController 中实现一些逻辑,以便它在屏幕旋转时正确地旋转/更改图片。此外,我还必须为 ViewController 覆盖一些属性,例如 preferredStatusBarStyle

现在我必须在我的应用程序中实现更多场景/屏幕,事实证明它们都必须与当前显示的屏幕具有相同的设计,所以我认为创建一个 CommonViewController< 是有意义的 包含背景图片的这个通用旋转相关逻辑,因此我可以从这个 CommonViewController 继承所有其他 ViewController。我遇到的唯一问题是 CommonViewController“要求”它管理的 View 具有 backgroundPicture: UIView 属性,我不知道如何确保这一点。

如果我创建一个新文件 CommonViewController 和 XIB 文件,我可以在 XIB 中添加 backgroundPicture ImageView 并将其与代码连接(通过常规的“control- drag"方法),但显然这是行不通的,因为不能保证继承 CommonViewController 的 View 将具有此属性。在 Swift 的 iOS 上没有 hack 的情况下解决这个问题的正确方法是什么?

不幸的是我找不到解决方案,也许我一直在寻找错误的东西。似乎我需要以某种方式为每个场景(对于每个 CustomViewController)继承一个 CommonViewController,而且我还必须以某种方式将每个 Controller 的顶 View 设置为等于某些 CommonView,这样当我尝试访问 @IBOutlet weak var backgroundPicutre: UIImageView! 时,CommonViewController 不会崩溃。


显而易见的方法是在 CommonViewController 中定义一些方法或属性,以便继承它的 Controller 可以实现/覆盖它,但它似乎有点 hacky,因为它仍然需要复制- 粘贴到每个继承 CommonViewControllerViewController

我是如何想象解决方案的:我创建了 CustomViewController: CommonViewController,然后在我的 Storyboard 中创建了一个 View Controller 并将“Class”属性更改为“CustomViewController”(在属性编辑器中),然后我选择与这个新添加的 Controller 对应的 View 并将“Class”属性更改为“BackgroundImageView。但我不确定这是否是正确的方法(我也怀疑CustomViewController将正确地“连接”它的IBOutlet字段bakcgroundImageView与相应的UIViewfromBackgroundImageView`,这就是为什么我想问专家什么他们会考虑。

最佳答案

我认为您应该完全在代码中定义您的基本 Controller (CommonViewController),即不要对基本 Controller 使用任何 xibs/ Storyboard。这并不意味着您应该完全摆脱 Storyboard/xib。除 CommonViewController 之外的所有其他 View Controller 的接口(interface)仍可使用 xibs/storyboards 实现。

在这种情况下,CommonViewController 实现可能如下所示:

import UIKit

class CommonViewController: UIViewController {
    // use this property every time you need to 
    // manipulate backgroundPicture
    var backgroundPicture: UIImageView  = {
        // Replace with your image name
        let image = UIImage(named: "BackgroundPicture")!
        let imageView = UIImageView()
        imageView.image = image
        return imageView
    }()

    override func viewDidLoad() {
        // If subclass overrides viewDidLoad() 
        // it should contain super.viewDidLoad()
        super.viewDidLoad()

        view.addSubview(backgroundPicture)

        // Align backgroundPicture to bounds of superview
        // You can remove this code and implement
        // your own alignment with frames or Autolayout
        backgroundPicture.frame = view.bounds

        // Send backgroundPicture to back of the view
        // Otherwise backgroundPicture may overlap views added in subclasses
        view.sendSubviewToBack(backgroundPicture)
    }
    
    override func viewDidLayoutSubviews() {
        // If subclass overrides viewDidLayoutSubviews()
        // It should contain super.viewDidLayoutSubviews() 
        super.viewDidLayoutSubvews()

        // Align backgroundPicture to bounds of superview
        // You can remove this code and implement
        // your own alignment with frames or Autolayout
        backgroundPicture.frame = view.bounds
    }
}

关于ios - 使用 "dependencies"继承自定义 ViewController 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55904238/

相关文章:

c# - 将 InputAccessoryView 设置为 UISearchController

swift - 如何在应用了渐变的 UIView 中添加圆角?

ios - UIView 中的 UIButton 目标操作

ios - Mapkit 带有 pin 的新注释,没有弹出窗口

ios - 内容更改时 WKWebView 不调整大小

iphone - 缩放 UIScrollView(不仅仅是其内容)

swift - 在 Swift 中初始化 UIViews 的惯用模式

Swift:以其他语言显示 Date()

Swift 'text' 不可用 : APIs deprecated as of iOS7. textLabel 不起作用

swift - 关闭 UIAlertController 后如何重新加载 UIView