Accessibility: Embedding a UITableView inside the Footer of a UITableView - ios

I am trying to reuse an existing UITableViewController by embedding a UITableView in the footer of an existing table.
The premise is that on selection of a row, the footer will appear with a list of further, related options. This works fine but the accessibility inspector is unable to read the rows in the table embedded in the footer.
I created a quick sample of code to show the issue.
Code for the main UITableViewController
#interface MyUITableViewController ()
#end
#implementation MyUITableViewController{
MySubUITableViewController *dataSourceClass;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dataSourceClass = [[MySubUITableViewController alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
if(section == 0){
CGRect tableFrame = CGRectMake(0, 0, self.view.frame.size.width, 200);
UITableView *view = [[UITableView alloc]initWithFrame:tableFrame style:UITableViewStylePlain];
view.rowHeight = 30;
view.scrollEnabled = YES;
view.showsVerticalScrollIndicator = YES;
view.userInteractionEnabled = YES;
view.bounces = YES;
view.delegate = dataSourceClass;
view.dataSource = dataSourceClass;
return view;
}
return nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
if(section == 0)
return 200;
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"identifier";
UITableViewCell *cell;
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"Section %d Row %d", indexPath.section, indexPath.row];
return cell;
}
The code for the table to embed within the footer
#implementation MySubUITableViewController {
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"subCell";
UITableViewCell *cell;
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"Footer Row %d", indexPath.row];
return cell;
}
#end
Anyone know how to get round the Footer rows not being read by accessibility?
I tried
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
}
but to avail.
Thanks

Ok, so the only solution I could get to work, is to create a custom UITableViewCell which implements the UITableViewDataSource, UITableViewDelegate delegates.
Effectively creating a table inside a UITableViewCell.
Something along the lines of:
#interface MyTableWrappingCell() <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, weak) UITableView *myTableView;
#end
#implementation MyTableWrappingCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
myTableView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
myTableView.dataSource = self;
myTableView.delegate = self;
[self.contentView addSubview:myTableView];
self.myTableView = myTableView;
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"subCell";
UITableViewCell *cell;
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"internal Row %d", indexPath.row];
return cell;
}
- (void) forceLoad{
[self.myTableView reloadData];
}
#end
Accessibility is then able to read the contents.

Related

Create a table on objective-c code without storyboard

