TVOS UITextView is not scrolling

UITextView
in
TVOS
not scrolling, I can see its
contentSize
is great then its
bounds
, I can confirm that
scrollEnabled = YES
,
userInteraction = YES
and it is current focused view.

Accepted Reply

By default UITextView is not focusable. Setting -selectable to YES will allow it to become focused, but you'll be responsbile for any focus appearance.

Replies

If you want to allow the user to scroll a UITextView you'll need to set the -allowedTouchTypes to .Indirect.

are you talking about textView.panGestureRecgonizer.allowTouchesType = @[@(UITouchTypeIndirect)];, then I tried that also and no luck

Maybe you already did this. But I found that I had to set userInteractionEnabled = YES in the ViewController's viewDidLoad method. Setting that flag in InterfaceBuilder didn't work.

For some reason I can't even deliver focus to my UITextView. What can be the cause of that?

By default UITextView is not focusable. Setting -selectable to YES will allow it to become focused, but you'll be responsbile for any focus appearance.

I have a UITextView that I have set Selectable, User Interaction Enabled, and Editable in IB, but it still doesn't seem to get focus. Should I file a bug report, or are you saying I still need to subclass and override the focus methods?

You can check by stopping at a breakpoint and doing:


po [textView _whyIsThisViewNotFocusable]

Thanks for the tip, although I guess this isn't particularly helpful:

(lldb) po [_moveArea _whyIsThisViewNotFocusable]

ISSUE: This view returns NO from -canBecomeFocused.

What is the result of:


po [_moveArea isSelectable]

Hmmm yeah the result is NO despite being checked in the IB storyboard.

(lldb) po [_moveArea isSelectable]

NO

Does it work if you set it in code?

Thanks, that lets me get focus. But there is no visual indication of when focus is actually there (except that nothing else has focus). Also, scrolling still doesn't seem to happen.

Great, please file a bug report at https://bugreport.apple.com about that option in IB not working.


UITextView does not provide a focus appearance so you'll be responsible for that. In a subclass you can implement the following method.


- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
    if (context.nextFocusedView == self) {
        // handle focus appearance changes
    }
    else {
        // handle unfocused appearance changes
    }
}


For scrolling see this post.

I spent some time on this today, I was able to get the UITextView to scroll with the remote with the following implementation:


class TextViewController: UIViewController {
    @IBOutlet weak var textView: UITextView!
   
    override var preferredFocusedView: UIView? {
        return textView
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
        textView.selectable = true
        textView.panGestureRecognizer.allowedTouchTypes = [NSNumber(integer: UITouchType.Indirect.rawValue)]
    }
}

Thanks Brad R - I added this to my ViewController viewDidLoad and was able to get focus and scroll:


    // Set UITextView to be selectable with scroll (IB doesn't do this)
    //     IBOutlet UITextView *resultText;
    resultText.selectable = true;
    resultText.panGestureRecognizer.allowedTouchTypes = [NSArray arrayWithObjects:[NSNumber numberWithInteger:UITouchTypeIndirect], nil];


Focus doesn't show up visually by default, you have to handle that yourself by extending didUpdateFocusInContext as mwhuss mentions. Here is what I used for a quick "focus" effect:


// Extend UITextView
@interface UITextField (UIFocusUpdateContext)
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator;
@end

@implementation UITextView (UIFocusUpdateContext)
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
    if (context.nextFocusedView == self) {
        // handle focus appearance changes
        [self setBackgroundColor:[UIColor whiteColor]];
        NSLog(@"Focused!");
    }
    else {
        // handle unfocused appearance changes
        [self setBackgroundColor:[UIColor clearColor]];
        NSLog(@"Unfocused");
    }
}
@end


I'm not too crazy about the text scrolling with the remote touch (IndirectTouch) if you have other controls in the View because the focus will leave the UITextView in random ways as focus on the other controls. I think I need to lock the focus on the UITextView or remove the other controls from the UI View while the user is scrolling.