简体   繁体   English

从故事板重用视图

[英]reuse view from storyboard

I have a tableview with custom section headers. 我有一个自定义节标题的tableview。 The view for the section header is defined in the storyboard and wired to an instance variable. 节标题的视图在故事板中定义并连接到实例变量。 Is there a way to request a new instance of the view from the storyboard? 有没有办法从故事板中请求视图的新实例?

In the past I have done this by having the section header defined in its own xib file and getting a new instance by using 在过去,我通过在自己的xib文件中定义节头并使用获取新实例来完成此操作

[[NSBundle mainBundle] loadNibNamed:@"TimerViewSectionHeader" owner:self options:nil];
UIView *newHeaderView = self.sectionHeaderView;

The solution I've come up with for this is as follows: 我想出的解决方案如下:

I have a tableview with multiple prototype cells that displays complex data. 我有一个包含多个原型单元的tableview,可以显示复杂的数据。 There is a segue to a detail view, and a transaction process view. 有详细视图的segue和事务处理视图。

This first tableview has a search button that displays a new tableview with the results. 第一个tableview有一个搜索按钮,显示带有结果的新tableview。 It needs the same functionality as the main tableview that pushes it; 它需要与推送它的主tableview相同的功能; including segues to the detail and transaction progress views so: 包括segue到详细信息和事务进度视图,所以:

On storyboard, select and copy your main tableview. 在故事板上,选择并复制主要的tableview。 Deselect and paste. 取消选择并粘贴。 Create a push segue from your main tableview to your 2nd tableview; 从主tableview到第2个tableview创建push segue; or from where ever you want to navigate to it from. 或者从哪里想要导航到它。 Modify the 2nd tableview as you like. 根据需要修改第二个tableview。 IE: If it requires some UI changes no problem. IE:如果需要一些UI更改没问题。

Create a new viewcontroller class that is a subclass of the viewcontroller running the main tableview. 创建一个新的viewcontroller类,它是运行主tableview的viewcontroller的子类。

Override the data delegate in your subclass to serve up the subset of data you want. 覆盖子类中的数据委托以提供所需的数据子集。

Back in the storyboard, select your 2nd tableview controller and in the identity inspector select your subclass as the custom class. 回到故事板,选择第二个tableview控制器,在身份检查器中选择子类作为自定义类。

For this solution to work smoothly, your app really needs to be managing data for the views. 为了使此解决方案顺利运行,您的应用程序确实需要管理视图的数据。 You could use prepareforsegue to pass data from 1st tableview to the second, but I've found the app data model far more flexible from numerous points of view. 您可以使用prepareforsegue将数据从第一个tableview传递到第二个,但我发现从多个角度来看,应用程序数据模型更加灵活。

Unless you have buttons that push to the sub views via segue, your subclass will need to override functions that push via segues with identities. 除非您有通过segue推送到子视图的按钮,否则您的子类将需要覆盖通过带有标识的segue推送的函数。 NB Segues must have unique identifiers if you id them at all. NB Segues必须具有唯一标识符(如果您完全标记它们)。

It took a lot of trial and error to figure this out, but once you understand the concept, it's a relatively smooth solution that is quite adaptable and not so bad to implement. 需要花费大量的试验和错误来解决这个问题,但是一旦你理解了这个概念,它就是一个相对平稳的解决方案,具有很强的适应性,并且实现起来并不是那么糟糕。

I am not sure about just views, but the way that I was able to get view controllers out of my storyboard is as follows. 我不确定只是视图,但我能从故事板中获取视图控制器的方式如下。

UIViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"IdentifierName"];

From here, perhaps you might be able to use this similarly to how it was once done with nibs. 从这里开始,也许你可以使用它与使用nib完成它的方式类似。

I dont' think there is a way to do that. 我不认为有办法做到这一点。 Best bet is to put the tableview custom header view in a separate nib and load it like you did in your code sample whenever you need to use it. 最好的办法是将tableview自定义标题视图放在一个单独的nib中,并像在代码示例中一样加载它,只要你需要使用它。

I tried to do the same thing and ran into the same problem. 我试着做同样的事情并遇到了同样的问题。

I like to work with storyboards a lot and was impressed how fast I could create a working UI. 我喜欢经常使用故事板,并且对创建工作UI的速度印象深刻。 However, as soon as you need to re-use views it makes a lot of sense to put those into a separate nib along with its UIViewController subclass. 但是,只要您需要重新使用视图,将它们与UIViewController子类一起放入单独的nib就很有意义。

