我试图抓住Swift并想要一些建议......
我有一个UIView存在于许多屏幕上;具体来说,它是一个使用许多元素/参数来正确设计样式的徽标,即阴影,形状,图像等。
对于我的第一个viewcontroller,我把它设置为一个从viewDidLoad函数调用的函数。然后在我的第二个视图控制器中,我有相同的徽标......这是我的问题,
我应该从故事板加载第一个视图控制器,然后在第二个viewcontroller中引用该函数,还是我应该让logo成为viewcontroller可以引用的类?我的直觉说应该是一个班级......
提前致谢
答案 0 :(得分:1)
对于可重用的视图,您将创建一个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
。否则你将创建一个无限循环。
答案 1 :(得分:0)
警告!正如我在另一个答案中指出的那样,不要从
awakeFromNib
内加载相同的笔尖,否则您将创建一个无限循环加载笔尖。
我会说,你的直觉本能是正确的。为您的可重用视图创建一个自定义类。如果您决定为您的类创建一个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
}
}
当然,您不必使用容器视图。将它放在视图层次结构中的任何位置,并像其他视图一样进行布局。