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.
UIPageControl (Paging scrollview with page indicators)
-
@Samer, couple more simplification/maintainability comments, which do not affect functionality.
Forgiveness, not permission
For the delegate calling, the pythonic way is to rely a bit more on the exception mechanism:
try: callback = self.delegate.page_changed except AttributeError: return if self.pageControl.currentPage() is not self._prev_page: callback(self, self.pageControl.currentPage()) self._prev_page = self.pageControl.currentPage()
This is not in any way inefficient (hasattr relies on catching the same exception), is much more focused on the "good case", and avoids a fair bit of nesting.
Oh, I lied, there is a functionality change there: recommend adding
self
as the first parameter to the callback. This enables using two or more instances of the component, all tracked with the same delegate, which then gets the information which component was triggered. This is in line how Button actions have a sender, TextView delegates get the textview etc.Minimize attributes
In
add_subview
, we add apNum
attribute to the pages. This is unnecessary, as we can change the layout method to simply use the order of subviews:for i, v in enumerate(self.scrollView.subviews): v.x = i * self.bounds.width
This even supports the future option of reorganising the views, without needing to fix the pNum.
Let iOS do the resizing wherever possible
If in
add_subview
we set the page size and flex:def add_subview(self, page): page.frame = self.scrollView.bounds page.flex = 'WH' ...
... we do not need to set v.width and v.height explicitly in the layout loop, so it reduces to the simple version above. I imagine native iOS resizing is slightly more efficient as well.
-
-
I took a few days to think about this bug/feature. I implemented a workaround for it which at the very least hides the problem. I don’t like it, but it works. If anyone has a better solution then overriding the present method, I would be happy to replace my current solution with it.
-
im sorry i never posted.. you dont need to override present. in your
__init__
just addy=20
to yourscrollView
creation.class PageControl(ui.View): def __init__(self, **kwargs): self.scrollView = ui.ScrollView( delegate=self, paging_enabled=True, shows_horizontal_scroll_indicator=False, bounces=False, frame=self.bounds, flex='WH', y=20 # <-- here )
just one line , 4 characters 🤓
-
i only overrided present cuz i tent to make stuff complicated when im tired lol i apologize
-
@stephen There are two problems I encountered with that solution, the first is that when
hide_title_bar=True
The whole view is shifted down 20px. The second is that on my iPad it still jumps down a few pixels, yet it doesn’t on my iPhone. I wish the solution was that simple however it is unfortunately not. -
@Samer Sorry for the late reply. been working on this one all night.
I still dont have the ideal fix for this.. (meaning without overriding present) but am u got three choices..
ONE:
Hard setting scrollView() like before..
self.scrollView = ui.ScrollView( delegate=self, paging_enabled=True, shows_horizontal_scroll_indicator=False, bounces=False, frame=self.bounds, flex='WH', y=20 # ⥢⬅ here )
TWO:
Hard set inside SetPage..
def set_page(self, page_number): if page_number < self.pageControl.numberOfPages() and page_number > -1: x = page_number * self.scrollView.width self.scrollView.content_offset = (x, -20) # ⥢⬅ here else: raise ValueError("Invalid Page Number. page_number is zero indexing.")
THREE:
Your favorit override..
added an instance variable to it though..class PageControl(ui.View): def __init__(self, **kwargs): self.titleBarAdjustment=0 # ⥢⬅ here ... #with this guy.. def present(self, **kwargs): # evaluate input before presenting if kwargs['hide_title_bar']: self.scrollView.y=20 #if hide_title_bar then adjust scrollView super(PageControl, self).present(**kwargs) # Continue..
the second option needs to know if the bar is present otherwise it just has a revers effect to original image issue.. (jumps up)
im still looking for a beter solution for this. the objc methods were not working last night and im sure it was writers error. but im the mean time at least two of these will hold by maybe?
as for your other issues..
Depending on your phone and tabelets they could be explained.
i suspect that it has todo with Retina scaling and resolution. i have an iPhone 6s and iPad Air 2 and they both have a 2x1 Retina Display so i dont get this issue but id imagine if u has a 2x1 phone and 3x1 ipad it would creat this. all you really need to do if thats the case is check device at runtime and setup Layout accordingly. ui/scene, atleast for 2x1, should auto compensate for this but pil doesnt. just for future info lol.. but by using ui.from_data(data, scale) is where u set scaling for retina convertion. this could help if your dispay happends to be a factor. if i find anything ill let you know!