Accessibility for UINavigationController and UINavigationItem - ios

I'm improving the accessibilty of my iOS project and am using an UINavigationController.
My UINavigationItem has two buttons, the left one is "Cancel".
By default, the cancel buttons gets selected when showing the view.
So the first thing a user hears is "Cancel".
What I really want is that the title should be selected and spoken, and the
cancel button should not be selected.
Questions:
Is this how it should be, and what could be the reason for this?
Has anyone successfully unselected the button and instead selected the title?
Thanks,
Claes

From Apple's UIAccessibility Guide:
UIAccessibilityLayoutChangedNotification - Posted by an application when the layout of a screen changes, such as when an element appears or disappears. This notification includes a parameter, which is either an NSString object that VoiceOver speaks or an accessibility element that VoiceOver moves to.
So you can do something like this:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification,title);
}
You should replace "title" in the above code with the actual Accessibility element you want to be selected and spoken.
You can also use UIAccessibilityScreenChanged instead of UIAccessibilityLayoutChanged "when a new view appears that comprises a major portion of the screen".

Related

Attaching a custom alert view above the iOS keyboard

I'm trying to design (a "properly designed," not "hack") custom alert view. The view should attach itself to the top of the keyboard; sliding up with the keyboard (if there is an alert) or being hidden (if there is no alert).
The view should always "stick" to the keyboard... including, for instance, when the keyboard hides. In that case, the view should slide right down, out of sight, along with the keyboard.
Here's an example of what I'm trying to achieve (with an active alert):
I have originally thought about subclassing UIAlertView, but it looks like that is not recommended. And, after experimenting a bit, this is clearly a tricky task. I've got an alert that shows up but, it turns into problems staying in sync with the keyboard, and I haven't found a way to make it "track" with the motion of the keyboard... not smoothly.
Any ideas?
You can achieve this with inputAccessoryView of UITextField and UITextView. See Custom Views for Data Input chapter in Apple's "Text Programming Guide for iOS" for more information.
For example, a very simple red bar above the keyboard can be added with the following code:
let keyboardAlertView = UIView(frame:CGRectMake(0,0,320,44))
keyboardAlertView.backgroundColor = UIColor.redColor()
textField.inputAccessoryView = keyboardAlertView

UIButton subview in UICollectionViewCell not changing control state

