I am trying to make an TableView inside of a ViewController working as a picker.
Its a simple Table View with o e textlabel.
My Problem is, that i cant leave the tableview on go on to the next textfield.
I have tried it with this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[_textfield becomeFirstResponder];
}
but that only open the keyboard and after i make the input i am back in the tableview.
What must i do to leave the tableview when i select a row?
You need to keep track of and update the preferredFocusView
of you UITableViewCell
subclass depending on whether the cell has been selected and what the UIFocusHeading
is.
The first thing you should do is add a property on your UITableViewCell
subclass to keep track of the current subview you'd like to have focused. For example:
@property (nonatomic, strong) UIView *currentPreferredFocusedSubview;
Then in your view controller in your didSelectRowAtIndexPath
you should set that to the text field you would like focused and then request the focus engine to update:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:YES];
cell.currentPreferredFocusedSubview = cell.textField;
[cell setNeedsFocusUpdate];
}
Now in your UITableViewCell
subclass you need to return your preferred focus view and change how the focus engine updates by overriding preferredFocusedView
and shouldUpdateFocusInContext
:
- (UIView *)preferredFocusedView
{
return self.currentPreferredFocusedSubview;
}
- (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context
{
if (self.currentPreferredFocusedSubview == self.textField && context.focusHeading == UIFocusHeadingRight)
{
self.currentPreferredFocusedSubview = self.textField2;
}
else if (self.currentPreferredFocusedSubview == self.textField2 && context.focusHeading == UIFocusHeadingRight)
{
self.currentPreferredFocusedSubview = self.textField3;
}
else if (self.currentPreferredFocusedSubview == self.textField3 && context.focusHeading == UIFocusHeadingRight)
{
self.currentPreferredFocusedSubview = self.textField3;
}
else if (self.currentPreferredFocusedSubview == self.textField3 && context.focusHeading == UIFocusHeadingLeft)
{
self.currentPreferredFocusedSubview = self.textField2;
}
else if (self.currentPreferredFocusedSubview == self.textField2 && context.focusHeading == UIFocusHeadingLeft)
{
self.currentPreferredFocusedSubview = self.textField;
}
else if (self.currentPreferredFocusedSubview == self.textField && context.focusHeading == UIFocusHeadingLeft)
{
self.currentPreferredFocusedSubview = self.textField;
}
else
{
self.currentPreferredFocusedSubview = nil;
}
return true;
}
Here we just update the preferredFocusedView
based on the direction the focus engine is going. If going up or down, the next row will become focused because we're returning nil
. If left or right, the appropriate text fields. This is somewhat clunky but this is the tvOS 9 way of programmatically updating the focus view.
var currentPreferredFocusedSubview: UITextField?
override var preferredFocusedView: UIView? {
get{
return self.currentPreferredFocusedSubview
}
}
override func shouldUpdateFocusInContext(context: UIFocusUpdateContext) -> Bool {
switch (self.currentPreferredFocusedSubview, context.focusHeading) {
case (self.textField?, UIFocusHeading.Right):
self.currentPreferredFocusedSubview = self.textField2
case (self.textField2?, UIFocusHeading.Right):
self.currentPreferredFocusedSubview = self.textField3
case (self.textField3?, UIFocusHeading.Right):
self.currentPreferredFocusedSubview = self.textField3
case (self.textField3?, UIFocusHeading.Left):
self.currentPreferredFocusedSubview = self.textField2
case (self.textField2?, UIFocusHeading.Left):
self.currentPreferredFocusedSubview = self.textField
case (self.textField?, UIFocusHeading.Left):
self.currentPreferredFocusedSubview = self.textField
default:
self.currentPreferredFocusedSubview = nil
}
return true
}