You can then place a generic UIView in all the places where your re-used view should go and add the view using your ViewController: 然后,您可以在重复使用的视图所在的所有位置放置一个通用的UIView ,并使用ViewController添加视图:

[myReusableViewController loadView];
[myReusableViewController viewDidLoad]; // You have to handle view callbacks yourself.

[self.myReusableViewPlaceholder addSubview:myResusableViewController.view];
[myReusableViewController viewWillAppear:YES];

So to sum it up: 总结一下:

  • Use storyboard, it's great 使用故事板,这很棒
  • Create the scaffold of your application in the storyboard, along with any static view (like About screens etc.) 在故事板中创建应用程序的脚手架,以及任何静态视图(如关于屏幕等)
  • Create re-used views in a custom nib + UIViewController subclass and add UIView placeholders in your storyboard. 在自定义nib + UIViewController子类中创建重用视图,并在故事板中添加UIView占位符。

In another answer I thought about some Pros and Cons of Storyboard 在另一个答案中,我想到了故事板的一些优点和缺点

I've been able to reuse a view in the storyboard just by connecting a transition from one tableview into the one I want to reuse. 我只能通过连接从一个tableview转换到我想要重用的一个视图来重用故事板中的视图。

so my tableview that I want to reuse is pointed to twice. 所以我要重用的表视图指向两次。 It sort of works but the problem I'm running into it setting a variable (using instantiateViewControllerWithIdentifier) in my app delegate to my table view that is getting reused. 它有点工作,但我遇到的问题是在我的app委托中设置一个变量(使用instantiateViewControllerWithIdentifier)到我的表视图,它被重用了。 It seems that if I reuse it, the storyboard is creating 2 instances of my tableview and the one I get with instantiateViewControllerWithIdentifier isn't the one I want. 似乎如果我重用它,故事板会创建我的tableview的2个实例,而我用instantiateViewControllerWithIdentifier创建的实例不是我想要的那个。

I'm not really sure if this is the proper way to do it. 我不确定这是否是正确的方法。 But I assume many others are doing this somehow. 但我认为其他许多人正以某种方式这样做。 With the custom table cells in storyboard I suspect lots of people want to reuse their views. 使用故事板中的自定义表格单元格,我怀疑很多人都希望重用其观点。

For example: We want to reuse the view(include subviews) in storyboard shown below. 例如:我们希望在下面显示的故事板中重用视图(包括子视图)。

我们想要重用的故事板中的目标视图

The best solution I know so far is clip and paste the view related code to the New Singe View file without losing the information. 到目前为止,我所知道的最佳解决方案是将视图相关代码剪贴并粘贴到New Singe View文件而不会丢失信息。

Detailed steps are as follows 详细步骤如下

Step 1: Rename the view we want reuse. 第1步:重命名我们想要重用的视图。 Just prepare for step 2. 准备第2步。

第1步

Step 2: Open storyboard as source code in order to clip the XML code we need 第2步:打开storyboard作为源代码,以便剪切我们需要的XML代码

第2步

Step 3、4: Search and clip the code we need 步骤3,4:搜索并剪辑我们需要的代码

第3步

第四步

Step 4.5(Not needed): Open as Interface Builder to see the view removed 步骤4.5(不需要):作为Interface Builder打开以查看删除的视图

步骤4.5

Step 5、6: New XXX.xib and paste the code we clipped just now 步骤5,6:新建XXX.xib并粘贴我们刚才修剪的代码

第5步

第6步

Step 7: Important. 第7步:重要。 Insert code <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> to XXX.xib source code. 将代码<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> freeformSimulatedSizeMetrics <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>插入XXX.xib源代码。 Warning: Do this before open it as Interface Builder! 警告:在将其作为Interface Builder打开之前执行此操作! Otherwise, you will see wrong size and layout waring. 否则,您将看到错误的大小和布局。

[![step 7][9]][9] [![步骤7] [9]] [9]

Step 8: New XXX.swift to connect the XXX.xib 第8步:新建XXX.swift以连接XXX.xib

[![step 8][10]][10] [![步骤8] [10]] [10]

Step 9: Add the view anywhere we want 第9步:在任何我们想要的地方添加视图

[![step 9][11]][11] [![第9步] [11]] [11]

I get warning: "You need at least 10 reputation to post more than 8 links." 我收到警告:“你需要至少10个声望来发布8个以上的链接。” Can you support me to upload the remaining 3 screenshots? 你能支持我上传剩下的3个截图吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM