这是我应该创建课程的时候吗?
Posted
技术标签:
【中文标题】这是我应该创建课程的时候吗?【英文标题】:Is this when I should be creating a class? 【发布时间】:2018-05-28 11:57:11 【问题描述】:我正在努力掌握 Swift 并希望得到一些建议......
我有一个存在于多个屏幕上的 UIView;具体来说,它是一个使用许多元素/参数来正确设置样式的徽标,即阴影、形状、图像等。
对于我的第一个视图控制器,我将其设置为从 viewDidLoad 函数调用的函数。然后在我的第二个视图控制器中,我有相同的徽标......这是我的问题,
我应该从情节提要加载第一个视图控制器,然后在第二个视图控制器中引用该函数,还是应该将徽标设置为任何一个视图控制器都可以引用的类?我的直觉说它应该是一个类......
提前致谢
【问题讨论】:
您也可以将函数移动到单例类并让该函数返回 UIView。现在,当您需要该视图时,只需调用该函数并获取视图,现在就可以对视图执行任何操作。 关键词是“我有一个UIView
,它存在于一个数字上......” 虽然有许多设计模式,但几乎在任何一个- 特别是 MVC - 你想分离这个视图和它的控制器。现在唯一要问的问题是您如何创建视图 - 通过 IB 还是在代码中?如果是 IB,请考虑使用 NIB 文件。如果是代码,那就恭维 - 子类UIView
。
【参考方案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
。否则你会创建一个无限循环。
【讨论】:
如果从 nib 实例化的视图也是ReusableView
,这不就开始了无限循环吗?
@Harry Robinson:不。实例化视图是ReusableView
的instance——您可以拥有任意数量的类实例。
但是 awakeFromNib
在从 nib 加载视图后调用。当从 nib 加载第一个视图时,然后从 nib 加载另一个视图。我看不出这怎么不会产生递归。
我刚刚创建了一个示例项目来测试它,它确实创建了一个无限循环。
@ABeard89:正确,这令人困惑......我已经更新了我的答案。感谢您指出。【参考方案2】:
警告!正如我在另一个答案中指出的那样,请勿从
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
当然,您不必使用容器视图。将其放置在视图层次结构中您需要的任何位置,并像对其他视图一样进行布局。
【讨论】:
以上是关于这是我应该创建课程的时候吗?的主要内容,如果未能解决你的问题,请参考以下文章
新站点创建和安全/身份验证,- 我应该使用 ASP.net Membership Provider 吗?