Usando Swift 1.1 e Xcode 6.2.
Eu tenho um UIStoryboard contendo uma UIViewController
subclasse única e personalizada . Nele, eu tenho um @IBOutlet
tipo de conexão UIView
desse controlador para uma UIView
subclasse no storyboard. Eu também tenho saídas semelhantes para subviews dessa visão. Veja a figura A.
Mas em tempo de execução, essas propriedades são nulas (Figura B). Embora eu tenha garantido que conectei as tomadas no Interface Builder.
Pensamentos :
- É possível que, por estar usando uma subclasse de uma subclasse, algo atrapalhe a inicialização? Não estou substituindo nenhum inicializador
awakeFromNib:
não está sendo chamado por algum motivo- Talvez não conecte a subvisualizações em subvisualizações
Coisas que tentei:
@IBOutlet
Tipos de itens correspondentes e de storyboard exatamente (em vez deUIView
)- Excluir propriedade e saída e adicioná-los novamente
Figura A *
Figura B
* O código obscuro em Figure A
é:
@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!
Obrigado.
clearView
Espero ser nulo. É algo que ainda preciso refatorar. Veja também a nota de rodapé da figura A. @ShaanSingh Deve ser! porque as conexões de storyboards são (supostamente) definidas no tempo de execução e não devem ser nulas.let vc = UIStoryboard(name: "LocationPickerModal", bundle: nil) .instantiateViewControllerWithIdentifier("LocationPickerModalViewController") as LocationPickerModalViewController
Respostas:
Normalmente, isso acontece porque seu controlador de visualização ainda não carregou sua hierarquia de visualização. Um controlador de visão só carrega sua hierarquia de visão quando algo lhe envia a
view
mensagem. O sistema faz isso quando é hora de realmente colocar a hierarquia de visualizações na tela, o que acontece depois que coisas comoprepareForSegue:sender:
eviewWillAppear:
retornaram.Como seu VC ainda não carregou sua hierarquia de visualização, seus pontos de venda ainda são nulos.
Você poderia forçar o VC a carregar sua hierarquia de visualizações dizendo
_ = self.view
.fonte
viewWillAppear:
é chamado, a primeira vez que faço alguma coisa com aquela tomada. Acessar a vista não faz nada para mim. Ainda nulo.UIViewcontroller.loadViewIfNeeded()
é o método certo para usar aqui.Você já tentou executar Product> Clean. Resolvido um problema muito semelhante para mim.
fonte
DerivedData
pasta do projeto.Você instanciou seu controlador de visualização a partir de um Storyboard ou NIB, ou instanciou-o diretamente por meio de um inicializador?
Se você instanciar sua classe diretamente com o inicializador, as saídas não serão conectadas. O Interface Builder cria instâncias personalizadas de suas classes e codifica essas instâncias em NIBs e Storyboards para decodificação repetida, não define as próprias classes. Se este foi o seu problema, você só precisa alterar o código onde você cria seu controlador para usar os métodos em UIStoryboard ou UINib.
fonte
UIStoryboard
instância e chamandoinstantiateViewControllerWithIdentifier
-a.O storyboard não estava reconhecendo nenhuma outra coisa da interface do usuário que eu adicionei a ele. Em tempo de execução, todas as referências eram nulas. Então, limpei minha pasta de dados derivados e essas conexões funcionaram novamente.
fonte
viewDidLoad()
todas as conexões foram feitas, mas emviewWillAppear()
quase todas foramnil
(às vezes uma ou duas ainda estavam conectadas). Tentei de tudo e finalmente apaguei a pasta de dados derivada, reconstruí, e tudo estava bem.Isso estava acontecendo comigo com minha célula de visualização de coleção personalizada. Acontece que tive que substituir meu método registerClassforReuseIdentifier por registerNib. Isso resolveu para mim.
fonte
Isso aconteceu comigo porque acidentalmente instanciei meu controlador de visualização diretamente, em vez de instanciá-lo por meio do storyboard. Se você instanciar diretamente via
MyViewController()
, as tomadas não serão conectadas.fonte
No meu caso, aconteceu porque eu substituí o
loadView
método na minha subclasse ViewController, mas esqueci de adicionar[super loadView]
Quando você substitui o
loadView
método, é sua responsabilidade inicializar suas subvisualizações. Como você o substitui, as visualizações do construtor de interface não têm a chance de se converter em objetos de cacau e, portanto, as saídas permanecem nulas.Se você implementar loadView em sua subclasse de controlador de visualização, então será sua responsabilidade carregar os elementos de UI do storyboard / xib para o código.
Ou apenas ligue
Para que a superclasse tenha a chance de carregar o storyboard / xib no código.
fonte
Você pode chamar o
controller.view
force para carregar a view para inicializar os IBOutlets, então você poderá atribuir os valores.fonte
Se você instanciar
view controller
por meio de programação. Em seguida, tente criá-lo como abaixoem vez de diretamente
Isso funcionou para mim.
fonte
Para mim, isso ocorreu quando eu acidentalmente declarei a classe do meu controlador de visualização como
(ou seja, como
UINavigationController
não aUIViewController
).O Xcode não pegar esse erro, a classe parece construir bem, e funções de substituição, tais como
viewDidLoad
,viewWillAppear
, etc. todo o trabalho corretamente. Mas nenhum dosIBOutlet
s se conecta.Alterando a declaração para
consertou completamente.
fonte
Eu encontrei esse problema recentemente! Aqui está meu pensamento. O problema não é sobre seu storyboard ou qualquer problema de link. É sobre como você inicia seu ViewController. Especialmente quando você está usando o Swift. (Quase não há nada no editor quando você cria um arquivo de classe)
Simplesmente usando a
init()
classe from super não é possível iniciar nada do que você trabalhou com o storyboard. Então, o que você precisa fazer é alterar a inicialização do ViewController. Substituirlet XXViewController = XXViewController()
porlet XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController
Isso diz ao programa para ir para o storyboard localizar XXViewController e iniciar tudoIBOutlet
em seu storyboard.Espero esta ajuda ~ GL
fonte
2019, UMA POSSIBILIDADE PARA ESTE HORRÍVEL PROBLEMA:
Digamos que você tenha uma visualização de contêiner que mostra algum tipo de relógio. Então você tem
classe Clock: UIViewController
Na verdade, você o usa em vários lugares no aplicativo .
Na tela principal, na tela de detalhes, na tela de edição.
Você tem um aplicativo moderno tipo snapchat complicado.
Na verdade,
Clock
pode realmente ser carregado mais de uma vez ao mesmo tempo em algum lugar na mesma tela . (Talvez esteja oculto em alguns casos.)Você começa a trabalhar em uma instância de
Clock
em um de seus muitos storyboards.Nesse storyboard, você adiciona um rótulo, NewLabel.
Naturalmente, você adiciona a saída em código. Tudo deve funcionar. Todas as outras tomadas funcionam perfeitamente.
Você definitivamente ligado à tomada.
Mas o aplicativo falha com o NewLabel como nulo.
O Xcode diz claramente "você se esqueceu de conectar a tomada".
A razão é esta .......... você tem "NewLabel" em apenas um dos usos do storyboard do Relógio!
A falha é na verdade de >>> outro lugar <<<< você está usando o Relógio !!!!
O Xcode não informa que a falha é de outro lugar, não de onde você está trabalhando!
A falha não é, na verdade, do local em que você está trabalhando - é de outro storyboard, onde não há item "NewLabel" nesse storyboard !!!
Frustrante.
fonte
Para Swift 3.
fonte
Você precisa carregar a hierarquia de visualização primeiro para instanciar as saídas no storyboard. Para isso, você pode chamar manualmente os métodos loadView ou loadViewIfNeeded.
fonte
No meu caso, o aplicativo começou a travar de repente. A depuração revelou que todos os pontos de venda ainda estavam
nil
no momento deviewDidLoad()
.Meu aplicativo ainda usa pontas (não storyboards) para a maioria dos controladores de visualização. Tudo estava no lugar, todas as tomadas devidamente conectadas. Eu verifiquei duas vezes.
Normalmente instanciamos nossos controladores de visualização como
... que por algum motivo parece funcionar, desde que o .xib é nomeado o mesmo que a classe controlador de exibição (não sei como isso funciona, no entanto. Estamos não chamar
init(nibName:bundle:)
com argumentos zero, ou substituindoinit()
a fazê-lo emself
como ele normalmente é sugerido ...).Tentei chamar explicitamente
... apenas para ser saudado com o erro de exceção de tempo de execução:
E então , eu vi:
A caixa de seleção "Associação de destino" do arquivo .xib foi desmarcada.
Deve ter acontecido ao resolver um dos conflitos de mesclagem frequentes em relação ao arquivo de projeto Xcode.
A Apple definitivamente precisa apresentar um formato de arquivo de projeto que seja mais compatível com o SCM.
fonte
Solução 100% funcional para criar ViewControllers a partir de XIB sem StoryBoards
7.1.
7.2.
7.3.
fonte
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
e chamar a etapa 7.2self
diretamente na classe CustomViewController.Verifique se sua conexão IBOutlet se conectou ao proprietário do arquivo ou à visualização. Pode haver erros.
fonte
Outro caso:
Seus pontos de venda não serão configurados até que a visão do controlador de visualização seja realmente instanciada, o que no seu caso provavelmente está acontecendo logo após initWithNibName: bundle: — em cujo ponto eles ainda serão nulos. Qualquer configuração que você fizer que envolva essas saídas deve ocorrer no método -viewDidLoad do controlador de visualização.
fonte
Para mim, eu tive o mesmo erro em um storyboard localizado, um elemento foi adicionado em algum local e não em outro, então eu tinha uma referência nula para esse elemento quando alternado para o local do elemento ausente, tive que remover a localização (redundante) para esse storyboard usando https://stackoverflow.com/a/42256341/1356559 .
fonte
Para mim, isso estava travando porque
containerView
era nulo.Aqui está meu código com Crash .
O que faltava era ligar para o
super.loadView()
. Então, adicioná-lo resolveu o problema para mim.Código Fixo :
fonte
Tive um problema semelhante ao adicionar o registro (_: forCellReuseIdentifier :) para a célula personalizada, depois de já ter definido o identificador no storyboard. Tinha este código na função viewDidLoad (). Depois de removê-lo, funcionou bem.
fonte
Mais um caso que acabei de encontrar. Mudei o nome da minha classe para o UIViewController, mas esqueci de mudar o nome do arquivo .xib onde a interface foi construída.
Depois de perceber isso e fazer com que os nomes dos arquivos refletissem o nome da classe, estava tudo certo!
Espero que ajude alguém.
fonte
Tenho mais um ...
Se você tiver uma classe personalizada para um UITableViewCell, mas se esqueça de especificar Custom no estilo da célula.
fonte
Você pode validar se o modo de exibição está carregado.
fonte
.h
e.m
veja os arquivos do controladorfonte
Sem querer , criei uma subclasse do meu controlador de visualização com em
AVPlayerViewController
vez deUIViewController
. Repetindo asUIViewController
coisas de volta ao normal. Isso deve ajudar.fonte
Tive o mesmo problema depois de copiar uma classe (vinculada a um xib) para reutilizá-la com outra classe viewcontroller (vinculada a um storyboard). Esqueci de remover
e
métodos.
Depois de removê-los, minhas tomadas começaram a funcionar.
fonte
Eu vejo que você usa
ViewController
!? naViewController
aula você deve usar-viewDidLoad
, não-awakeFromNib
,-awakeFromNib
usar para aUIView
aulafonte
Verifique se há alguma tomada ausente ou desconectada.
fonte
Se você tiver dois
main.storyboards
e estiver fazendo alterações no errado, isso pode acontecer. Isso pode acontecer sempre que você conectar uma tomada de um não instanciadostoryboard
.fonte