Why doesn't UIScrollview have an accessibility area in the Interface Builder? - objective-c

I've noticed that a UIScrollView doesn't have mentioned accessibility area where I can set accessibility label or accessibility. This seems to apply for activity indicators too.
Why does UIVIews, UIButtons and more have this area and not UIScrollView and UIActivityIndicatorView?

Good question - the reason for a scroll view is that Apple don't consider it to be an accessible element.
If you look at the UIAccessibility documentation, you'll find Apple have the following to say on what counts as an 'accessible element':
The only exception to this [a view being accessible] is a view that merely serves as a container for other items that should be accessible. Such a view should implement the UIAccessibilityContainer protocol and set this property to NO.
A UIScrollView is simply a container for subviews, so its isAccessibilityElement property is set to no (hence why you don't see the accessibility options in interface builder).
So basically, when you're using a scroll view the items inside it should be accessible, but not the scroll view itself.

To add more details on UIAutomation accessibility labels for UIScrollView you will have to use the index to the ScrollView to access subviews on the scroll view. Eg :
target.frontMostApp().mainWindow().scrollViews()[0].buttons()["logoutButton"].tap();
NOTE : Assumption is that the "logoutButton" is the accessibility label for the logout button and it is a subview on the scroll view.

Related

UIPageControl (Page Control) not show in UIPageViewController

my UIPageViewController class conforms to UIPageViewControllerDataSource protocol and yet UIPageControl is not visible.
I've attached screen representing segues between UIPageViewController and it's child UIViewController's which are added by setViewControllers method.
Question is why Page Control is not shown and what can i do with it except adding UIPageControl instance to view myself ?
For some reason, it seems as though UIPageControl only appears when the Transition Style is set to "Scroll" -- very frustrating! (Hope I'm wrong?)
Click on your UIPageViewController ('Home Page View Controller'?) to see the option under Page View Controller.
Make sure you've implemented the optional -presentationCountForPageViewController: and -presentationIndexForPageViewController: data source methods.
UIPageViewController.h is very clear about the requirements:
A page indicator will be visible if both methods are implemented,
transition style is 'UIPageViewControllerTransitionStyleScroll', and
navigation orientation is
'UIPageViewControllerNavigationOrientationHorizontal'.

UIScrollView with controls repeating on every page?

I have perfectly working UIPageControl. I would like to add paging by swipe, and as I understood, it is done by UIScrollView.
But all tutorials are done with images, I want to have controls (labels, buttons) repeating on every page.
Because UIScrollControl is working the way that it must have set its width * pages count, does it mean, that controls can be placed only in code, not in IB?
Should I place labels and buttons directly on UIScrollView?
Thanks
If you have a View Controller designed using IB with all its buttons and labels, then it is possible to add that View Controller as a subview of your UIScrollView as such:
[scrollView addSubview:controller.view];
scrollView being your UIScrollView and controller being your IB designed View Controller.
You can achieve repeating controls with pagecontroll by using IB by ordering the objects appropriately. Here's what I have:
Drag the UIScrollview to the ViewController and also the drag the Page Controller and other controls also to the ViewController but not onto the UIScrollView. Keep them separate. The objects on the bottom of the IB list of objects shows up at the top of the view stack. (So when you swipe new pages the controls dont move and isn't covered by the UIScrollView) I also group the various controls by group selecting them and then use the "embed with view" menu item so that in IB I have two groups, the controls and the UIScrollView. Makes it neater and easier to manage. As for changing labels, I haven't tried it but I've seen tutorials where you can have iboutlets linked to changing value of pagecontroller and then update the labels in uiscrollview appropriately.

Creating a Scrolling Categories Section In a Navigation Controller (XCode)

So I'm curious. I was looking into a way to create a categories selector similar to the one located at the top of this application: http://itunes.apple.com/us/app/xfeed-rss-reader/id313206921?mt=8 ... 06921?mt=8. Would I tackle this using a Toolbar and elongating it to where the user can 'scroll' side to side for categories? Or a ScrollView with a Tabbar in it? I want to do this the 'proper' way per say and I've seen flags raised about a Tabbar being in a ScrollView.
If I were implementing this, I would create it with a UIScrollView containing UIButtons. UITabBars have some nice integration with UIViewControllers and UINavigationControllers, but the benefits quickly drop off when you need more customizable behavior (left to right scrolling, for instance.). I would normally just put them all in a xib and connect the outlets appropriately, unless it was important that they be dynamic.
You mentioned correctness, so an even more "correct" way is to create a UIControl similar to a UISegmentedControl that handles the creation of properly sized labels, deals with touches appropriately, etc. If you are setting categories dynamically you'll want to override sizeThatFits: and call sizeToFit so you can properly size the content area of your scrollview.

In Interface Builder, how can I add UIViews to a subview that is a part of a custom view I've created?

I am working to create a custom view for an iPhone app I'm creating. This custom view is a Popover dialog which is made up of a UIView which contains two images, a button to close the dialog, a label, and a UIScrollView. This view is named MDPopoverCard. I have these files as a part of my view:
MDPopoverCard.xib - The view as drawn up in Interface Builder.
MDPopoverCard.h - Defines a few IBActions and some other properties
MDPopoverCard.m - Implements some functions defined in the header
This is what it looks like in Interface Builder: http://cl.ly/2B0f2x3s1w1i0K2G0Q1r (sorry, I can't post an image yet as I'm new to stackoverflow)
There are a few properties defined in my .m and .h files that control whether the green button is displayed and what the text of the title label is.
I need to display a number of these dialogs in my app and I'd like to reuse this interface I've designed. I want to be able to add buttons and other form elements into the UIScrollView via Interface Builder. However, I have a problem:
Imagine that I have another view I'm drawing up in Interface Builder. I add a UIView to it and set its class to MDPopoverCard. I then drag a couple UIButton objects into my MDPopoverCard view. Here's an example of what it looks like in Interface Builder:
http://cl.ly/1X090h1t1q3f0i3E0917
This screenshot shows another view (the root view) that I've added my MDPopoverCard to. I've then added two buttons as subviews of MDPopoverCard.
These buttons do get properly nested in Interface Builder. However, when I run my app these buttons are added before any of the items that make up my MDPopoverCard view in the xib file. This means that the buttons are being added behind my popover dialog. That's the first problem.
The second problem is that I want these buttons and form elements to actually be added into the UIScrollView that's contained within the MDPopoverCard view, and not just right into the UIView's subviews array. Is there a way to specify this in Interface Builder? I'd really much rather draw buttons into my UIView and connect them to IBActions via Interface Builder than hand write every instance of these dialogs that I may need to display (several).
Any advice? Is there anything I can do to clarify the question?
Thanks for your help!
Formerly Xcode supported user-defined IB plugins for custom UI elements which you could just drag and drop into the XIBs the same way you do with built-in widgets. As of Xcode 4 this nice feature has been removed. (Thanks a lot, Apple.)
Currently I can only think of a hacky way to achieve what you described. What I would do is the following:
create an IBOutletCollection on your MDPopoverCard, e.g. embeddedControls
link it with every UI element (here: the buttons) you want to go inside the scroll view
implement the awakeFromNib in MDPopoverCard and explicitly reset the superview of all the views in embeddedControls to the scroll view in there
Hope this helps (although I haven't tried).

How can I enable zoom in on UIWebView which inside the UIScrollView?

I have a UIWebView which inside a UIScrollView (scrollview contain another component)
I tried to enable multitouch both on Interface Builder or Programmatic on UIWebView but it still cannot zoom for html, do I need to handle both zoom in at the UIScrollView and UIWebView? Or anything I haven't to set?
You MUST set scalesPageToFit=YES for any pinching and zooming to work on a UIWebView
OK, you need to do both the above, but also the following. I had a web view in the main view, and that didn't work.
As above, you first have to put a UIScrollView in the main view, then put the web view in the scroll view.
As above, implement <UIScrollViewDelegate> in your view controller, drag the scroll view delegate to the view controller in Interface Builder, and implement the viewForZoomingInScrollView method. This must return the pointer to the UIScrollView (return myScrollView).
I created IBOutlet properties for both the web view and the scroll view - link them in the NIB to your view controller.
On the Scroll View, go to the Attributes Inspector, set your Max and Min zoom factors (I set 0.5 to 5.0, that works well).
On the Web View, in the Attributes Inspector:
In the Web View section, select Scales Pages To Fit
In the View section, select for Mode, "Top Left"
In the View section at the bottom, check off User Interaction Enabled, and Multiple Touch Enabled
With JavaScript you can control the zoom level, although the oly solution I have found doesn't look smooth.
Say you have in <head>:
<meta id="vp" name="viewport" content="width=768,initial-scale=1.0">
To zoom to 4x, and still allow the user to change zoom, change the content twice:
var vp = document.getElementById('vp');
vp.content = "width=767,minimum-scale=4.0,maximum-scale=4.0,user-scalable=yes";
vp.content = "width=768,minimum-scale=0.25,maximum-scale=10.0,user-scalable=yes";
Toggling the width is very important - otherwise Mobile Safari has serious repainting bugs (due to over-optimisation).
You cannot just set initial-scale again - it is ignored the second time.
You need to implement the viewForZoomingInScrollView method in your controller, or zooming won't do anything. (I don't really know why this should be needed, but there you go.)
For detailed information, see http://developer.apple.com/iphone/library/documentation/WindowsViews/Conceptual/UIScrollView_pg/ZoomZoom/ZoomZoom.html.