Forum Archive

Horizontal scroll TableView

BGKirkham

How do I horizontally scroll a TableView? I found where I can bounce it, but I want to scroll it.

Here’s a screenshot of the GUI

As you can see the table keeps going to the right.

mikael

@BGKirkham, I assume the contents of each row are extending beyond the content_view of the cell, and TableView does not really know this is happening.

One option could be to make TableView big enough to fit all rows and columns, and then place it in a ScrollView.

BGKirkham

@mikael

Thank you. That seemed to solve my problem. I had to (set sv.directional_lock_enabled = True) to get it to behave right.

Now I need to work on always displaying the top row (header) of the table during a vertical scroll.

cvp

@BGKirkham you should define your top row as a separate View or even TableView of only one row just above the ScrollView, something like

import ui

v = ui.View()
w,h = ui.get_screen_size()

tv_h = ui.TableView()
tv_h.frame = (0,0,w,32)
tv_h.data_source = ui.ListDataSource(items=range(1))
v.add_subview(tv_h)

sv = ui.ScrollView()
sv.background_color = 'white'
sv.frame = (0,32,w,h-32)
v.add_subview(sv)

tv_l = ui.TableView()
tv_l.row_height = tv_h.height
tv_l.data_source = ui.ListDataSource(items=range(1,101))
hh = tv_l.row_height*len(tv_l.data_source.items)
tv_l.frame = (0,0,w,hh)
tv_l.border_color = 'red'
sv.add_subview(tv_l)

v.present('fullscreen') 
BGKirkham

@cvp

Thanks for the suggestion. That should work. I’ll have to provide a way to horizontally scroll the header table when the scrollview scrolls horizontally.

cvp

@BGKirkham perhaps could you use the same def for tableview_cell_for_row, checking which TableView in it for the content of your separate columns

BGKirkham

@cvp

Yes, that gets the columns defined the same, but I’m not sure how that handles the scrollview scroll event to move the header table. Unless I’m not understanding something. But really it should be able to work both way. If I scroll the header to the right, then the scrollview needs to be scrolled to the right by the same amount. And vice versa. I hope that’s clear.

cvp

Perhaps also set the header TableView as a subview of a ScrollView of only its height and intercept scrollview_did_scroll delegate of both ScrollView to set their content_offset[0] identic so they scroll horizontally together

cvp

@BGKirkham like

import ui

v = ui.View()
w,h = ui.get_screen_size()

sv_h = ui.ScrollView(name='sv_h')
sv_h.background_color = 'white'
sv_h.frame = (0,0,w,h-32)
class MyScrollViewDelegate (object):
    def scrollview_did_scroll(self, scrollview):
        x = scrollview.content_offset[0]
        if scrollview.name == 'sv_h':
            svo = scrollview.superview['sv_l']
        else:
            svo = scrollview.superview['sv_h']
        y = svo.content_offset[1]
        svo.content_offset = (x,y)
sv_h.delegate = MyScrollViewDelegate()
v.add_subview(sv_h)

l = []
for i in range(10,11):
    l.append((str(i)+' ')*50)
tv_h = ui.TableView()
tv_h.font=('Menlo',20)
tv_h.frame = (0,0,w*2,32)
tv_h.data_source = ui.ListDataSource(items=l)
sv_h.content_size = (tv_h.width,tv_h.height)
sv_h.add_subview(tv_h)

sv_l = ui.ScrollView(name='sv_l')
sv_l.background_color = 'white'
sv_l.frame = (0,32,w,h-32)
sv_l.delegate = MyScrollViewDelegate()
v.add_subview(sv_l)

tv_l = ui.TableView()
tv_l.font=('Menlo',20)
tv_l.row_height = tv_h.height
l = []
for i in range(11,100):
    l.append((str(i)+' ')*80)
tv_l.data_source = ui.ListDataSource(items=l)
hh = tv_l.row_height*len(tv_l.data_source.items)
tv_l.frame = (0,0,w*2,hh)
tv_l.border_color = 'red'
sv_l.content_size = (tv_l.width,tv_l.height)
sv_l.add_subview(tv_l)

v.present('fullscreen') 
mikael

@BGKirkham, when you are done with this view, would be nice if you could publish it as a generally usable table view.

BGKirkham

@cvp

Thank you for the suggestion.

I ended up going a different way. I made the header a TableView above the Scrollview. I then added a scroll delegate to the scroll view which sets the header scroll position based on the scrollview position

class MyScrollViewDelegate (object):
        def scrollview_did_scroll(self, scrollview):
            x = scrollview.content_offset[0]
            hv = scrollview.superview['headerView']
            hv.content_offset = (x, 0) 

Shown scrolled a little

This implementation doesn’t allow scrolling based on the user dragging the header. I decided it wasn’t that important to me.

BGKirkham

@mikael

Will do.

I’ve been including links to my screen shots, which will eventually disappear. Is there a way to directly embed the image in my post?

cvp

@BGKirkham use link, no text, with a ! In front

cvp

@BGKirkham said:

I ended up going a different way

👍 even better

cvp

@BGKirkham said:

Is there a way to directly embed the image in my post

You can always quote a post to see which commands are used for a visual effect

cvp

It seems that it does not work with iCloud photos but it does for imgur and a lot of other ones

Perhaps because iCloud needs a login

BGKirkham

@cvp

Fixed in both posts

mikael

@BGKirkham, thanks.

Note that the images are still not copied over to the forum in any way, and will go away when you remove or move them at your end.

BGKirkham

@mikael

I understand. I have control over them now, I didn’t previously. They were going to be automatically deleted after a month on the Apple cloud site.