Je rencontre un problème lorsque j'ajoute une vue d'entrée personnalisée à mon application sur iOS 8. Cela fonctionnait parfaitement sur iOS 7, mais lors du passage à iOS 8, tout échoue.
Voici la trace de la pile:
2014-06-03 21:23:54.237 MyApp[1910:47245] *** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x1103f9d40>
should have parent view controller:<StopChooser: 0x11083e200> but requested parent is:<UIInputWindowController: 0x110858800>'
*** First throw call stack:
(
0 CoreFoundation 0x00000001042eee35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000103b919a0 objc_exception_throw + 45
2 CoreFoundation 0x00000001042eed6d +[NSException raise:format:] + 205
3 UIKit 0x00000001023d94cd -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:] + 184
4 UIKit 0x0000000102977a2b -[UIInputWindowController changeToInputViewSet:] + 416
5 UIKit 0x0000000102973f56 -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] + 185
6 UIKit 0x000000010297826a -[UIInputWindowController setInputViewSet:] + 526
7 UIKit 0x0000000102973c97 -[UIInputWindowController performOperations:withAnimationStyle:] + 50
8 UIKit 0x00000001027559bb -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:] + 1054
9 UIKit 0x0000000102422afd -[UIResponder becomeFirstResponder] + 468
10 UIKit 0x00000001023235d3 -[UIView(Hierarchy) becomeFirstResponder] + 99
11 UIKit 0x00000001029cdbfb -[UITextField becomeFirstResponder] + 51
12 UIKit 0x0000000102655d61 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 177
lib: terminating with uncaught exception of type NSException
(lldb)
La partie pertinente étant les quelques premières lignes. Quelqu'un peut-il expliquer cela? Tout ce que j'appelle c'est myTextview.inputView = keyboard
; Le clavier étant un UIView créé dans le storyboard et lié via IBOutlet.
J'ai rencontré ce problème auparavant.
Problème:
inputView
ou inputAccessoryView
n'appartient à aucune vue parent. Lorsque vous créez ces vues à partir d'un xib à l'intérieur d'un ViewController, par défaut, elles sont définies en tant que sous-vues d'une vue d'ensemble.Conseils de solution:
removeFromSuperview
dans la vue que vous affecterez à inputView
ou inputAccessoryView
Juste avant becomeFirstResponder
supprimez la vue que vous utilisez pour l'entrée de la vue d'ensemble:
mTextField.inputView = mInputVeiw;
[mInputVeiw removeFromSuperview];
[mTextField becomeFirstResponder];
J'espère que ça aide.
Vous devez vous assurer que la vue que vous affecterez à
inputView
ouinputAccessoryView
n'appartient à aucune vue parent.
Cette erreur est particulièrement gênante car toute "vue d'entrée" créée dans un storyboard (et donc ajoutée au view
du VC) ne peut pas être définie comme inputView
ou inputAccessoryView
sans provoquer cela crash.
Si la vue d'entrée n'est pas ajoutée au view
du VC, la vue d'entrée ne sera pas disponible pour l'édition visuelle dans le Storyboard du générateur d'interface. Il n'est visible que dans le volet gauche du Storyboard.
Je préfère établir une connexion IB au inputAccessoryView
directement dans le Storyboard. Cela provoque ce crash. Une solution que j'ai trouvée est de faire un IBOutlet secondaire connecté à la vue dans le Storyboard, puis dans viewDidLoad
le supprimer de la super vue puis l'assigner immédiatement à inputAccessoryView
. Je ne sais pas si je vais finir par l'utiliser.
- (void)viewDidLoad {
// ...
[self.keybordView removeFromSuperview];
self.inputAccessoryView = self.keybordView;
}
Mon problème était que j'ai nommé une vue ayant un textField 'inputAccessoryView' ...
@property (weak, nonatomic) IBOutlet CustomView *inputAccessoryView;
Erreur:
Terminating app due to uncaught exception
'UIViewControllerHierarchyInconsistency', reason: 'child view
controller:<UICompatibilityInputViewController: 0x7fed7063a1a0> should
have parent view controller:<MyViewController: 0x7fed70606f00> but
requested parent is:<UIInputWindowController: 0x7fed710cde00>'
Solution:
Vérifiez la dénomination; ne remplacez pas s'il n'est pas nécessaire.
Je l'ai compris. Je ne sais pas quel était le problème avant, mais au lieu de lier un UIView
dans le générateur d'interface, j'ai plutôt créé un UIView
par programme et cela a bien fonctionné.
Oui, la solution Tuyen Nguyen n'a pas fonctionné pour moi. Ce qui a fonctionné pour moi dans iOS 8/Xcode 6 pour définir un InputAccessoryView n'était pas à removeFromSuperview
mais à la place:
[[UIApplication sharedApplication].keyWindow addSubview:**MyViewToBeTheUIAccessoryView**];
J'espère que ça aidera quelqu'un.
J'ai eu le même problème lorsque j'ai essayé de configurer mon UIDatePicker dans mon UITextField
- (void)setupViews {
...
dobField.inputView = aDatePicker; // Here was the problem
...
}
Ma solution, je viens "d'allouer" et "init" mon datePicker dans ViewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
...
aDatePicker = [[UIDatePicker alloc] init]; // My solution
...
}
J'ai trouvé la solution créant l'UIView par programme (comme suggéré par Milo), mais elle se bloque lorsqu'elle est utilisée comme un @property. Dans mon cas, je devais créer l'instance UIPickerView dans viewDidLoad et l'assing à UITextView inputView. Quand j'ai besoin d'accéder au sélecteur, je le reçois comme ceci
UIPickerView *picker = (UIPickerView *)self.myTextField.inputView;
L'appel de removeFromSuperView
dans viewDidLoad
ne semble pas fonctionner correctement dans les modaux. J'ai fini par définir la vue cachée, puis la supprimer de superView dans viewDidAppear
.
Ma solution pour ce problème était d'ajouter la vue à inputView, mais pas d'ajouter le contrôleur de vue au parent.
La plupart des réponses que j'ai reçues étaient liées aux changements de code. J'ai découvert que la suppression d'une sortie vers l'UIView dans la vue principale le corrigeait. https://stackoverflow.com/a/40037236/46431
J'ai eu la même erreur lorsque je renvoie une vue du storyboard en tant que inputAccessoryView
. Je l'ai corrigé avec childViewController. Voir ma réponse ici .