如何使用 xib 创建单例 UIView 以在不同的 VC 上使用一个实例?
Posted
技术标签:
【中文标题】如何使用 xib 创建单例 UIView 以在不同的 VC 上使用一个实例?【英文标题】:How to create singleton UIView with xib for using one instance on different VCs? 【发布时间】:2018-04-18 15:19:34 【问题描述】:我有一个自定义 UIView 子类,它有 xib。我需要在我的 App 中的不同 ViewController 上使用一个实例。
我的自定义视图初始化如下:
@IBOutlet var contentView: UIView!
override init(frame: CGRect)
super.init(frame: frame)
commitInit()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
commitInit()
private func commitInit()
contentView = loadFromNib(named: "ChartWithPoints")// Extension for UIView class, loading by name
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
addSubview(contentView)
单例如何修改这段代码,修改后如何使用这个类?
感谢所有回答。
【问题讨论】:
【参考方案1】:我不认为你想要一个单例,你也需要为每个视图控制器使用一个实例。管理一个视图的所有权是完全没有必要的。一个类的全部意义在于拥有多个对象。你不需要有一个单身人士。
对于每个视图控制器,继续做你现在正在做的事情,并为每个控制器实例化一个新的自定义视图。
要回答有关使用子类的问题,请将视图属性更改为子类而不是 UIView
:
@IBOutlet var contentView: SubclassView!
要详细了解单例解决的问题,请查看上面的 Wikipedia article。
编辑
既然您询问了模型-视图关系是什么样的,我将尝试给出一个基本示例。
说,在您看来,您想显示用户的姓名和爱好。单例模型类看起来像这样:
class UserData
static let singletonUserData = UserData()
var name: String
var hobbies: [String]
private init()
self.name = "Bob Appleseed"
self.hobbies = ["Swimming", "Planting Apples", "Drawing"]
然后您将能够通过以下方式访问单例:
UserData.singletonUserData
在你的视图类中,你可能有一些标签:
@IBOutlet var nameLabel: UILabel!
@IBOutlet var favoriteHobbyLabel: UILabel!
然后,在初始化之后,您可以使用单例填充标签:
contentView.nameLabel.text = UserData.singletonUserData.name
contentView.favoriteHobbyLabel.text = UserData.singletonUserData.hobbies.first!
如果你想修改单例的属性,你可以从任何地方改变它们:
UserData.singletonUserData.name = "John Appleseed"
【讨论】:
我不需要每个 ViewController 的个人实例。我想创建一次实例,如果用户更改了该视图上的任何信息,其他 ViewControllers 上的视图也会更改 @GolovanovDmitrii 不要使用单例视图。使用模型对象并让视图引用该对象。当您对该对象进行更改时,您可以更新每个视图。 “一个类的全部意义在于拥有多个对象”。那为什么单身人士会存在呢?如果只需要一个实例,则不需要从一个类中拥有多个对象 @tktsubota,这听起来像是 OOP 的好模式。如果您将添加一些带有图像和代码的示例,我将不胜感激! @J.Doe 类的基本原理是拥有多个对象并让它们符合相同的“模板”。单例满足了持久的、通用的状态的必要性,如果它们不存在,OOP 将缺乏这种状态,但它们不是大多数问题的答案(参见依赖注入),包括这个。【参考方案2】:import UIKit
import Foundation
class CustomView : UIView
@IBOutlet weak var titleLabel : UILabel!
// Singleton instance
static let shared : CustomView = CustomView.sharedInstanceFromNib(size: CGSize(width: 100, height: 100))
// You can modify argument list as per your need.
class private func sharedInstanceFromNib(size : CGSize)->(CustomView)
// This will connect your IBOutlet's with view's in Xib.
let view = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)?.first as! CustomView
view.frame.size = size
return view
注意 - 第一次使用共享实例时,必须在主线程上使用,否则 Xcode 的控制台会显示一些警告消息。
【讨论】:
以上是关于如何使用 xib 创建单例 UIView 以在不同的 VC 上使用一个实例?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用不同的 init 方法在 XIB 中创建自定义视图?
我可以使用 UIView(.xib 和类)作为许多视图的视图基础示例吗?