Thursday, October 22, 2015

iOS 9 Issues

This is just a list for keeping track of iOS 9 related issues I've run into.

1) If you get a list of font families, some of those families do not contain any actual fonts - only seems to affect newer devices.  (reported to apple - marked as dupe)

2) Weird issues with UIView hit test not propagating.   Oddball things where it works everywhere but on an iPhone 6s.  Generally, once recompiled, it works fine.  Actually, I've found that recompiling or changing the hit test code does not work.  In fact, any old style touchesBegan type tap handling does not work on the iPhone 6s.

3) CSS Sibling selectors do not work in certain conditions, for example:

input:checked + label ~ div {
    z-index: 1;

changing to:

input:checked + label + div {
    z-index: 1;

does work, but doesn't work in iOS 8.   Adding both rules seems to do the trick.

4) Using willRotateToInterfaceOrientation to force a UISplitViewController to refresh the layout no longer works.  Should use  setPreferredDisplayMode instead, as in:

    [sv setPreferredDisplayMode:(hideMaster)?UISplitViewControllerDisplayModePrimaryHidden : UISplitViewControllerDisplayModeAllVisible];

for example.

5) External http calls not working (after iOS 9 recompile).  Need to add

   NSAllowsArbitraryLoads  : YES

to info plist.

Tuesday, October 6, 2015

How to use the UIFocusGuide for navigation

I really didn't quite understand how UIFocusGuides were supposed to work until after several hours of banging my head against the wall.  I think I got it now....

The focus guide, like the layout guide it extends, can be thought of as an invisible view - in this case, an invisible focusable view.

A UIFocusGuide functions as a bridge between different areas of the screen since focus navigation only works up/down or left/right.

Consider a screen that has two objects A and B.  



With the default focus behaviors, there is no way to transition from A to B because B is not directly to the right or bottom.

Thus, to make this work, you'd need a focus guide in between, like




and we would set the focus guide's preferredFocusedView = B to start.  

So, given this example layout, if view A has the focus, and the user navigates down, it will find the focus guide (F), and the focus guide will then redirect the focus to the guide's  preferredFocusedView, in this case B.

Of course, if B has the focus, you'd want to update the focus guide so its preferredFocusedView is now A, so that when the user navigates up, it goes from B to A.

Okay, now that you get the concept, what's the code look like?  Something like this (Warning: I have not compiled/run this segment):

UIFocusGuide *F;

- (void)viewDidLoad
   [super viewDidLoad];
   F = [UIFocusGuide new];
   [self.view addLayoutGuide:F];

   [F.topAnchor constraintEqualToAnchor:A.bottomAnchor].active = YES;
   [F.heightAnchor constraintEqualToConstant:1].active = YES;
   [F.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
   [F.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;

   [F setPreferredFocusedView:B];
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator

   if (context.nextFocusedView == A){
       [F setPreferredFocusedView:B];
   } else if (context.nextFocusedView == B){
       [F setPreferredFocusedView:A];

Apple has a simple example in the UIKitCatalog demo that demonstrates the concept in swift.  The layout in that example case is more like:



and it shows the navigation between B and C via F.