VoiceOver only speaks two cell and skips remainder cells - uicollectionview

My app has a banner that is made with horizontal UICollectionView.
And the data of banner get from server.
The banner has two or more count (test count was 4.).
But the VoiceOver only speaks two cell and skips remainder cells.
View Hierarchy is
ViewController > TableView > CollectionView
CollectionView in TableViewCell
- (void)setVoiceOver
{
self.isAccessibilityElement = NO;
self.collectionView.isAccessibilityElement = NO;
}
CollectionViewCell
-(void)setArr:(NSDictionary *)arr
{
_arr = arr;
[self setVoiceOver];
}
-(void)setVoiceOver
{
self.isAccessibilityElement = YES;
self.contentView.accessibilityElementsHidden = NO;
self.accessibilityLabel = [NSString stringWithFormat: "ad%d", _arr["bannerId"]];
}
I want to make VoiceOver reads all banner cells.

I guess the VoiceOver can access the collectionViewCell which is appeared in the screen.
I tested several apps, the cells that I can access with the voiceover swipe gesuture are over the screen a little bit.
like this.
enter image description here
So the voiceover have to adjust to collectionview, not the collectionviewcell.
And we can access each cell by scrolling gesture (three finger swipe)

Related

NSTableView Cell Display Issue

I'm using a view-based NSTableView, and I've ran across a little issue.
I'm trying to switch the text color of my two labels from black to white when highlighted.
To do so, I've written the following code,
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
NSView * viewInQuestion = [table viewAtColumn:0 row:[table selectedRow] makeIfNecessary:YES];
if ([viewInQuestion isNotEqualTo:lastViewSelected])
{
[(NSTextField*)lastViewSelected.subviews.lastObject setTextColor:NSColor.blackColor];
[(NSTextField*)[lastViewSelected.subviews objectAtIndex:1] setTextColor:NSColor.grayColor];
}
[(NSTextField*)viewInQuestion.subviews.lastObject setTextColor:NSColor.whiteColor];
[(NSTextField*)[viewInQuestion.subviews objectAtIndex:1] setTextColor:NSColor.whiteColor];
lastViewSelected = viewInQuestion;
}
That works great; I get this result:
The issue is that sometimes the text doesn't appear white even though an NSLog told me that the NSTextField's color was NSCalibratedWhite (or whatever it's called).
The color also switches back to black when the textField is not visible (scrolling away from it and then back). Yet again, even when it does this, the NSTextField's color is still logged as white.
Overriding setBackgroundStyle on NSTableViewCell has worked perfectly for me, at least on OS X 10.8. (Given the number of relevant questions here on SO, one can guess that there used to be some problems before.)
The background style is updated on selection events and on window activation/deactivation, just as one would expect.
Here's my custom cell impl — as trivial as it can get:
#implementation RuntimeInstanceCellView
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
[super setBackgroundStyle:backgroundStyle];
self.detailTextField.textColor = (backgroundStyle == NSBackgroundStyleLight ? [NSColor darkGrayColor] : [NSColor colorWithCalibratedWhite:0.85 alpha:1.0]);
// self.detailTextField.textColor = (backgroundStyle == NSBackgroundStyleLight ? [NSColor blackColor] : [NSColor whiteColor]);
}
#end
My method is very hacky, and probably not the optimal solution; But it resolves it so that's good.
Assuming you implemented tableSelectionDidChange the way I have, all you need to do is register an NSNotification and implement a custom method that should be more explicit.
In the init, awake, or didFinishLaunching part of your application...
NSView * contentView = table.enclosingScrollView.contentView;
[contentView setPostsFrameChangedNotifications:YES];
[NSNotificationCenter.defaultCenter addObserver:self selector:#selector(boundsDidChange:) name:NSViewBoundsDidChangeNotification object:contentView];
Somewhere else in the program...
(assuming hasUpdatedCell is a BOOLEAN property)
- (void)boundsDidChange:(NSNotification *)notification
{
/* Bounds can change while nothing is selected--> but we only want to execute the method if a cell is selected. */
if ([table selectedRow] == -1) {return;}
NSRect visibleRect = table.enclosingScrollView.visibleRect;
NSView * viewInQuestion = [table viewAtColumn:0 row:[table selectedRow] makeIfNecessary:YES];
NSPoint selectedViewOrigin = [viewInQuestion convertPoint:viewInQuestion.frame.origin toView:table.enclosingScrollView];
/* If the selected cell is visible, then we can go ahead and redraw the white text as a part of the workaround.
This is because scrolling away from the selected cell and back will make the cell revert back to black. */
BOOL cellVisible = NSPointInRect(selectedViewOrigin, visibleRect);
/* We already know we need to update it, and we will so we don't need to evaluate the next step in the program */
if (!cellVisible && !hasUpdatedCell) {return;}
if (cellVisible && !hasUpdatedCell)
{
/* The cell is visible but we haven't updated. Let's do it then. */
[self tableViewSelectionDidChange:nil];
hasUpdatedCell = YES;
}
else if (!cellVisible)
{
/* The cell is not visible and we need to update next time. */
hasUpdatedCell = NO;
}
}
Things then should get displayed properly.

Displaying an arrow for indicating user to scroll up or down in a UITableView in objective c

I want to display an arrow which indicates the user to scroll up or down in a table depending on the data in the table.
i.e Down arrow indicating user to scroll down or Up arrow indicating scroll up.
How can i gt the current status of the table to display arrows?
Many Thanks,
Avi.
Since UITableView is the subclass of UIScrollView. Implement the followin UIScrollView delegate in you view controller:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (tableView.contentOffset.y <
tableView.contentSize.height - tableView.frame.size.height)
downArrow.hidden = NO;
else
downArrow.hidden = YES;
if (tableView.contentOffset.y > 0)
upArrow.hidden = NO;
else
upArrow.hidden = YES;
}
DownArrow and uparrow shoulf be your images placed at the appropriate positions on your view.

