在视图控制器中访问 UIView 子类
accessing UIView subclass in view controller
假设我有 SomeViewController: UIViewController
,并且我有一个自定义视图 CustomView: UIView
,定义为 XIB,我想显示它。这个自定义视图将在其他视图控制器中重复使用,甚至在同一个视图控制器中多次使用。
class CustomView: UIView {
@IBOutlet public var label: UILabel!
}
我添加此视图的方式一直是:
class UIExamples: UIViewController {
@IBOutlet private var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
let customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.frame = myView.bounds
myView.addSubview(customView)
}
}
假设稍后我想通过 public 属性 label
修改一些关于 CustomView
的内容。
我可以在 viewDidLoad
中完成它只是因为我可以访问 customView
,但是如果我想在其他功能中更改它怎么办?我所看到的是必须做
let customView = myView.subviews[0] as! CustomView
customView.label.text = "some text"
这看起来不对。
所以,我认为正确的方法应该是这样的:
class UIExamples: UIViewController {
@IBOutlet public var customView: CustomView! // Now this is always a CustomView type
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.label.text = "some text" // DOES NOT WORK!
}
}
最后一行 customView.label.text 不起作用。事实上,屏幕上什至看不到标签。我究竟做错了什么?
好的,没读过(或者可能在编辑之前读过)你使用 xib。如果 ViewController 是从带有标签的 xib 创建的,这将是正确的方法:
在 xib 中设置 myView class:
然后连接IBOutlet(从这里的xib中删除当前的一个:
然后从代码)。
现在 myView.label.text = "some text"
应该可以正常工作了。
祝你好运!
如果您通过代码创建视图,请按以下方式进行:
class UIExamples: UIViewController {
@IBOutlet private var myView: CustomView!
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
myView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
myView.frame = view.bounds
view.addSubview(myView)
}
}
因为您已经 属性 将此视图存储在您的视图控制器中,所以没有必要在子视图中挖掘,它会像那样工作
myView.label.text = "some text"
以及
的原因
customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.label.text = "some text"
不工作是因为它是全新的视图,没有添加到您的视图控制器子视图中(顺便说一句,框架也没有设置)。并且因为您更改了 customView 属性 的值,它现在不指向子视图中存在的旧视图实例(您仍然可以看到 "old one" 但不能更改它)。
但我真的建议使用创建一次的指针,因为正确 class 可以避免强制转换。 (或者直接在xib/storyboard中创建视图,否则@IBOutlet
不需要)
发布我自己的答案。
- 创建 XIB 文件。
- 创建 UIView 子class Swift 文件。
- 在 XIB 文件所有者的 Identify Inspector 自定义 class 字段下,输入 UIView subclass 名称(您的自定义视图)。
- 在 XIB 文件所有者的连接检查器下,确保 Swift 文件中的所有 IBOutlets 都已连接。
- 向视图控制器添加一个视图,并在其 Identify Inspector 自定义 class 类型下,指定自定义 class 名称。
重要:
* 在您的 XIB swift 文件中,您必须正确加载 XIB 内容视图。
...
/// Initializer used by Interface Builder.
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
/// Initializer used programmatically.
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
...
func configure() {
let contentView = // here use many of the functions available on the internet to
// load a view from a nib.
// Then add this view to the view hierarchy.
addSubview(contentView)
}
假设我有 SomeViewController: UIViewController
,并且我有一个自定义视图 CustomView: UIView
,定义为 XIB,我想显示它。这个自定义视图将在其他视图控制器中重复使用,甚至在同一个视图控制器中多次使用。
class CustomView: UIView {
@IBOutlet public var label: UILabel!
}
我添加此视图的方式一直是:
class UIExamples: UIViewController {
@IBOutlet private var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
let customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.frame = myView.bounds
myView.addSubview(customView)
}
}
假设稍后我想通过 public 属性 label
修改一些关于 CustomView
的内容。
我可以在 viewDidLoad
中完成它只是因为我可以访问 customView
,但是如果我想在其他功能中更改它怎么办?我所看到的是必须做
let customView = myView.subviews[0] as! CustomView
customView.label.text = "some text"
这看起来不对。
所以,我认为正确的方法应该是这样的:
class UIExamples: UIViewController {
@IBOutlet public var customView: CustomView! // Now this is always a CustomView type
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.label.text = "some text" // DOES NOT WORK!
}
}
最后一行 customView.label.text 不起作用。事实上,屏幕上什至看不到标签。我究竟做错了什么?
好的,没读过(或者可能在编辑之前读过)你使用 xib。如果 ViewController 是从带有标签的 xib 创建的,这将是正确的方法:
在 xib 中设置 myView class:
然后连接IBOutlet(从这里的xib中删除当前的一个:
然后从代码)。
现在 myView.label.text = "some text"
应该可以正常工作了。
祝你好运!
如果您通过代码创建视图,请按以下方式进行:
class UIExamples: UIViewController {
@IBOutlet private var myView: CustomView!
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
myView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
myView.frame = view.bounds
view.addSubview(myView)
}
}
因为您已经 属性 将此视图存储在您的视图控制器中,所以没有必要在子视图中挖掘,它会像那样工作
myView.label.text = "some text"
以及
的原因customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.label.text = "some text"
不工作是因为它是全新的视图,没有添加到您的视图控制器子视图中(顺便说一句,框架也没有设置)。并且因为您更改了 customView 属性 的值,它现在不指向子视图中存在的旧视图实例(您仍然可以看到 "old one" 但不能更改它)。
但我真的建议使用创建一次的指针,因为正确 class 可以避免强制转换。 (或者直接在xib/storyboard中创建视图,否则@IBOutlet
不需要)
发布我自己的答案。
- 创建 XIB 文件。
- 创建 UIView 子class Swift 文件。
- 在 XIB 文件所有者的 Identify Inspector 自定义 class 字段下,输入 UIView subclass 名称(您的自定义视图)。
- 在 XIB 文件所有者的连接检查器下,确保 Swift 文件中的所有 IBOutlets 都已连接。
- 向视图控制器添加一个视图,并在其 Identify Inspector 自定义 class 类型下,指定自定义 class 名称。
重要: * 在您的 XIB swift 文件中,您必须正确加载 XIB 内容视图。
...
/// Initializer used by Interface Builder.
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
/// Initializer used programmatically.
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
...
func configure() {
let contentView = // here use many of the functions available on the internet to
// load a view from a nib.
// Then add this view to the view hierarchy.
addSubview(contentView)
}