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.
ui.TableViewCell - returning a custom class instead?
-
Really, this is so cool. I did nothing, just hanging on the work of others. I have done a million cells, does not phase it in the slightest. It's the 2 magics, @JonB 's a custom TableCellView and the magic sitting behind ui.TableView. Not sure if that magic is @omz or iOS foundation classes. But who cares, it's great.
-
Ok, then Speedy Jomzales!
-
@JonB, I thought your approach here might solve another problem I have with the ui.Rect class. I would like to be able to add attrs to ui.Rect, but as far as I know normally you can't just make an assignment as its not written in python. But I thought I would try your idea here, but it does not work. I am guessing the reason why what you do with TableViewCell works because ui.View can be subclassed. But I still gave it a go , just in case 😱
import ui class CustomUIRect(object): # my_color = None def as_rect(self, x=0, y=0, w=0, h=0): r = ui.Rect(x, y, w, h) return r def __init__(self, color): print('in init') self.my_color = color if __name__ == '__main__': r = CustomUIRect('blue').as_rect() print(dir(r)) print(r.my_color)
-
The difference is that, for the custom tableview cell, it returns a tableview cell with the content view filles with the current view. Your as_rect is returning a Rect...so you need to set any Rect attributes in the method.
-
@JonB , thanks. I think it would be good if there was a ui.Rect on steroids for use with ui.Path etc. that could be subclassed. It's all about rects. I know we have ui.View etc. but whole views are not really required or wanted when doing ui.Path stuff. I think of it like using smart rects like a wire frame design. I think it's a good idea, but more than likely just a lack of skill on my part
-
I guess I don't understand what you are trying to achieve. Just encapsulation of colors with the rect? Or is there something else? Your approach would work if you just convert the custom rect to a rect at the drawing time, rather than sending to your class.
-
@JonB , basically I would just like to be able to subclass ui.Rect, which you can't as its written in Objective C I am guessing , like you can't directly ui.Switch for example.
The reason, I want it I really want to make wire frame views. Meaning I just want to use rects to describe the views and yes a few more attrs and methods as required. I know you are thinking well that's just called a ui.View. But that's just so heavy compared to a extended ui.Rect.
I went back to your FlowContainer repo today. However, I didn't strike me how it could help me constructing wire frame views. Not to say it won't later. As I say, I am a slow learner.
I am not sure if you tried my crude example here, as basic as it is, if you try doing it with ui Elements you will see a huge difference, with speed.
But @JonB , I don't understand your comments about my last code example. I didn't try to draw it. I just tried create the custom Rect adding a instance attr, then accessing the attr. Hmmm, even as I write it, I can see it's a little stupid what I am saying. But all I want to do is extend ui.Rect with attrs and methods. It's probably just so easy. But I don't see a clear way to do it.
-
I think you might find a ui.View is not as heavy as you think... the app has probably a hundred Views nested dozens deep. Once you come up with something that is actually too "slow", then figure out how to optimize it..
But, that aside, If you are in control of your drawing method, you can "extend" rects by encapsulation, rather than subclassing. In other words, you would have a class that includes a Rect instance attribute, a line and fill color attributes, and whatevr else you want to customize. Then you could simply have a draw() method which creates a Gstate, and draws to the current context (Gstate would ensure that setting fill color to draw a rect does not change thnglobal fill,color). You then call your custom draw from the draw() method of your top View. In other words, your WireFrameContainer would have a list of CustomRects and you cycle through calling draw for each CustomRect.
@polymerchm made a pyui explorer a while back that showed the entire heirarchy of a pyui views as wireframes, to allow you to more easily encapsulate views inside conainer views, and move views from a deep layer to a top layer, etc.
https://github.com/polymerchm/pyuiEdit
Not sure if this is still compatible with the new pythonista verstions, but it might have some ideas. -
@phuket2 I mentioned that I had seen something like this before... And I remember now that I had attempted to do it a long while back. Maybe a year ago when I was first learning some UI things. But I didn't know what I was doing. Some stuff sort of worked, but I ran into problems because I was trying to stick a webview in the tableviewcell. It wasn't working nice and I just thought it wasn't ever going to work.
I've learned a few things since. Now I've attempted to do again what I did before. The fix is really this little objc bit that gives the webview an opaque background - that way the selections in the tableview still work.
If there is a difference here from what @jonb is doing, I don't know what it is. I'm limited with my knowledge of how classes work (in the deep bowels of classes) so I don't know what's going on.
Anyway, try this out....
import ui from objc_util import * class MyTableViewDataSource (object): def __init__(self, data): self.data = data def tableview_number_of_sections(self, tableview): return 1 def tableview_number_of_rows(self, tableview, section): return len(self.data) def tableview_cell_for_row(self, tableview, section, row): cell = ui.TableViewCell() wv = ui.WebView(frame=cell.content_view.bounds, flex='WH') wv.touch_enabled = False #necessary for tableview scrolling to work, unfortunate side effect is that you can't do any touch of content in the webview. Tried disabling scolling with objc but the result wasn't good either. wv.scales_page_to_fit = False wv.load_html(html) #webview needs to have an opaque background for selection colors to work... do in objc wv_obj = ObjCInstance(wv) wv_obj.webView().setBackgroundColor_(ObjCClass('UIColor').clearColor()) wv_obj.webView().setOpaque_(False) cell.content_view.add_subview(wv) return cell def tableview_can_delete(self, tableview, section, row): return False def tableview_can_move(self, tableview, section, row): return False def tableview_did_select(self, tableview, section, row): t.name = self.data[row]['name'] if __name__ == '__main__': from faker import Faker fake = Faker() style = '<style>p {font: arial 10pt; color:#888888; margin:0px} a {color:#888888; text-decoration:none} h4 {margin:0px; background-color:#dd7575; color:white; border-radius:5px; padding: 0 5}</style>' contact_list = [] for x in range(200): name, email, phone, address = fake.name(), fake.email(), fake.phone_number(), fake.address() html = style + '<h4 style="margin:0px">{}</h4><p>{}</p><p>{}</p><p>{}</p>'.format(name, email, phone, address) contact_list.append({'html':html, 'name':name}) t=ui.TableView() t.frame=(0,0,400,480) t.data_source=MyTableViewDataSource(contact_list) t.delegate = t.data_source t.row_height = 100 t.present('sheet')
-
@cook Your example caused me to write fake_format.py to enable a usage like:
from fake_format import fake_fmt html = fake_fmt('<h4 style="margin:0px">{name}</h4><p>{email}</p>' '<p>{phone_number}</p><p>{address}</p>')
-
@ccc
That's cool! I don't remember how I saw this faker module- maybe just looking at the pythonista docs as it's listed as a third party module. Sure is useful though!