I can't create table on objective-c, cause I start learning objective-c.
Google can't help me, I tried.
I hope what u can help me
//Update: Below Nick showed the correct answer. After some time, I was prompted to answer this question and now I can share with you the answer. I want to be useful for such guys as I was
- (void)viewDidLoad
{
[super viewDidLoad];
//Here we initialize the table, create delegates and display it on the screen
arrData=[[NSArray alloc]initWithObjects:#"ONE",#"TWO",,#"THREE", nil];
tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
}
#pragma mark - UITableView DataSource & Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return arrData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Cells initialization
static NSString *identifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = [arrData objectAtIndex:indexPath.row];
return cell;
}
For default tableview cell with array:
- (void)viewDidLoad
{
[super viewDidLoad];
arrData=[[NSArray alloc]initWithObjects:#"ONE",#"TWO",,#"THREE", nil];
tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
}
#pragma mark - UITableView DataSource & Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return arrData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = [arrData objectAtIndex:indexPath.row];
return cell;
}
IF YOU ARE USING XIB
You have to create tablviewcell file and design your own cell.
Import your cell file too..
#import "selectedcell.h"
- (void)viewDidLoad {
[super viewDidLoad];
array =[[NSArray alloc]initWithObjects:#"AAAA",#"BBBB",,#"CCCC", nil];
tableView = [[UITableView alloc] initWithFrame:self.view.bounds
style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.tablview registerNib:[UINib nibWithNibName:#"SelectedTableViewCell"
bundle:nil] forCellReuseIdentifier:#"cellidentifier"];
self.tablview.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
[self.view addSubview:tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SelectedTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"cellidentifier" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.label.text = [Nsstring stringwithformate:#"%#",[array objectatindex:indexpath.row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//After selecting row
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}

Programmatically created tableview delegate not working

Lets say I have a tableview created in the storyboard and referenced as "tableViewJobList" and I want to generate a tableview in each cell of tableViewJobList so I do it in cellForRowAtIndexPath.
My .h file (tableViewJobList delegate and datasource is set to viewcontroller in storyboard)
#interface JobByAccountViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableViewJobList;
...
#end
My .m file
...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//realJoblist is my data array
if (tableView == _tableViewJobList) {
return [realJobList count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == _tableViewJobList) {
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == _tableViewJobList) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
//each cell has a tableview
UITableView *subTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
subTableView.delegate = self;
subTableView.dataSource = self;
subTableView.frame = CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height);
[cell addSubview:subTableView];
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == _tableViewJobList) {
NSLog(#"outer tableview");
} else {
NSLog(#"inner tableview");
}
...
}
...
In heightForRowAtIndexPath shouldn't the print statement trigger in the else block because those are the tableviews I created programmatically?
Try this,,,
you just replace your table outlet name.
- (void)viewDidLoad {
[super viewDidLoad];
tableViewJobList.delegate = self;
tableViewJobList.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//realJoblist is my data array
if (tableView == _tableViewJobList) {
return [realJobList count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == _tableViewJobList) {
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == _tableViewJobList) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
//each cell has a tableview
UITableView *subTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
tableViewJobList.delegate = self;
tableViewJobList.dataSource = self;
subTableView.frame = CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height);
[cell addSubview:subTableView];
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == _tableViewJobList) {
NSLog(#"outer tableview");
} else {
NSLog(#"inner tableview");
}
...
}
... `enter code here`

Load Array in UITableView Cell

I want to make paging swipe left and right using UIScrollView after view detailController.
First, main.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
OZDetailViewController *detailViewController = [[OZDetailViewController alloc] initWithNibName:#"OZDetailViewController" bundle:nil];
detailViewController.arrDetailNews = [_arrNews objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
OZDetailViewController *arrNewsAll = [[OZDetailViewController alloc] initWithNibName:#"OZDetailViewController" bundle:nil];
arrNewsAll.allNewsArray = _arrNews;
[self.navigationController pushViewController:arrNewsAll animated:YES];
}
When I selected content in tableviewcell, arrDetailNews can loaded in method viewDidLoad() and cellForRowAtIndexPath(). But arrNewsAll cannot loaded in method cellForRowAtIndexPath().
This is my detailViewController.h:
#property (nonatomic, copy) NSArray *allNewsArray;
And detailViewCOntroller.m:
#synthesize allNewsArray;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.separatorColor = [UIColor clearColor];
NSLog(#"dataArray: %#", allNewsArray);
}
- (int)numberINSectionsInTableView: (UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"dataArrayCell: %#", allNewsArray);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"New Cell"];
}
if(indexPath.row != self.arrDetailNews.count-1){
UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake(0, 44, 320, 2)];
line.backgroundColor = [UIColor whiteColor];
[cell addSubview:line];
}
tableView.allowsSelection = NO;
cell.textLabel.text = [NSString stringWithFormat:#"%u", indexPath.row];
if (indexPath.row==0) {
cell.textLabel.text = #"1st";
}
if (indexPath.row==1) {
cell.textLabel.text = #"2nd";
}
if (indexPath.row==2) {
cell.textLabel.text = #"3rd";
}
return cell;
}
If allNewsArray can loaded in cellForRowAtIndexPath() I can continue next step for paging with UIScrollView. Note, numberOfRowsInSection I set to 4 because I need 4 rows (custom view).
Assuming you setup your delegate & dataSource outlets correctly from xib/storyboard, you still need to specify the number of rows per section (or number of sections).
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return allNewsArray.count;
}
Alternatively, the method for number of sections is:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

Parsing data in uitableview application

I am parsing data from multiple xml files in my iOS application and I need to put all the data together in 1 table. However, whenever I try to change the number of rows in the section to a number such as 5, instead of what is currently there I get an error. I also would like to add two cell identifiers but I am also getting issues when adding an extra cell identifier in the cellforRowatIndexPath method.
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"retrieving");
xmlParser = [[XMLParser alloc] loadXMLByURL:#"http://nodeon"];
xmlParser1 = [[XMLParser1 alloc] loadXMLByURL:#"http://nodeonon"];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *) tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[xmlParser nodes] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
VMdelivered *nodes = [[xmlParser nodes] objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [nodes nodeid];
label = (UILabel *)[cell viewWithTag:2];
label.text = [nodes lastoutput];
return cell;
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 55;
}

Need to add a view as TableHeader?

Is it possible to load a View of height 672 as TableView header?I added it But i am not able to scroll and See the tableview cell Details.
i have used the code
ACCRemainderView *header = [ACCRemainderView customHeaderView];
[self.tableView setTableHeaderView:header];
In the Remainder View
+ (id)customHeaderView
{
ACCRemainderView *customView = [[[NSBundle mainBundle] loadNibNamed:#"ACCRemainderView" owner:nil options:
nil] lastObject];
//make sure customView is not nil or the wrong class!
if ([customView isKindOfClass:[ACCRemainderView class]]) {
return customView;
} else {
return nil;
}
}
Try implementing - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section in your UITableViewController and return [ACCRemainderView customHeaderView].
Set tableHeaderView is the best choice. I tested and it works.
ViewForHeaderInSection can not because at this view header's height is larger than table's height.
You can not scroll, I think your tableView is overlap by another view.
- (void)viewDidLoad
{
[super viewDidLoad];
_tableView.dataSource = self;
_tableView.delegate = self;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *title=[self tableView:tableView titleForHeaderInSection:section];
if ( !title )
return nil;
UIView *view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 500)];
view.backgroundColor = [UIColor greenColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 500;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"abcd";
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"a";
return cell;
}

Resources