0

I have a Table View Controller Scene which has a Table View Controller which has a Table View which has a Table View Cell which has the Content View which has my 3 UILabels. All it well, it displays my data and I can scroll up and down through my data just fine.

However, my data in my Table View Cell is wider than the screen. I would like to be able to scroll the entire table horizontally so all the data in my table is viewable. I was able to add a UIScrollView to the Content View and then each individual cell was capable of scrolling horizontally, but the data is columnar so scrolling it as a table makes more sense. I understand that UITableView is incapable of scrolling horizontal for whatever reason, in which case it seems reasonable to put the entire table into a UIScrollView. However there seems to be no possible way to insert the UIScrollView between the Table View and the Table View Controller in IB.

Any suggestions as to how to go about implementing this seemingly basic functionality work? I have to be missing something really basic.

Lehrian
  • 311
  • 1
  • 2
  • 8

2 Answers2

0

I don't think it's easy to achieve what you're mentioning using just a table view. One way would be each cell of the table view to be a collection view with horizontal scrolling. Here's an article on how to do that.

Another option would be to use a collection view with a custom flow layout so you can provide both vertical and horizontal scrolling. If I'm not wrong, what you want to achieve is something like that. It shows how to do it, but it's a bit old article and code is in Objective-C.

Also, take a look at this StackOverflow question where it's suggested to do it with a scroll view and a collection view.

Generally speaking, search around a bit on StackOverflow and the web. I found many sites/articles discussing about this topic, so you'll definitely come up with a solution.

Gabb
  • 107
  • 5
  • Thanks for your response. Your first and third links are solutions that don't scroll the entire table horizontally but scroll the contents of the individual cells. I was able to implement that by putting a UIScrollView into the Content View and then adding my labels to the UIScrollView. Your second link is more like a solution I was looking for whereby the entire table scrolls, like a spreadsheet. In the end I ended up using abandoning UITableViewContoller and used Quick Look and the QLPreviewController which opens my data as a CSV file and allows horizontal and vertical scrolling. – Lehrian Nov 22 '19 at 01:09
0

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.

Lehrian
  • 311
  • 1
  • 2
  • 8