Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用相同的视图控制器进行添加、显示和编辑_Ios_Model View Controller_Uinavigationcontroller_Uitableview - Fatal编程技术网

Ios 使用相同的视图控制器进行添加、显示和编辑

Ios 使用相同的视图控制器进行添加、显示和编辑,ios,model-view-controller,uinavigationcontroller,uitableview,Ios,Model View Controller,Uinavigationcontroller,Uitableview,我正在开发一个iOS应用程序,它使用一个非常常见的基于核心数据的tableview来显示项目,当选中一个时,它会显示一个更详细的视图,很像Contacts应用程序。细节视图本身是一个以编程方式生成的分组表,具有一个自定义(nib定义)视图,用于具有图片和名称的标题。表中的某些单元格是具有标签名称和文本框值的自定义单元格。在“编辑”模式下,可编辑表格单元格(以及标题中的名称)将.clearButtonMode设置为UITextFieldViewMode,以始终显示它们是可编辑的 我目前正在使用相同

我正在开发一个iOS应用程序,它使用一个非常常见的基于核心数据的tableview来显示项目,当选中一个时,它会显示一个更详细的视图,很像Contacts应用程序。细节视图本身是一个以编程方式生成的分组表,具有一个自定义(nib定义)视图,用于具有图片和名称的标题。表中的某些单元格是具有标签名称和文本框值的自定义单元格。在“编辑”模式下,可编辑表格单元格(以及标题中的名称)将.clearButtonMode设置为UITextFieldViewMode,以始终显示它们是可编辑的

我目前正在使用相同的视图控制器来显示详细信息、编辑信息以及向原始列表中添加新记录

添加新项时,视图控制器是通过自定义init重载以模式创建的,该重载在视图控制器中设置一个标志,指示它正在添加记录。这允许它在编辑模式下启动,如果保留编辑模式,则模型视图将被删除。右菜单栏按钮是通常的编辑/完成按钮,左菜单栏按钮是取消按钮。编辑现有项目时,左侧按钮(正常后退按钮)将替换为取消按钮

我开始重新考虑是否应该让一个视图控制器处理三种不同的模式。有几个问题我不知道如何处理

1) 我如何通过点击“完成”来判断编辑模式是否保留?有行动吗?如果单击“取消”,则该操作将自动解除(添加模式)或恢复先前的值,并退出编辑模式。我想我可以在setEditing覆盖中设置一个复选框来处理它,但似乎应该有更好的方法

2) 当进入编辑模式并且我将可编辑文本字段设置为UITextFieldViewModeAlways时,是否有办法使“X”按钮的外观具有动画效果,以便它们与常规单元格上的编辑指示器一起淡入

这些问题有没有简单的解决方案,或者我的三合一视图控制器是个坏主意?为不同的模式重做相同的视图似乎是不对的,但是为视图控制器提供多个模式似乎有点麻烦


jorj

我还没有完全理解你提出的问题,但这里有一些关于结构的想法,这些想法在一开始可能更有用

似乎您使用单个UITableViewController做了太多的工作,最终不可避免地会出现大量if语句和混乱的代码。我将其分解为两个独立的UITableViewController,一个用于处理主视图(以及您需要的任何后续编辑模式),另一个用于处理局部视图。然后,它们中的一个或两个可以根据需要使用NIB

使用两个这样的控制器,您可以简单地将第二个detailViewController推送到导航堆栈上,而不是以模式显示它,这在本例中似乎不是显而易见的事情

但是,如果您希望以模式显示,可以为detailView编写协议,在按下“取消”、“编辑”或“完成”按钮时发送消息。然后,第一个viewController可以实现协议并接收这些事件


我希望这能有所帮助……

我喜欢三位一体的方法,并一直使用它。有很多优点:一个xib、一个视图控制器、列表和详细视图控制器之间的一个简单协议。是的,还有一些检查,比如
if(self.editing).
,但我更喜欢它,而不是更多的视图控制器和XIB

为了帮助添加,我公开了一个委托可以设置的BOOL

@property (nonatomic) BOOL adding;
1) 内置的editButtonItem不允许您在setEdit:animated之前拦截它:点击Done后进行数据验证时,这是有问题的。由于这个原因,我很少使用editButtonItem,也很少使用自己的Edit、Done和Cancel按钮及其操作方法。见下文

2) 为此,我喜欢UITableView的重载部分:withRowAnimation。对你来说可能有用

- (void)edit:(id)sender 
{
    self.editing = YES;
}
- (void)done:(id)sender 
{
    // data validation here
    if (everythingChecksOut)
    {
      //save here
    } else {
      return; //something didn't validate
    }

    //if control reaches here all is good
    //let the delegate know what happened...
    if (self.adding) {
      [self.delegate didFinishAddingWithData:self.yourData];
    } else {
      [self.delegate didFinishEditingWithData:self.yourData];
    }

    self.adding = NO;
    self.editing = NO;
}
- (void)cancel:(id)sender
{
    [self.view endEditing:YES]; //in theory, forces the view that is editing to resign first responder
    //in practise I find it doesn't work with the YES parameter and I have to use my own flag

    // roll back any changes here

    self.editing = NO;

    if (self.adding) //let the delegate know we cancelled the add...
    {
        [self.delegate didCancelAdd];
    }
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];

    //set your nav bar title
    [self.tableview.editing = editing]; //you may or may not require this
    [self.tableview reloadSections... withRowAnimation:yourChoice];

    if (editing)
    {
        //install your Done and Cancel buttons
    } else {
        //remove Cancel and put the Edit button back
    }
}
然后在viewDidLoad中

- (void)viewDidLoad
{
    [super viewDidLoad];

    //whatever else you do

    if (self.adding)
    {
        self.editing = YES;
    }
}