无法以编程方式将视图添加到情节提要中的现有子视图
Posted
技术标签:
【中文标题】无法以编程方式将视图添加到情节提要中的现有子视图【英文标题】:Can't add a view to an existing subview in storyboard programatically 【发布时间】:2016-07-19 10:07:52 【问题描述】:我正在尝试在代码中模拟这种视图层次结构:
"scene"
"view Shop Main" -> `UIView`
"view shop scroll" -> `UIScrollView`
"ViewDetail" -> `UIView`
"Shop Connected Container" -> `UIView`
"Connected Shop" -> `UIView`
我想实例化多个“Connected Shop”并将它们添加到“Shop Connected Container” 像这样:
"scene"
"view Shop Main" -> `UIView`
"view shop scroll" -> `UIScrollView`
"ViewDetail" -> `UIView`
"Shop Connected Container" -> `UIView`
"Connected Shop" -> `UIView`
"Connected Shop" -> `UIView`
"Connected Shop" -> `UIView`
如何以编程方式执行此操作? 我为每个 subView 和一个 xib 文件都有一个自定义类。 这就是我从代码中实例化子视图的方式:
override func viewDidLoad()
/*1*/ let vShopMain = NSBundle.mainBundle().loadNibNamed("viewShopMain", owner: self, options: nil).first as! viewShopMain
/*2*/ let vShopScroll = NSBundle.mainBundle().loadNibNamed("viewShopScroll", owner: vShopMain, options: nil).first as! viewShopScroll
/*3*/ let vDetail : UIView = NSBundle.mainBundle().loadNibNamed("viewDetail", owner: vShopScroll, options: nil).first as! viewDetail
//
//
/*4*/ let sConContainer : UIView = NSBundle.mainBundle().loadNibNamed("shopConnectedContainer", owner: vDetail, options: nil).first as! shopConnectedContainer
/*5*/ let cShop = NSBundle.mainBundle().loadNibNamed("connectedShop", owner: sConContainer, options: nil).first as! connectedShop
cShop.bannerTitle.text = "Shop Title"
vShopMain.addSubview(vShopScroll)
vShopScroll.addSubview(vDetail)
vDetail.addSubview(sConContainer)
sConContainer.addSubview(cShop)
self.view.addSubview(sConContainer)
也试过这个,结果完全相同:
let vShopMain = UINib(nibName: "viewShopMain", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! viewShopMain
let scroll = UINib(nibName: "viewShopScroll", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! viewShopScroll
let vDetail = UINib(nibName: "viewDetail", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! viewDetail
let sConContainer = UINib(nibName: "shopConnectedContainer", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! shopConnectedContainer
let cShop = UINib(nibName: "connectedShop", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! connectedShop
cShop.bannerTitle.text = "hola"
vShopMain.addSubview(scroll)
scroll.addSubview(vDetail)
vDetail.addSubview(sConContainer)
sConContainer.addSubview(cShop)
self.view.addSubview(sConContainer)
但是添加的“新”视图位于另一个视图下方,这不是预期的行为,因为我是从情节提要中实例化现有视图,而不是创建新视图。
我遵循故事板层次结构的顺序。视图也与它们的自定义类链接,并且它们有它们的 xib 文件。但是当我运行我的应用程序时,我遇到了这个奇怪的问题
我在这里做错了什么?请帮忙
【问题讨论】:
view's custom classes area assigned in storyboard
够了,现在在实例化相应的控制器时会自动加载视图。您可以在控制器类中创建所需的任何视图的出口并使用它。无需使用loadNibNamed
以编程方式加载它
是的,视图将被创建。但是我想以编程方式设置视图的数量,所以它可以是 1 也可以是 10。我需要多次实例化这个视图来创建多个视图。我该怎么做?
【参考方案1】:
帮助您找出崩溃的原因。 loadNibNamed
返回一个对象数组而不是单个视图。所以这肯定会崩溃
let vShopScroll = NSBundle.mainBundle().loadNibNamed("viewShopScroll", owner: self, options: nil) as! viewShopScroll
因为您假设它返回 viewShopScroll
并强制解开它。正如你所说,你的第一行正在工作,因为你在那里使用first
对象
let vShopMain = NSBundle.mainBundle().loadNibNamed("viewShopMain", owner: self, options: nil).first as! viewShopMain
对所有其他情况也这样做
【讨论】:
所以我正在这样做,但它也崩溃了:让 vShopScroll = NSBundle.mainBundle().loadNibNamed("viewShopScroll", owner: vShopMain, options: nil).first as! viewShopScroll 崩溃日志说了什么? 无法将“yuApp.viewShopMain”(0x10a2fcf50)类型的值转换为“yuApp.viewShopScroll”(0x10a2faf30)。以上是关于无法以编程方式将视图添加到情节提要中的现有子视图的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式创建视图和添加子视图比使用情节提要更好/更快[重复]