继承带有“依赖项”的CustomViewController的正确方法

时间:2019-04-29 13:17:42

标签: ios swift uiview uiviewcontroller

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

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

如果我与XIB文件一起创建新文件backgroundPicture: UIView,则可以在XIB中添加CommonViewController图像视图,并将其与代码连接(通过常规的“控制-拖动”方法),但是显然这是行不通的,因为不能保证继承backgroundPicture的视图将具有此属性。在Swift中没有iOS上的hacks的情况下解决此问题的正确方法是什么?

不幸的是,我找不到解决方案,也许我一直在寻找问题。看来我需要以某种方式为每个场景(每个CommonViewController)继承一个CommonViewController,但是我还必须以某种方式将每个控制器的顶视图设置为等于某个{{1 }},这样在我尝试访问CustomViewControllerCommonView不会崩溃。


一种明显的方法是在CommonViewController中定义一些方法或属性,以便继承该方法或属性的控制器可以实现/覆盖它,但这似乎有点棘手,因为它仍然需要复制粘贴。每个继承@IBOutlet weak var backgroundPicutre: UIImageView!的{​​{1}}。

我对解决方案的想象:创建CommonViewController,然后在Storyboard中创建一个视图控制器,并将“ Class”属性更改为“ CustomViewController”(在属性编辑器中),然后选择对应的视图到此新添加的控制器,并将“ Class”属性更改为“ BackgroundImageView ViewController CustomViewController CommonViewController IBOutlet CustomViewController: CommonViewController bakcgroundImageView . But I'm not sure if it's the correct way to do (also I doubt that UIView will properly "connect" its BackgroundImageView`,这就是为什么我想问问专家他们对此有何看法。

1 个答案:

答案 0 :(得分:1)

我认为您应该在代码中完整地定义基本控制器(CommonViewController),即,不要在基本控制器中不使用xibs / storyboard。这并不意味着您应该完全摆脱情节提要/ xibs。除CommonViewController之外的所有其他视图控制器的接口仍可以使用xib /情节提要实现。

在这种情况下,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
    }
}