I have a UICollectionView where each UICollectionViewCell has a UIButton as a subview. The UIButtons respond to taps no problem (their targets get fired), but the button itself does not change to the selected state (no change in look and feel of the button). I have a hunch it's because of the UICollectionViewCell not properly forwarding its touch events to the button, but I'm not sure. Even if that's so, how do I set things up so that the button's state changes properly in this scenario?
The UIScrollview (and thus UICollectionView too) has a property called delaysContentTouches, by default it is set to YES, change this to NO and your button should highlight like it is supposed to.
If i may suggest an alternative, the UICollectionView has an awesome delegate method called
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { }
which could handle the click to that cell... if you are looking for specific events to happen like seeing an image change to the state of the button, you could hard code that in... when they press the button do one thing, when they release the button do another thing....
according to the documentation as well
UIControlStateSelected
Selected state of a control. For many controls, this state has no effect on behavior or appearance. But other subclasses (for example, the UISegmentedControl class) may have different appearance depending on their selected state. You can retrieve and set this value through the selected property.
in laymens terms.. for a UIButton the "Selected State" does nothing...
if the the button is suppose to dim when it's clicked and it's not doing that, then you may have to do that programmatically if, but i'm not exactly sure what you are trying to do...
the dimming feature is with in the highlighted state
UIControlStateHighlighted
Highlighted state of a control. A control enters this state when a touch enters and exits during tracking and when there is a touch up event. You can retrieve and set this value through the highlighted property.
in laymens terms, you touch the button it's highlighted
to see if the button is changing states properly you can do something like this
[button addTarget:self action:#selector(functionToCall:) forControlEvents:UIControlEventAllTouchEvents];
NSLog(#"Selected: %i", button.selected);
NSLog(#"Highlighted: %i", button.highlighted);
NSLog(#"Normal State or not: %i", button.state);
the "functionToCall will be called when any type of touch even happens to the button and with in that function you could have those 3 NSLogs which will print to your console the different UIControlState values, this will show that the button is working properly and show that it may be a UIViewCollection error, if it's the UICollectionView... then you will have to programmatically dim the button :3
hope this helps !

clearButton not working in UITextEditField

This is one of those "it was working a while ago" troubleshooting efforts.
I'm working on the document preview view controller, in which is a scroll view, which itself contains subclasses of UIView that represent each document. I'm modeling this pretty closely to how Keynote handles its document preview, except I build my scroll view horizontally and with paging. But the standard user experience is present: Long press on a document icon causes all document icons to start jiggling, nab bar has + button and Edit button, etc.
The issue at hand is that when you tap on the name of a document, I hide all the others, move the one being edited front and center, build a new text edit field, add it as a subview atop the real name label, and set it as first responder; but the
[editNameTextField setClearButtonMode:UITextFieldViewModeWhileEditing];
while correctly showing in the edit field is not taking any action when the user taps on the clear button.
I can't figure out what I may have done to cause this to not work -- it had been!
My first thought was that somehow my instance of this subclass is no longer the delegate for this text edit field. To try and confirm/deny that, I usurped a tap on the image view of the document preview to compare the delegate property to self, and it passes.
if (editNameTextField) {
NSLog(#"editNameTextField is still active");
if ([editNameTextField.delegate isEqual:self]) {
NSLog(#"we're still the delegate for the editNameTextField");
}
}
Editing the text within the edit field works fine. Pressing the Return/Done key correctly sends the delegate message textFieldShouldReturn:
While investigating this I implemented the delegate method textFieldShouldClear: just to write a log message if the method gets called (and return YES of course). It never gets called.
My next thought was that perhaps a subview had covered up the area where the clear button sits. So I implemented textFieldShouldBeginEditing: and used the opportunity to bring my the text field to the front. That didn't change anything either. I set a debugger breakpoint there to play a sound when it was called, and it got called, so I know my text edit field is frontmost.
I have only one troubleshooting strategy remaining: Go backwards through snap shots until it starts working again. Before doing that I thought I'd see if any of the more experienced folks out here have any suggestions of what to try next.
Where are you adding the textfield? As a subview of the scrollView? If you added the textfield and it is out of bounds of its parent view it won't receive any touches.
You can try and not call becomeFirstResponder and see if clicking it will show keyboard. Another possible error might be that the parent view of the UITextField has userInteractionEnabled = NO.
Without seeing more code I'm afraid I can not offer more solutions.

ios navigation buttons

I'm doing a custom nav in ios for the first time. I have six buttons laid out in a row. When I tap the button, I want the image to change. However, the button is not togglable. The only way a button can be unselected is if another button is touched. Only one button can be active at any given time.
My idea:
use UIButtons
change UIButton image on touch
keep track of the active button inside the navigation class
when an inactive button is touched, make the currently active button inactive and turn the touched button to active
I want the end product to work like a custom TabBarController, but without switching layouts. I just want to edit the content in the current ViewController.
Is there a better way to do this?
You could just use the UISegmentedControl, which has that functionality already. If you need to significantly customise the look and feel though, your UIButton solution sounds fine.
I setup the UIButtons in the Interface Builder like so:
Default with unselected background image
Disabled with selected background image
On touch, a button is self.enabled = NO which makes the UIButtons look change. However, the button goes dim, so I also implemented self. adjustsImageWhenDisabled = NO.
This way a button can't be re-selected once it's "active".

How do I make the keyboard go away when the user clicks somewhere else? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Dismiss keyboard by touching background of UITableView
How do I make the keyboard go away when the user clicks somewhere else?
Note: I know how to make the keyboard disappear with sending the resignFirstResponder command to the UITextField. At present the "Done" button is connected to all the correct code to do this and this works.
I have a UITableView with different UITableViewCells, and if the user moves onto another cell I want the keyboard to disappear.
So what events do I also need to include the resignFirstResponder in, for the keyboard to disappear.
Suppose UITableViewCell A has the UITextField, and UITableViewCell B has a button. If the user presses the button in cell B, then I will need to send the command resignFirstResponder back to the UITextField in cell A. First of all the button has no idea which cell it should sent the command to, and second even if the button did know which cell to send the command to how would it?
There's no trivial way to do this. You can put a transparent set of "shield views" all the way around the text field that take up the rest of the screen, and use any touches on them to dismiss the keyboard.
You can create a generic 'hideKeyboard' method in which you can include all text fields that can be first responders. For example,
-(void) hideKeyboard {
[textFieldName resignFirstResponder];
[textFieldSurname resignFirstResponder];
for (UITextField * txtField in arrTextFields) {
[txtField resignFirstResponder];
}
}
Then, at various sections in your class, depending on the functionality required, call;
[self hideKeyBoard];
This simple method means you won't need to keep track of the individual item that 'has the focus' / first responder status.
How to touch any part of the screen to make the keyboard go away
To touch somewhere outside the UITableView and have the keyboard disappear, place an invisible button on top of the 'touch area' that you want to respond to. Then, simply call [self hideKeyboard] from the touch event for that invisible button. Using IB, drag a new rounded button onto your view, then size it to take up the full size of the screen. Next,drag the button up or down the controls list in the IB document window so that button is behind all text fields and buttons, but in front of anything else (like images etc.). Finally, change the type of the button to 'Custom' to make it invisible, but still respond to events. Now all you have to do is to connect the new button's 'touch up inside' event to trigger the 'hideKeyboard' method.
Additionally, see this post for a brilliant solution to dismiss the keyboard when the above solution doesn't work : stackoverflow question 1823317

Resources