Pergunta

Eu tenho um UIViewController - vamos chamá-lo "FormController" - que é simplesmente uma forma que edita um objeto. Eu quero usá-lo em 2 situações diferentes:

  1. A criação de um novo objeto -. Usando usando o método presentModalViewController: de UINavigationController

  2. Edição de um objecto existente - empurrar o controlador de visualização para a pilha UINavigationController, não utilizando um método de diálogo

  3. .

Há uma ligeira diferença de que, na situação modal eu gostaria de ter uma barra de ferramentas com "Cancelar" e botões "Feito", enquanto que na situação pilha eu gostaria de ter apenas a barra de navegação fornecidos pela UINavigationController.

Isto seria semelhante para o aplicativo Contatos em que o "Novo Contato" e "Editar Contato" telas parecem usar o mesmo controlador de vista, mas a forma Novo contato é apresentado de forma modal enquanto a tela Editar é empurrado para a pilha de navegação .

A minha pergunta é: Qual é a melhor maneira de lidar com ambas as situações sem ter que escrever 2 separados, mas na maior parte idênticos controladores de vista

Eu pensei sobre a criação de um "ModalFormController" que encapsula o nu "FormController" através da composição e adiciona uma barra de ferramentas, mas eu li em algum lugar na documentação que a Apple não recomenda controladores de vista de nidificação.

Foi útil?

Solução

O que eu faço (por vezes), é criada uma enum que especifica o tipo do controlador de vista.

Por exemplo, você pode ter dois tipos: um tipo Edit, e um tipo de Add ( "nova").

O tipo Add é implementado por meio de um controlador de vista modal, enquanto o tipo Edit é empurrado para uma pilha de navegação existente.

No método -viewDidLoad: do controlador de vista, eu simplesmente faço uma árvore switch/case que configura o título e outras características de aparência dependendo da enumeração tipo especificado acima.

A coisa agradável sobre este é que é fácil de adicionar um novo tipo. A desvantagem é que a árvore condicional para entregar essa enumeração pode ficar complicado rapidamente, dependendo de como diferentes tipos são.

Mas a árvore switch/case torna muito mais fácil de gerir.

Então, isso depende do que você está tentando fazer com os dois tipos. Mas é definitivamente factível.

Outras dicas

Por que não usar subclassificação? Faça ModalCreateFormController uma subclasse de EditFormController e lidar com o material específico-modal na subclasse.

Além de ter uma propriedade explícita sobre o controlador de vista (como Alex Reynolds sugere), duas outras abordagens que me ocorrem são:

  1. Se você tem algum tipo de modelo de objeto que você está editando, pedir-lhe para seu estado atual. Se ele nunca foi salvo, então você está no modo de edição. Caso contrário, você está no modo de criar.

  2. Olhe para o valor da propriedade parentViewController do controlador. Se é uma instância de UINavigationController, então você está na pilha de navegação. Se você estiver sendo exibido modalmente, vai ser uma instância de lista de seu controlador.

Ug, eu odeio ivars extras ...

Eu uso isso em vez disso:

if([[self.navigationController viewControllers] objectAtIndex:0] == self){

        //Modal

    }else{

        //Pushed

    }

É um pouco de um truque, mas nós estamos usando a lógica de que, se o controlador de vista ofensora é o primeiro na pilha, você não pode voltar. Na verdade, estamos ignorando o fato de saber se é modal exibida em tudo.

Eu tive que fazer isso um monte de vezes em meu aplicativo e depois de tentar algumas maneiras diferentes de fazê-lo, incluindo subclasses modais e uma re-utilizáveis ??classes auxiliares modal que forwardInvocation usado. Eu encontrei o melhor padrão era fazer um método containingModalViewController cada vista controladores que (geralmente) Cria e retorna um UINavigationController para o chamador para uso com presentModalViewController.

Na maioria dos casos este método cria e retorna um UINavigationController com auto como o controlador de vista raiz (com chamadas repetidas para o método de verificação self.navigationController e retornando que, ao invés, se não é nulo). Outros casos Fiz um controlador de raiz manequim primeira e empurrou auto em segundo, a fim de obter um botão de volta. Em seguida, um truque pode ser usado para capturar o botão voltar de imprensa: http: // smallduck .wordpress.com / 2010/10/05 / interceptando-UINavigationController /

Em alguns casos, a visão não precisa de uma barra de navegação e assim este método apenas ajusta algumas bandeiras e retornos self. Eu mesmo encontrei em alguns casos, que tinha necessidade de uma barra de navegação era mais simples para fazer esse método invoke self.view, em seguida, ajustar a hierarquia vista para adicionar um UINavigationBar e novamente retornar self. Mas em qualquer caso, a configuração frequentemente isoladas a esse método de um, e as alças de chamada-lo da mesma em cada caso.

a Apple explica como funciona o aplicativo de contatos sob o capô:

Para permitir que uma classe de controlador de exibição personalizado para ser usado tanto para exibir o conteúdo e editar, substituir o método setEditing:animated:.

Você tem algumas funcionalidades de graça, por exemplo, Edit/Done botão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top