重新加载/刷新子视图 - setNeedsDisplay 不起作用

Posted

技术标签:

【中文标题】重新加载/刷新子视图 - setNeedsDisplay 不起作用【英文标题】:reload/refresh subViews - setNeedsDisplay doesnt work 【发布时间】:2012-01-23 22:31:58 【问题描述】:

我在使用 setNeedsDisplay 时遇到了问题。我有一个带有很多子 UIView 的 UIView,它们是在 Inteface Builder 中创建的。我还有一个带有 IBAction 的按钮。在这个 IBAction 中,我想重绘/重新加载所有 UIView(或所有 UIElement,如 UILabel、UIWebView 等)

我正在这样做,这对我不起作用,不知道为什么..:

//redraw the UIViews
[self.view_card_0 setNeedsDisplay];
[self.view_card_1 setNeedsDisplay];
[self.view_card_stapel setNeedsDisplay];

//other UI Elements
[self.webView_0 setNeedsDisplay];
[self.webView_1 setNeedsDisplay];
[self.webView_stapel setNeedsDisplay];

[self.lblCardTitle_0 setNeedsDisplay];
[self.lblCardTitle_1 setNeedsDisplay];
[self.lblCardTitle_stapel setNeedsDisplay]; 

[self.img_card_0 setNeedsDisplay];
[self.img_card_1 setNeedsDisplay];
[self.img_card_stapel setNeedsDisplay];

如何重绘/重新加载/刷新所有 UIElements/UIViews 和 Subviews?

编辑 1:

我如何加载视图:

detailViewController = [[DetailViewController alloc]  
initWithNibName:@"DetailViewController_iPad" bundle:[NSBundle mainBundle]];  

detailviewcontroller没有viewcontroller,只有uiviews,这里是层次结构:

UIView -- UIViewContainer --- UIView0 --- UIView1 --- UIViewStapel

我希望做什么:

*我不想重置 UIView,我想更改它们的背景和内容。 *

我的详细视图中有很多子视图(uiviews),见上面的层次结构。我在 UIViews 中显示内容,内容来自 coreData。 view1 包含 coreData 的当前行。 view0 包含上一行 coreData。 viewStapel 包含下一行 coreData。

使用 IBAction,我想迭代 coreData 行,如果调用该操作,则在当前显示下一行..等等..

在 Log 中,数据发生了变化,但不显示在 UIViews 中。原因是我需要重绘或重新加载或类似的东西,以显示当前数据。

编辑 2:已解决我已将代码放入新方法中,调用此方法解决了我的问题。

【问题讨论】:

你为什么要这样做?你期待它做什么?通常在其他一些 UI 元素上调用 -setNeedsDisplay 不会做任何事情,因为如果 UI 元素需要更新其显示(以响应更改的属性),它本身已经调用了该方法. 我正在更改该 IBAction 的内容以及颜色/图像。内容来自coreData。我需要重新绘制 uiview 以显示 ibaction 上的更改。 setNeedsDisplay 只是重绘视图,它不会重置它的属性(例如颜色)。为此,您必须从 nib 文件中重新加载它们(请参阅下面的答案)。 【参考方案1】:

您是否尝试将视图和子视图重置为 nib 文件中的默认状态?

如果是这样,上述方法将不起作用。自动执行此操作的唯一方法是从 nib 重新加载视图,但在我提供帮助之前,您首先需要更清楚地了解如何加载视图。

如果您将它加载到视图控制器中,那么刷新它的最简单方法是从屏幕上删除视图控制器并重新创建它,但是您可能能够重新加载视图,这样说(从控制器):

UIView *parent = self.view.superview;
[self.view removeFromSuperview];
self.view = nil; // unloads the view
[parent addSubview:self.view]; //reloads the view from the nib

如果您使用 [[NSBundle mainBundle] loadNibNamed...] 或等效方法直接从 nib 加载视图,那么重新加载视图的最佳方法就是将其丢弃并再次调用该方法。

【讨论】:

感谢您的回复。请参阅我的 Edit1。解释了一下。 看起来你正在用视图控制器做一些奇怪的事情,可能不像你想象的那样工作。你说你没有视图控制器,但是如果没有视图控制器,DetailViewController 是什么?我知道 nib 文件中没有视图控制器,因为 nib 不是这样工作的,但您仍在创建视图控制器并从 nib 填充它的视图层次结构。 我已将代码放入一个新方法中,调用此方法解决了我的问题。谢谢!【参考方案2】:

斯威夫特 2

这是尼克洛克伍德回答的复制品,用于一些简单的复制粘贴

let parent = self.view.superview
self.view.removeFromSuperview()
self.view = nil
parent?.addSubview(self.view)

【讨论】:

【参考方案3】:

这可能有助于某人在容器视图中进行分页。上面的代码给了我尝试这个的想法,它可以工作。

[self.pageViewController.view removeFromSuperview];
self.pageViewController.view = nil; // unloads the view
[self performSegueWithIdentifier:@"pageViewSegue" sender:self];

【讨论】:

以上是关于重新加载/刷新子视图 - setNeedsDisplay 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在kendo树视图中重新加载或刷新整个分支(父级+子级)

Swift - 在刷新控件中禁用默认重新加载表视图

在Vue中重新加载或刷新页面时如何显示正确的嵌套子选项卡

像刷新一样重新加载tableview视图

重新渲染视图而不重新加载/刷新 AngularJS 应用程序

如何在不加载视图的情况下重新加载/刷新部分视图中的级联下拉列表