问题:如何以编程方式将类分配给在Storyboard中创建的UIView
我在IB(graphView
(中创建了一个UIView,我想在其中显示几个图中的一个,它们的定义在各自的类中创建。
为此,我以编程方式创建了另一个视图,然后将所选图形的类分配给该视图,然后添加到原始视图:
@IBOutlet weak var graphView: UIView!
func displayGraph(choice: Int) {
var selectedGraphView = UIView()
switch choice {
case 1: selectedGraphView = class1()
case 2: selectedGraphView = class2()
case 3: selectedGraphView = class3()
default: selectedGraphView = class1()
}
selectedGraphView.frame = CGRect(x: 0, y: 0, width: graphView, height: graphView)
graphView.addSubview(selectedGraphView)
}
事情似乎很正常,但我真的需要第二个UIView(selectedGraphView
(吗?
我试着把它改成:
func displayGraph2(choice: Int) {
switch choice {
case 1: graphView = class1()
case 2: graphView = class2()
case 3: graphView = class3()
default: graphView = class1()
}
}
但我不知道如何运行类的内容。
我可以这样做吗?如果是,缺少什么?
EDIT:实际上,有3个UIViews:IB中的一个,保存图形的一个和类本身创建的一个。
如果说class1
除了print("entered class1")
什么都没有,在第一种情况下(displayGraph
(,我看到";进入类1";打印。在第二个(displayGraph2
(中,我一无所获。
第2版:我可以在IB中将任何一个类分配给graphView
,并从该类中获得打印消息。如何以编程方式将类分配给graphView
(因为我在displayGraph2
中尝试的操作不起作用(?
在Storyboard中添加UIView
时,可以分配其自定义类。然而,在运行时,您不能以这种方式更改其类:
@IBOutlet var graphViewHolder: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// cannot do this
let v = View2Class()
graphViewHolder = v
}
正如您所做的,一种常见的方法是在Storyboard中添加一个UIView
作为";支架";(或"容器"(视图。然后,在代码中,实例化所需自定义类的实例,并将其作为子视图添加到"中;支架";看法
然而,如果你这样做:
selectedGraphView.frame = CGRect(x: 0, y: 0, width: graphView, height: graphView)
graphView.addSubview(selectedGraphView)
新添加的子视图将具有"0"的大小;支架";视图,如果/当支架视图更改大小(例如在设备旋转时(,您将遇到布局问题。
所以,你可以这样做:
// let's name it "graphViewHolder" so we know we're using it as a "holder" view
@IBOutlet var graphViewHolder: UIView!
var currentChoice: Int = 1
override func viewDidLoad() {
super.viewDidLoad()
displayGraph(choice: 1)
}
func displayGraph(choice: Int) {
var selectedGraphView: UIView?
switch choice {
case 1: selectedGraphView = View1Class()
case 2: selectedGraphView = View2Class()
case 3: selectedGraphView = View3Class()
default: selectedGraphView = View1Class()
}
// unwrap optional
guard let sgv = selectedGraphView else { return }
// does the "holder" view already have any subviews?
// if so, remove them
graphViewHolder.subviews.forEach { v in
v.removeFromSuperview()
}
// add the new view as a subview of the "holder" view
graphViewHolder.addSubview(sgv)
// we need to give the new view auto-layout properties
sgv.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// constrain it to all 4 sides of the "holder" view
sgv.topAnchor.constraint(equalTo: graphViewHolder.topAnchor),
sgv.leadingAnchor.constraint(equalTo: graphViewHolder.leadingAnchor),
sgv.trailingAnchor.constraint(equalTo: graphViewHolder.trailingAnchor),
sgv.bottomAnchor.constraint(equalTo: graphViewHolder.bottomAnchor),
])
}
现在子视图将跟随";支架";视图的约束。
请注意,如果要对加载的视图执行某些操作,则必须确保它是正确的类。
例如,如果我们想在View2Class
:中调用一个自定义函数
// make sure the "holder" view has a subview
guard let v = graphViewHolder.subviews.first else {
print("Graph View Holder has no subviews!")
return
}
// make sure the subview is a View2Class instance
guard let v2 = v as? View2Class else {
print("The Holder subview is not View2Class!")
return
}
// call a func in View2Class
v2.myFunc()