在另一个 ViewController 中切换编辑模式
Toggle edit mode in another ViewController
我在导航控制器中嵌入了一个 ViewController(带有容器视图)。容器包含一个页面 ViewController,其中一个 'pages' 是 TableViewController(UITableView 出口:'aTableView').我想在导航栏中点击自定义 editButton 时触发 tableViewController 中的编辑模式。当我在 tableViewController 中创建自定义 editutton 时,编辑模式按预期工作,但是当我在导航栏中使用自定义 editButton 时,即使我在 editButton 选择器中将 setEditing 设置为 YES,setEditing bool 值仍然为零。这是代码:
ViewController.m
-(void)viewDidLoad {
self.editBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.editBtn setFrame:CGRectMake(0, 0, 40, 22)];
[self.editBtn addTarget:self action:@selector(goToToggleEdit:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *editButton=[[UIBarButtonItem alloc]initWithCustomView:self.editBtn];
self.navigationItem.rightBarButtonItem = editButton;
}
-(void)goToToggleEdit:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
TableViewController *tvc = [storyboard instantiateViewControllerWithIdentifier:@"aTableViewController"];
if(something==foo){
[tvc toggleEdit];
}
}
aTableViewController.h
@interface aTableViewController : UITableViewController <UITextFieldDelegate> {
IBOutlet UITableView *aTableView;
}
-(void) toggleEdit ;
@end
aTableViewController.m
-(void)toggleEdit {
[aTableView setEditing:YES animated:YES];
NSLog(aTableView.editing ? @"Yes" : @"No"); // --> logss 'No'.
if (aTableView.editing){
//do something
}
else {
//do something else
}
}
如何才能有效地触发表格中的编辑模式ViewController?
编辑
@Bagrat Kirakosian 向我指出我的视图层次结构(导航控制器 > 视图控制器(带容器)> 页面视图控制器(在容器中)> Table 视图控制器)可能是问题所在。我只想创建一个固定的导航栏(带有编辑按钮),因此我不能将 Table 视图控制器直接嵌入导航控制器中。
谢谢。
更新:解决方案
虽然@sebastien 和@Bagrat 的解决方案都很好,但我已经接受了@sebastien 的解决方案。 @Bagrat 的回答包括直接访问 Table 视图控制器,而 @sebastien 的解决方案在页面 ViewController 中调用编辑模式。我认为,考虑到棘手的层次结构,后者更安全一些。
这是我的视图控制器的代码,完全可以正常工作。请确保您在 View Controller 生命周期的正确方法中配置了您的条形按钮。还要确保您的@selector 在您的代码中正确实现。
在同一个视图控制器中放置这两块代码
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"edit_icon.png" ] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] style:UIBarButtonItemStylePlain target:self action:@selector(edit:)];
[rightBarButton setTintColor:[UIColor whiteColor]];
self.navigationItem.rightBarButtonItem = rightBarButton;
}
之后你还需要把你的编辑选择器
-(void)edit:(UIButton *)sender {
// Toggle edit by inverting current edit state
// Also in this block change your right bar button text or image
[self.tableView setEditing:!self.tableView.editing animated:YES];
}
更新 1
在您发表评论后,我们开始讨论另一个问题。您的问题不在您尝试调用切换编辑的部分。您的问题是控制器层次结构错误 (Navigation Controller > View Controller > Page View Controller > Table View Controller)。这可能会导致问题。尝试像这样更改您的控制器;
UINavigationController > UIPageViewController > UIViewController(s)
此外,在 UIViewController
中使用 UITableView
而不是使用 really dead UITableViewController
是一个好习惯。不要忘记连接您的 tableView IBOutlet(顺便说一句,您在 UITableViewController 中不需要它),同时连接 datasource
和delegate
致文件所有者。在您的 MyTableViewVC.h 文件中添加此行
@interface MyTableViewVC : UIViewController <UITableViewDataSource, UITableViewDelegate>
之后您的所有通话都将正常工作。
更新 2
在分析了你的整个结构后,我发现你每次点击按钮时都会犯错误。
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
tvc = [[TodolistTableViewController alloc] init];
当你每次都调用故事板时没问题,但是当你这样做时 [[TodolistTableViewController alloc] init]
你每次都 RE-MAKING 相同的 table 视图控制器但不是甚至将其添加到您的主视图中。正如我告诉过你的,你的棘手层次结构可能会带来困难,但它有一个解决方案。
在你的 PageViewController.m
中,在 .h 文件中创建 tv1 和 tv2 属性,就像这样。
@property (strong, nonatomic) UITableViewController *tv1;
@property (strong, nonatomic) UITableViewController *tv2;
然后在视图控制器文件中执行此操作
-(void)toggleEdit:(id)sender
{
PageViewController *current = (PageViewController *)[[self childViewControllers] firstObject];
if ([current isKindOfClass:[PageViewController class]])
{
[((TodolistTableViewController *)[current tv1]) toggleEdit];
}
}
答案包括所有安全检查和直接访问您的 table 视图控制器,因为您以后可能需要更改其他 properties/call 功能。
现在,在 -(void)toggleEdit:(id)sender
中,您不必每次都重新创建视图,但您可以捕获当前视图控制器中已有的视图。
祝你好运!
好的,您的问题是您试图以错误的方式访问嵌入式控制器。
您实际上管理着 2 个不同的 PageViewController
:
- 你通过故事板生成的那个
- 您在代码中进一步启动的另一个
这就是为什么你达不到预期的结果。
首先,为您的 PageViewController
添加一个新方法:
PageViewController.h:
- (void)editTableAtIndex:(int)index;
PageViewController.m:
- (void)editTableAtIndex:(int)index {
[[self viewControllerAtIndex:index] setEditing:YES];
}
现在,在您的主 ViewController 中,使用 childViewControllers
:
访问 PageViewController
-(void)toggleEdit:(id)sender
{
PageViewController *pvc = self.childViewControllers[0];
[pvc editTableAtIndex:0];
}
应该编辑你的 TodoListTableView
:
(请注意我使用了 [pvc editTableAtIndex:0];
,而你应该调用 [pvc editTableAtIndex:_PageViewController_current_index_];
)
我在导航控制器中嵌入了一个 ViewController(带有容器视图)。容器包含一个页面 ViewController,其中一个 'pages' 是 TableViewController(UITableView 出口:'aTableView').我想在导航栏中点击自定义 editButton 时触发 tableViewController 中的编辑模式。当我在 tableViewController 中创建自定义 editutton 时,编辑模式按预期工作,但是当我在导航栏中使用自定义 editButton 时,即使我在 editButton 选择器中将 setEditing 设置为 YES,setEditing bool 值仍然为零。这是代码:
ViewController.m
-(void)viewDidLoad {
self.editBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.editBtn setFrame:CGRectMake(0, 0, 40, 22)];
[self.editBtn addTarget:self action:@selector(goToToggleEdit:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *editButton=[[UIBarButtonItem alloc]initWithCustomView:self.editBtn];
self.navigationItem.rightBarButtonItem = editButton;
}
-(void)goToToggleEdit:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
TableViewController *tvc = [storyboard instantiateViewControllerWithIdentifier:@"aTableViewController"];
if(something==foo){
[tvc toggleEdit];
}
}
aTableViewController.h
@interface aTableViewController : UITableViewController <UITextFieldDelegate> {
IBOutlet UITableView *aTableView;
}
-(void) toggleEdit ;
@end
aTableViewController.m
-(void)toggleEdit {
[aTableView setEditing:YES animated:YES];
NSLog(aTableView.editing ? @"Yes" : @"No"); // --> logss 'No'.
if (aTableView.editing){
//do something
}
else {
//do something else
}
}
如何才能有效地触发表格中的编辑模式ViewController?
编辑
@Bagrat Kirakosian 向我指出我的视图层次结构(导航控制器 > 视图控制器(带容器)> 页面视图控制器(在容器中)> Table 视图控制器)可能是问题所在。我只想创建一个固定的导航栏(带有编辑按钮),因此我不能将 Table 视图控制器直接嵌入导航控制器中。
谢谢。
更新:解决方案
虽然@sebastien 和@Bagrat 的解决方案都很好,但我已经接受了@sebastien 的解决方案。 @Bagrat 的回答包括直接访问 Table 视图控制器,而 @sebastien 的解决方案在页面 ViewController 中调用编辑模式。我认为,考虑到棘手的层次结构,后者更安全一些。
这是我的视图控制器的代码,完全可以正常工作。请确保您在 View Controller 生命周期的正确方法中配置了您的条形按钮。还要确保您的@selector 在您的代码中正确实现。
在同一个视图控制器中放置这两块代码
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"edit_icon.png" ] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] style:UIBarButtonItemStylePlain target:self action:@selector(edit:)];
[rightBarButton setTintColor:[UIColor whiteColor]];
self.navigationItem.rightBarButtonItem = rightBarButton;
}
之后你还需要把你的编辑选择器
-(void)edit:(UIButton *)sender {
// Toggle edit by inverting current edit state
// Also in this block change your right bar button text or image
[self.tableView setEditing:!self.tableView.editing animated:YES];
}
更新 1
在您发表评论后,我们开始讨论另一个问题。您的问题不在您尝试调用切换编辑的部分。您的问题是控制器层次结构错误 (Navigation Controller > View Controller > Page View Controller > Table View Controller)。这可能会导致问题。尝试像这样更改您的控制器;
UINavigationController > UIPageViewController > UIViewController(s)
此外,在 UIViewController
中使用 UITableView
而不是使用 really dead UITableViewController
是一个好习惯。不要忘记连接您的 tableView IBOutlet(顺便说一句,您在 UITableViewController 中不需要它),同时连接 datasource
和delegate
致文件所有者。在您的 MyTableViewVC.h 文件中添加此行
@interface MyTableViewVC : UIViewController <UITableViewDataSource, UITableViewDelegate>
之后您的所有通话都将正常工作。
更新 2
在分析了你的整个结构后,我发现你每次点击按钮时都会犯错误。
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
tvc = [[TodolistTableViewController alloc] init];
当你每次都调用故事板时没问题,但是当你这样做时 [[TodolistTableViewController alloc] init]
你每次都 RE-MAKING 相同的 table 视图控制器但不是甚至将其添加到您的主视图中。正如我告诉过你的,你的棘手层次结构可能会带来困难,但它有一个解决方案。
在你的 PageViewController.m
中,在 .h 文件中创建 tv1 和 tv2 属性,就像这样。
@property (strong, nonatomic) UITableViewController *tv1;
@property (strong, nonatomic) UITableViewController *tv2;
然后在视图控制器文件中执行此操作
-(void)toggleEdit:(id)sender
{
PageViewController *current = (PageViewController *)[[self childViewControllers] firstObject];
if ([current isKindOfClass:[PageViewController class]])
{
[((TodolistTableViewController *)[current tv1]) toggleEdit];
}
}
答案包括所有安全检查和直接访问您的 table 视图控制器,因为您以后可能需要更改其他 properties/call 功能。
现在,在 -(void)toggleEdit:(id)sender
中,您不必每次都重新创建视图,但您可以捕获当前视图控制器中已有的视图。
祝你好运!
好的,您的问题是您试图以错误的方式访问嵌入式控制器。
您实际上管理着 2 个不同的 PageViewController
:
- 你通过故事板生成的那个
- 您在代码中进一步启动的另一个
这就是为什么你达不到预期的结果。
首先,为您的 PageViewController
添加一个新方法:
PageViewController.h:
- (void)editTableAtIndex:(int)index;
PageViewController.m:
- (void)editTableAtIndex:(int)index {
[[self viewControllerAtIndex:index] setEditing:YES];
}
现在,在您的主 ViewController 中,使用 childViewControllers
:
PageViewController
-(void)toggleEdit:(id)sender
{
PageViewController *pvc = self.childViewControllers[0];
[pvc editTableAtIndex:0];
}
应该编辑你的 TodoListTableView
:
(请注意我使用了 [pvc editTableAtIndex:0];
,而你应该调用 [pvc editTableAtIndex:_PageViewController_current_index_];
)