如果从不同的视图控制器按回,则重新加载而不是重新加载。 Swift
Reload and not reload if press back from different view controllers. Swift
前三个答案可以解决我的问题。很难选择哪一个是最好的。所以,我只选择第一个回答我问题的人。对不起业余爱好者和 iOSEnthusiatic。谢谢您的帮助。我很感激。
ViewController 1 人有 table 次观看。
我的问题是如何仅当我从视图控制器 2 单击返回时才重新加载 table 视图,如果我从视图控制器 3 单击返回则不重新加载 table 视图。
现在,我的后退按钮代码是
@IBAction func backButtonTapped(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
在视图控制器 1 中。我知道 table 视图将从视图控制器 2 或 3 中重新加载
override func viewDidAppear(animated: Bool) {
loadTable()
}
我尝试将 loadTable() 放在 viewDidLoad 中,并尝试为视图控制器 2 中的后退按钮编写以下代码。但是,它不起作用。
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("UserHomePageViewController") as! UserHomePageViewController
controller.viewDidLoad()
有什么建议我应该怎么做?感谢您的帮助。
编辑:
我认为这是一种更简单的方法,但它仍然不像我想的那样有效。我猜是因为 viewDidAppear 在调用 reloadTableBool 之前执行。正确的?有什么办法可以解决吗?谢谢你。您的帮助将不胜感激。
class 2ViewController
@IBAction func backButtonTapped(sender: AnyObject) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("1ViewController") as! 1ViewController
print("viewcontroller2 before call: \(controller.reloadTableBool)")
controller.reloadTableBool = false
print("viewcontroller2 after call: \(controller.reloadTableBool)")
self.dismissViewControllerAnimated(true, completion: nil)
}
class 1ViewController
var reloadTableBool = true
override func viewDidAppear(animated: Bool) {
print("viewcontroller1: \(reloadTableBool)")
if reloadTableBool == true {
loadTable()
}
}
当我在视图控制器 2 上单击返回时,它打印
viewcontroller2 before call: true
viewcontroller2 after call: false
viewcontroller1: true
这是我几天前回答的一个问题的。使用导航控制器委托来处理后退按钮。在您的第二个视图控制器中,将委托设置为 self 并在您按下后退按钮时重新加载表视图。
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
}
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
if let controller = viewController as? FirstViewController {
controller.tableView.reloadData()
}
}
注意:
我假设您在这里使用导航控制器的后退按钮。
编辑:使用您手动添加的后退按钮的另一个示例:
@IBAction func backButtonTapped(sender: AnyObject) {
if let viewControllers = app.window?.rootViewController?.childViewControllers {
viewControllers.forEach { ([=11=] as? FirstViewController)?.tableView.reloadData() }
}
self.dismissViewControllerAnimated(true, completion: nil)
}
鉴于您正在使用导航控制器:
@IBAction func backButtonTapped(sender: AnyObject) {
navigationController?.viewControllers.forEach { ([=12=] as? FirstViewController)?.tableView.reloadData() }
self.dismissViewControllerAnimated(true, completion: nil)
}
为此您可以轻松地使用通知方法。
在 viewDidLoad 方法中的第一个 ViewController 添加观察者。
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadTable:", name: "reloadTable", object: nil)
func reloadTable(notification : NSNotification){
let isReload : NSNumber = notification.userInfo!["isReload"] as! NSNumber
if (isReload.boolValue) {
self.tableView.reloadData()
}
}
然后 post 当您调用 dismissViewController.
时分别从您的第二个和第三个 ViewController 收到这样的通知
// From 2nd viewcontroller
NSNotificationCenter.defaultCenter().postNotificationName("reloadTable", object: nil, userInfo: ["isReload" : NSNumber(bool: false)])
// From 3rd viewcontroller
NSNotificationCenter.defaultCenter().postNotificationName("reloadTable", object: nil, userInfo: ["isReload" : NSNumber(bool: true)])
如果显示vc2是由vc1执行的并且总是肯定会使vc1中的数据无效,则可以执行以下操作:
- 向 vc1 添加一个
needsReload
布尔实例变量
- 每当您显示 vc2 时(以及实例化 vc1 时,例如在
awakeFromNib
中,如果来自故事板)将其设置为 true
- 如果needsReload为真,只执行
loadTable
的内容(也许重构这个逻辑为loadTableIfNeeded
)
- 别忘了在
loadTableIfNeeded
的最后设置needsReload
为false
这种失效模式在整个 UIKit 中随处可见,例如 UIView setNeedsLayout
/layoutIfNeeded
。优点是即使有几个事件导致数据失效,它只会在你需要的时候才真正刷新。
在您的情况下,它还有一个额外的优势,即保留包含在 vc1 中的逻辑,并且不会在您的 VC 之间创建不必要的耦合,这总是好的。
---更新:示例实现(ObjC,但你会明白的)
你只需要在 VC1 中处理这个,忘记 VC2 中的所有后退按钮。此实现将在 VC2 出现时立即将 VC1 标记为重新加载,但实际上只会在 VC2 被关闭时在 viewWillAppear 上重新加载。
---更新 2:添加了基于委托回调的条件重新加载
请注意,_needsReload
现在是在委托回调中设置的,而不是在首次呈现 VC2 时设置的。相反,我们将 VC1 设置为 VC2 的委托。 (_needsReload
逻辑上其实不用这种方法,留着参考)
//VC2: add a delegate to the interface
@class VC2;
@protocol VC2Delegate
- (void) viewController:(VC2*)myVC2 didFinishEditingWithChanges:(BOOL)hasChanges;
@end
@interface VC2
@property (nonatomic, weak) id<VC2Delegate> delegate
@end
@implementation VC2
- (IBAction) finishWithChanges
{
[self.delegate viewController:self didFinishEditingWithChanges:YES];
}
- (IBAction) finishWithoutChanges
{
[self.delegate viewController:self didFinishEditingWithChanges:NO];
}
@end
//VC1: implement the VC2Delegate protocol
@interface VC1 () <VC2Delegate>
@end
@implementation VC1
{
BOOL _needsReload
}
- (void) awakeFromNib
{
//adding this for completeness but the way you did it in Swift (at init) is correct
[super awakeFromNib];
_needsReload = YES;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self reloadTableIfNeeded];
}
- (IBAction) displayVC2
{
VC2* myVC2 = ... //instanciate your VC2 here
myVC2.delegate = self; //set as the delegate of VC2
[self presentViewController:myVC2 animated:YES completion:nil];
}
- (void) viewController:(VC2*)myVC2 didFinishEditingWithChanges:(BOOL)hasChanges
{
_needsReload = hasChanges;
[self reloadTableIfNeeded];
}
- (void) reloadTableIfNeeded
{
if (_needsReload) {
[self.tableView reloadData];
_needsReload = NO;
}
}
@end
前三个答案可以解决我的问题。很难选择哪一个是最好的。所以,我只选择第一个回答我问题的人。对不起业余爱好者和 iOSEnthusiatic。谢谢您的帮助。我很感激。
ViewController 1 人有 table 次观看。
我的问题是如何仅当我从视图控制器 2 单击返回时才重新加载 table 视图,如果我从视图控制器 3 单击返回则不重新加载 table 视图。
现在,我的后退按钮代码是
@IBAction func backButtonTapped(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
在视图控制器 1 中。我知道 table 视图将从视图控制器 2 或 3 中重新加载
override func viewDidAppear(animated: Bool) {
loadTable()
}
我尝试将 loadTable() 放在 viewDidLoad 中,并尝试为视图控制器 2 中的后退按钮编写以下代码。但是,它不起作用。
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("UserHomePageViewController") as! UserHomePageViewController
controller.viewDidLoad()
有什么建议我应该怎么做?感谢您的帮助。
编辑:
我认为这是一种更简单的方法,但它仍然不像我想的那样有效。我猜是因为 viewDidAppear 在调用 reloadTableBool 之前执行。正确的?有什么办法可以解决吗?谢谢你。您的帮助将不胜感激。
class 2ViewController
@IBAction func backButtonTapped(sender: AnyObject) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("1ViewController") as! 1ViewController
print("viewcontroller2 before call: \(controller.reloadTableBool)")
controller.reloadTableBool = false
print("viewcontroller2 after call: \(controller.reloadTableBool)")
self.dismissViewControllerAnimated(true, completion: nil)
}
class 1ViewController
var reloadTableBool = true
override func viewDidAppear(animated: Bool) {
print("viewcontroller1: \(reloadTableBool)")
if reloadTableBool == true {
loadTable()
}
}
当我在视图控制器 2 上单击返回时,它打印
viewcontroller2 before call: true
viewcontroller2 after call: false
viewcontroller1: true
这是我几天前回答的一个问题的
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
}
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
if let controller = viewController as? FirstViewController {
controller.tableView.reloadData()
}
}
注意: 我假设您在这里使用导航控制器的后退按钮。
编辑:使用您手动添加的后退按钮的另一个示例:
@IBAction func backButtonTapped(sender: AnyObject) {
if let viewControllers = app.window?.rootViewController?.childViewControllers {
viewControllers.forEach { ([=11=] as? FirstViewController)?.tableView.reloadData() }
}
self.dismissViewControllerAnimated(true, completion: nil)
}
鉴于您正在使用导航控制器:
@IBAction func backButtonTapped(sender: AnyObject) {
navigationController?.viewControllers.forEach { ([=12=] as? FirstViewController)?.tableView.reloadData() }
self.dismissViewControllerAnimated(true, completion: nil)
}
为此您可以轻松地使用通知方法。
在 viewDidLoad 方法中的第一个 ViewController 添加观察者。
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadTable:", name: "reloadTable", object: nil)
func reloadTable(notification : NSNotification){
let isReload : NSNumber = notification.userInfo!["isReload"] as! NSNumber
if (isReload.boolValue) {
self.tableView.reloadData()
}
}
然后 post 当您调用 dismissViewController.
时分别从您的第二个和第三个 ViewController 收到这样的通知// From 2nd viewcontroller
NSNotificationCenter.defaultCenter().postNotificationName("reloadTable", object: nil, userInfo: ["isReload" : NSNumber(bool: false)])
// From 3rd viewcontroller
NSNotificationCenter.defaultCenter().postNotificationName("reloadTable", object: nil, userInfo: ["isReload" : NSNumber(bool: true)])
如果显示vc2是由vc1执行的并且总是肯定会使vc1中的数据无效,则可以执行以下操作:
- 向 vc1 添加一个
needsReload
布尔实例变量 - 每当您显示 vc2 时(以及实例化 vc1 时,例如在
awakeFromNib
中,如果来自故事板)将其设置为 true - 如果needsReload为真,只执行
loadTable
的内容(也许重构这个逻辑为loadTableIfNeeded
) - 别忘了在
loadTableIfNeeded
的最后设置
needsReload
为false
这种失效模式在整个 UIKit 中随处可见,例如 UIView setNeedsLayout
/layoutIfNeeded
。优点是即使有几个事件导致数据失效,它只会在你需要的时候才真正刷新。
在您的情况下,它还有一个额外的优势,即保留包含在 vc1 中的逻辑,并且不会在您的 VC 之间创建不必要的耦合,这总是好的。
---更新:示例实现(ObjC,但你会明白的)
你只需要在 VC1 中处理这个,忘记 VC2 中的所有后退按钮。此实现将在 VC2 出现时立即将 VC1 标记为重新加载,但实际上只会在 VC2 被关闭时在 viewWillAppear 上重新加载。
---更新 2:添加了基于委托回调的条件重新加载
请注意,_needsReload
现在是在委托回调中设置的,而不是在首次呈现 VC2 时设置的。相反,我们将 VC1 设置为 VC2 的委托。 (_needsReload
逻辑上其实不用这种方法,留着参考)
//VC2: add a delegate to the interface
@class VC2;
@protocol VC2Delegate
- (void) viewController:(VC2*)myVC2 didFinishEditingWithChanges:(BOOL)hasChanges;
@end
@interface VC2
@property (nonatomic, weak) id<VC2Delegate> delegate
@end
@implementation VC2
- (IBAction) finishWithChanges
{
[self.delegate viewController:self didFinishEditingWithChanges:YES];
}
- (IBAction) finishWithoutChanges
{
[self.delegate viewController:self didFinishEditingWithChanges:NO];
}
@end
//VC1: implement the VC2Delegate protocol
@interface VC1 () <VC2Delegate>
@end
@implementation VC1
{
BOOL _needsReload
}
- (void) awakeFromNib
{
//adding this for completeness but the way you did it in Swift (at init) is correct
[super awakeFromNib];
_needsReload = YES;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self reloadTableIfNeeded];
}
- (IBAction) displayVC2
{
VC2* myVC2 = ... //instanciate your VC2 here
myVC2.delegate = self; //set as the delegate of VC2
[self presentViewController:myVC2 animated:YES completion:nil];
}
- (void) viewController:(VC2*)myVC2 didFinishEditingWithChanges:(BOOL)hasChanges
{
_needsReload = hasChanges;
[self reloadTableIfNeeded];
}
- (void) reloadTableIfNeeded
{
if (_needsReload) {
[self.tableView reloadData];
_needsReload = NO;
}
}
@end