iOS increase edit mode indentation for custom UITableViewCell

I've got a UITableView with the ability to delete the rows using edit mode etc. As standard, when you tap the 'edit' button, you go into edit mode and the content of the cells gets moved to the right. If you do a 'swipe to delete', the cell content stays where it is.
What I want to do is increase the indentation when you enter edit mode. I've tried the UITableView delegate method indentationLevelForRowAtIndexPath but that doesn't seem to work when I'm using a UITableViewCell subclass.
In the end I used the layoutSubviews method in my UITableViewCell subclass. Below is my code:
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect b = [self bounds];
if(self.editing && !self.showingDeleteConfirmation){
b.origin.x = 42;
}
[self.contentView setFrame:b];
}
This indents the cell content further when you enter edit mode and thanks to the "!self.showingDeleteConfirmation", when you do a 'swipe to delete', it doesn't indent it.
However, when you tap the 'edit' button, then tap one of the circle delete buttons, the cell content slides back to the original 0 x axis position. This is because the showingDeleteConfirmation is now set to true.
I've tried to fix this by checking what the current origin.x value is, but every time I check, it's set to 0.
Is there a way I can achieve what I want?

How to hide tab bars and show full tableview on screen?

In my app's implementation, I have a tabbar controller with 5 different tabs.
After I hide my tab bar via the following code
- (void)hideTabBar
{
for(UIView *view in self.tabController.view.subviews)
{
if([view isKindOfClass:[UITabBar class]] || [view isKindOfClass:[UIButton class]])
{
view.hidden = YES;
}
}
}
I still see the bottom portion of my tableview obscured by a white rectangular section (previously occupied by visible tabbar)
For example, before I hide the tab bar
After I hide the tab bar, the tableview still does not completely show on the screen, the bottom section is still occupied by a white rectangular space (previously occupied by the tab bar
As mentioned above, how can I hide the tabbar and ensure that the whole tableview is displayed on my screen?
myViewController.hidesBottomBarWhenPushed = YES;

Objective-C : Endless UIScrollView without pagingEnabled

In my iPhone app there is a scrollview pagingEnabled=NO which can contain up to 200 subviews (150 x 150) and the challenge is to do lazy loading and simulate endless scrolling (without bouncing) in horizontal directions.
Is there a solution or an alternative for this request?
Lazy loading of a scroll view is demonstrated in one of Apple's sample code projects: PageControl.
To fake endless scrolling what I'd suggest is to make your scroll view very wide to begin with, wider than an average person would scroll in one set of scrolling behaviors. Then in your delegate methods -scrollViewDidEndScrollingAnimation:, -scrollViewDidEndDragging:willDecelerate: and -scrollViewDidEndDecelerating:, one or more of which will be called after the user is done scrolling, reposition your content to exist in the center of the scroll view and update your contentOffset point without animating.
For that to work visually you would need to also disable the horizontal scroller. You'll also need to consider how to determine what view to draw at a particular contentOffset with this method since you won't be able to just divide the contentOffset.x by the scroll view's bounds anymore to find out where you are.
Hello I found the way to do it.
I have a master array with all the subviews (in my case they are images, so I store the names).
The scrollview only has 3 subviews: left, current, right.
Paging is enabled, so the user cant really spin more that one view left/right at any time.
What I do is:
1) track his current position on the master array. If he moves left, subtract one; right add one. Like this:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[some code to determine current page, based on contentOffset]
if (page == 0){
NSLog(#"Going left");
if (currentPage > 0){
currentPage--;
} else {
//cycle to last
currentPage = [images count] -1;
}
} else if (page == 2){
NSLog(#"Going right");
if (currentPage < ([images count] -1)){
currentPage++;
} else {
//cycle to first
currentPage = 0;
}
} else{
NSLog(#"Not moving");
}
2) after the user moves, I reload 3 new images, like this:
//updates the 3 views of the scrollview with a new center page.
-(void) updateScrollViewForIndex:(NSInteger)newCenterPage{
//fist clean scroll view
for (UIView *sView in [scroll subviews]){
[sView removeFromSuperview];
}
NSInteger imgCount = [images count];
//set center view
[self loadImageIndex:newCenterPage atPosition:1];
//set left view
if (newCenterPage > 0){
[self loadImageIndex:newCenterPage-1 atPosition:0];
} else {
//its the first image, so the left one is the last one
[self loadImageIndex:imgCount-1 atPosition:0];
}
//set right view
if (newCenterPage < imgCount-1){
[self loadImageIndex:newCenterPage+1 atPosition:2];
} else {
//its the last image, so ther right one is the first one
[self loadImageIndex:0 atPosition:2];
}
}
3) Finally re-center the scroll view to the center view again:
[scroll setContentOffset:CGPointMake(1 * viewWidth, 0)];
Hope this helps, although "the man with the plan" is Mr. Clark, who pointed the way.
Gonso
Matt Gallagher has a blog post which describes a solution to this exact problem. I've used it and it works great.
The UIScrollView and UIPageControl in Cocoa Touch allow for user interfaces with multiple panning pages. The sample project that Apple provides (PageControl) keeps all child views for every page in a lazily loaded array. I'll show you how you can implement this using just two child views, no matter how many virtual pages you wish to represent.
It works by shuffling around the child views and reseting their content when necessary. I used this for displaying flash cards, where there could be anywhere from 3 to 3,000 items. Although it's set up right now for paging, I'm sure you could get it to work with regular scrolling.