Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 这是我应该创建类的时候吗?_Ios_Swift - Fatal编程技术网

Ios 这是我应该创建类的时候吗?

Ios 这是我应该创建类的时候吗?,ios,swift,Ios,Swift,我正试图抓住斯威夫特,希望得到一些建议 我有一个UIView,它存在于许多屏幕上;具体来说,它是一个使用大量元素/参数来正确设置其样式的徽标,即阴影、形状、图像等 对于我的第一个viewcontroller,我将其设置为从viewDidLoad函数调用的函数。然后在我的第二个viewcontroller中,我有相同的徽标。。。这是我的问题, 我应该从故事板加载第一个视图控制器,然后引用第二个视图控制器中的函数,还是应该让徽标成为任何一个视图控制器都可以引用的类?我的直觉告诉我这应该是一门课 提前

我正试图抓住斯威夫特,希望得到一些建议

我有一个UIView,它存在于许多屏幕上;具体来说,它是一个使用大量元素/参数来正确设置其样式的徽标,即阴影、形状、图像等

对于我的第一个viewcontroller,我将其设置为从viewDidLoad函数调用的函数。然后在我的第二个viewcontroller中,我有相同的徽标。。。这是我的问题,

我应该从故事板加载第一个视图控制器,然后引用第二个视图控制器中的函数,还是应该让徽标成为任何一个视图控制器都可以引用的类?我的直觉告诉我这应该是一门课


提前感谢

对于可重用视图,您将创建一个用于设计视图的XIB,以及一个用于实例化XIB的视图控制器类,如下所示:

class ReusableView: UIView {
    override func awakeFromNib() {
        super.awakeFromNib()

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "ReusableView", bundle: bundle)

        if let view = nib.instantiate(withOwner: self, options: nil).first as? UIView {
            view.frame = bounds
            addSubview(view)
        }
    }
}
在视图控制器中,只需在所需位置放置占位符UIView,并将其自定义类型设置为
ReusableView
。通过将此视图的插座连接到视图控制器,您可以访问视图的属性

请注意,您必须将XIB中的自定义视图属性保留为UIView,并将文件的所有者设置为
ReusableView
。否则将创建一个无限循环

警告正如我在另一个答案中指出的,不要从
awakeFromNib
中加载相同的nib,否则您将创建一个加载nib的无限循环

我想说,你的直觉是正确的。为可重用视图创建一个自定义类。如果您决定为类创建nib,我建议您从静态函数实例化它

class ReusableView: UIView {
    static func newFromNib() -> ReusableView {
        let bundle = Bundle(for: ReusableView.self)
        let nib = UINib(nibName: "ReusableView", bundle: bundle)
        guard let view = nib.instantiate(withOwner: self, options: nil).first as? ReusableView else {
            preconditionFailure("Could not instantiate ReusableView")
        }
        return view
    }
    override func awakeFromNib() {
        super.awakeFromNib()

        // Configuration ONLY if you use a Nib.
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        // Configuration if you DO NOT use a nib
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
然后,可以在视图控制器中使用它:

class ViewController: UIViewController {
    @IBOutlet weak var reusableViewContainer: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create a new instance of your reusable view
        let reusableView = ReusableView.newFromNib()

        // If not using a nib, just use the 'init(frame:)' method
//        let reusableView = ReusableView(frame: .zero)

        // Add your reusable view to the view hierarchy
        self.reusableViewContainer.addSubview(reusableView)

        // Layout your view as necessary:
        // For example, if using AutoLayout:
        self.reusableViewContainer.topAnchor.constraint(equalTo: reusableView.topAnchor).isActive = true
        self.reusableViewContainer.bottomAnchor.constraint(equalTo: reusableView.bottomAnchor).isActive = true
        self.reusableViewContainer.leadingAnchor.constraint(equalTo: reusableView.leadingAnchor).isActive = true
        self.reusableViewContainer.trailingAnchor.constraint(equalTo: reusableView.trailingAnchor).isActive = true
    }
}

当然,您不必使用容器视图。将其放置在视图层次结构中需要的任何位置,并像对其他视图一样进行布局。

您还可以将该函数移动到singleton类,并使该函数返回UIView。现在,每当您需要该视图时,只需调用函数并获取视图,现在就可以对该视图执行任何操作。关键短语是“我有一个
UIView
,它存在于一个数字上…”虽然存在许多设计模式,但在几乎所有模式中,尤其是MVC,您都希望将该视图与它的控制器分离。现在唯一要问的问题是如何通过IB或代码创建视图?如果是IB,考虑一个笔尖文件。如果它是代码,那么就做它的补充-子类
UIView
。如果从nib实例化的视图也是一个
可重用视图
,这难道不会启动一个无限循环吗?@Harry Robinson:不。实例化视图是
ReusableView
的一个实例-您可以拥有任意多个类的实例。但是从nib加载视图后会调用
awakeFromNib
。当从nib加载第一个视图时,您可以从nib加载另一个视图。我不明白这怎么会不创建递归。我只是创建了一个示例项目来测试这一点,它确实创建了一个无限循环。@ABeard89:正确,它令人困惑。。。我已经更新了我的答案。谢谢你指出。