1

I am trying to make a simple app accessible with VoiceOver.

The app loads a view controller with an opaque view, and tracks the location of one finger on this view. However I cannot understand why I have to re-focus (by tapping) on my view, even after its '(void) accessibilityElementDidBecomeFocused' method is called. I am confused because my view's '(void) accessibilityElementDidLoseFocus' is never called either.

I believe I am correctly following the instructions for View Controller containment from SO and the Apple docs:

1 - http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW81

2 - How does View Controller Containment work in iOS 5?

The code to show the new view controller is as follows:

CGRect frame = self.view.bounds;
customViewController = [[FocusIssueCustomViewController alloc] init];
[customViewController loadWithFrame:frame forViewController:self withAlpha:0.5];

// setting properties of the custom view:
[customViewController.view setAccessibilityLabel:@"Touch area"];
[customViewController.view setMultipleTouchEnabled:YES];
[customViewController.view setIsAccessibilityElement:YES];
[customViewController.view setAccessibilityTraits:UIAccessibilityTraitAllowsDirectInteraction];

// inform user the screen has changed:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, customViewController.view);

and the loadWithFrame method is as follows:

- (void) loadWithFrame: (CGRect) frame forViewController: (UIViewController*) viewController withAlpha: (float) alphaValue
{
// keep a reference to the view controller that requested the Custom View
[self setOriginatingViewController:viewController];

// load the custom view
[self setCustomView:[[FocusIssueCustomView alloc] initWithFrame:frame]];
[self customView].alpha = alphaValue;

// make this the ViewController for this view
self.view = [self customView];

// add the view controller following guidelines from the
// viewController containment in the UIViewController class reference from the Apple docs
[self.originatingViewController addChildViewController:self];
[self.originatingViewController.view addSubview:self.view];
[self didMoveToParentViewController:self.originatingViewController];
}

This custom view then tracks one touch: the implementation file is given below.

#import "FocusIssueCustomView.h"
#define CIRCLE_DIAMETER 110

@interface FocusIssueCustomView ()
{
    // coordinate of this one touch
    float xCood, yCood;
}
@end

@implementation FocusIssueCustomView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
return self;
}

 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {

 // make the custom view opaque
 CGContextRef ctx = UIGraphicsGetCurrentContext();
 CGFloat black[] = {0, 0, 0, 1.0};
 CGContextSetFillColor(ctx, black);
 CGContextAddRect(ctx, rect);
 CGContextFillPath(ctx);
 [self setAlpha:0.5];

 // clear current context
 CGContextRef CurrentContext = UIGraphicsGetCurrentContext();
 CGContextClearRect(CurrentContext, rect);

 // draw a blue circle, no fill for the touch
 CGContextRef context = UIGraphicsGetCurrentContext();
 CGContextSetLineWidth(context, 4.0);
 CGContextSetRGBStrokeColor(context, 0, 0, 255, 1);
 CGRect rectangle = CGRectMake(xCood - CIRCLE_DIAMETER/2, yCood - CIRCLE_DIAMETER/2, CIRCLE_DIAMETER, CIRCLE_DIAMETER);
 CGContextAddEllipseInRect(context, rectangle);
 CGContextStrokePath(context);
 }

- (void) accessibilityElementDidBecomeFocused
{
    NSLog(@"Inside the custom view's \"accessibilityElementDidBecomeFocused\" method");
}

- (void) accessibilityElementDidLoseFocus
{
    NSLog(@"Inside the custom view's \"accessibilityElementDidLoseFocus\" method");
}

#pragma mark - touch method
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // if 1 touch on screen, track this touch
    if ([[event allTouches] count] == 1)
    {
        CGPoint point = [[touches anyObject] locationInView:self];
        xCood = point.x;
        yCood = point.y;
        NSLog(@"Touch at (%f, %f)", xCood, yCood);        
    }

    // redraw
    [self setNeedsDisplay];
}
@end

I genuinely will need a view controller to control this transparent CustomView (hence the view controller containment approach). That is why I am not simply taking an 'addSubview' approach. Any help is greatly appreciated..

Thanks -

VP

Community
  • 1
  • 1

0 Answers0