omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Change color/style of ui.TableView section headers?

    Pythonista
    tableviewcell tableview
    3
    9
    4369
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • shinyformica
      shinyformica last edited by

      It's not hard to modify the appearance of table cells in a ui.TableView, by changing how the tableview_cell_for_row() method in the delegate for the table creates table cells. But I'm not seeing an easy way to modify the section headers you get when you implement a data source which provides sections as well as rows.

      The data source provider has a tableview_title_for_header() method which works fine to provide the text for the header, but I want to modify the background color and font size for the headers as well...is there any easy way to do that?

      JonB 2 Replies Last reply Reply Quote 0
      • JonB
        JonB @shinyformica last edited by

        @shinyformica I'm sure you've seen https://forum.omz-software.com/topic/5080/tableview-style-header-and-footer

        There is not an easy way to implement with then UI module, unless you treat sections as regular cells, and just format them yourself. I think they won't behave quite the same.

        The alternative is to go full objc.. I vaguely recall someone, maybe me, implementing a wrapper for tableview that implements all of the relevant delegate methods. Or maybe I recall planning to do that.

        As an alternative, it would be possible to swizzle the pythonista tableview delegate, that includes some extra methods.

        1 Reply Last reply Reply Quote 0
        • JonB
          JonB @shinyformica last edited by

          @shinyformica see https://github.com/jsbain/objc_hacks/blob/master/tableview_rowheight.py

          This was more about rowheight, but this would also work for implementing your own custom delegate calls. I think the one you need is

          tableView_willDisplayHeaderView_forSection_

          Which will pass you the header view, then you can mess with the contentView.background, etc.

          I can play around with it this later. Swizzling isn't the ideal solution, but is probably the easiest way without re-implementing all of ui.TableView.

          1 Reply Last reply Reply Quote 0
          • shinyformica
            shinyformica last edited by

            Yeah...I saw that post, but as you pointed out I really would prefer not to completely override and reimplement the way the tableview handles sections just to change the font/color under specific circumstances.

            I was actually just investigating the idea of swizzling the delegate to just implement one additional method, which appears to do exactly what I want:

                willDisplayHeaderView:(UIView *)view 
                forSection:(NSInteger)section
            

            But I'm not clear on exactly how best to safely swizzle that delegate in python/objc...so any pointers there would be appreciated.

            1 Reply Last reply Reply Quote 0
            • shinyformica
              shinyformica last edited by

              Ha @JonB!

              Nice, you posted exactly what I wanted just as I was asking for it.
              You rock, sir.

              1 Reply Last reply Reply Quote 1
              • JonB
                JonB last edited by

                i update tableview_rowheight in the repo above to include an example changing the headerview background.

                in short

                @on_main_thread
                def tableView_willDisplayHeaderView_forSection_(_self,_sel,tv, v,section):
                	tv_o=objc_util.ObjCInstance(_self)
                	pyo=tv_o.pyObject(restype=c_void_p,argtypes=[])
                	tv_py=ctypes.cast(pyo.value,ctypes.py_object).value
                	if tv_py.delegate and hasattr(tv_py.delegate,'will_display_header'):
                			tv_py.delegate.will_display_header(v,section)
                

                this checks for tv.delegate.will_display_header(v,section), and calls it with the headerview.

                Setting up the swizzle needs to only happen once -- could do it in main of an imported module for instance. multiple times wont hurt, in theory.

                def setup_tableview_swizzle(override=False):
                	t=ui.TableView()
                	t_o=ObjCInstance(t)
                
                	encoding=b'v@:@@i'
                	swizzle.swizzle(ObjCClass(t_o._get_objc_classname()),
                		('tableView:willDisplayHeaderView:forSection:'),
                		tableView_willDisplayHeaderView_forSection_,encoding)
                
                

                to change the color you would then define said delegate method, for example

                	def will_display_header(v,section):
                		ObjCInstance(v).contentView().backgroundColor=UIColor.redColor()
                
                1 Reply Last reply Reply Quote 0
                • shinyformica
                  shinyformica last edited by

                  Just so anyone who needs to know, knows: this worked great.

                  You don't actually need to provide the encoding if you are swizzling the delegate on a ui.TableView object, since it already has that method in the protocol it implements. Those encoding strings can be frightening things...in this case there is some danger in encoding an NSInteger as 'i' instead of 'q', since 64bit devices will expect 'q' for NSInteger (not really an issue in this case).

                  It also nice to stick a weakref to the actual pythonista ui.TableView object, or to the data source, into the objc_instance of the ui.TableView, so that when you have your new delegate function called, you can access the python table or data source objects.

                  This is just more evidence that basically anything is possible in pythonista with objc_util.

                  cvp 1 Reply Last reply Reply Quote 0
                  • cvp
                    cvp @shinyformica last edited by

                    @shinyformica said:

                    This is just more evidence that basically anything is possible in pythonista with objc_util.

                    👍

                    1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB last edited by

                      I probably should have pulled out the pyObject and passed that as the tableview object, to be consistent with other delegate methods.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post
                      Powered by NodeBB Forums | Contributors