So it appears that there is no simple way to make a UITableViewController scroll horizontally. By scroll horizontal I mean maintain vertical scrolling AND add the ability to scroll horizontal to view UITableViewCell's whose data elements are wider than the screen and to scroll the entire table as a coherent table. I don't want to turn the UITableView 90 deg so it will scroll horizontal at the expense of scrolling vertical and I don't want to scroll the data in each cell individually. The solution I came across for UITableView that was most like what I'm talking about is here but I didn't implement this solution. Instead I changed my entire approach and deleted a bunch of code. Because I was displaying spreadsheet like data I created a CSV file and opened it using the Quick Look QLPreviewController. It opens the file and provides both vertical and horizontal scrolling and allows the user to save or share or email the file which was something else I needed to implement so this solution killed the proverbial 2 birds with 1 stone and it was pretty simple.
In my view controller I imported QuickLook.h and adopted the protocol.
#import <UIKit/UIKit.h>
#import <QuickLook/QuickLook.h>
@interface MyTableViewController : UITableViewController <QLPreviewControllerDataSource>
@end
I declare 2 properties in my view controller
@interface TimersTableViewController ()
@property NSString *csvFile;
@property QLPreviewController *qlController;
@end
The protocol implementation in my controller is:
// quick look preview controller protocol methods. there is only one file and it is the csv file
// this controller will allow the use to decide what they want to do with the file. DML 11/21/2019
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
return 1;
}
- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
return [NSURL fileURLWithPath:self.csvFile];
}
Then I wrote my data to a file and called QLPreviewController to display it.
- (void)setLogs:(NSArray<LogRecords *> *)logs{
_logs = logs;
// allocate the quick look preview controller to display the csv file.
if (self.qlController == nil){
self.qlController = [[QLPreviewController alloc] init];
// set self as it's datasource
self.qlController.dataSource = self;
}
// get the path to the NSDocumentDirectory which
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// the path I want is the first object in the array
NSString *documentsDirectory = [paths objectAtIndex:0];
// set the cvs file name
self.csvFile = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"MyCSVFile.csv"];
// use NSFileManaget to create the file because it needs to exist before it can be opened with NSFileHandle
NSFileManager *fm = [NSFileManager defaultManager];
[fm createFileAtPath:self.csvFile contents:nil attributes:nil];
NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:self.csvFile];
// write the header to the csv file
[file writeData:[@"date,time,message" dataUsingEncoding:NSUTF8StringEncoding]];
// for my app I loop through the logs and write each of them to the file
for (int i = 0; i < self.logs.count; i++){
[file writeData:[[[self.logs objectAtIndex:i] toCsvString] dataUsingEncoding:NSUTF8StringEncoding]];
}
[file closeFile];
// make sure quick look preview controller gets latest csvFile
[self.qlController reloadData];
// display the quick look preview controller
[self presentViewController:self.qlController animated:YES completion:nil];
}
This solved both of my issues at once: scrolling horizontally and allowing the user access to the file to save or share it.