Forum Archive

Any User Interface requests?

TutorialDoctor

I am taking requests for user interfaces. I am using this as an opportunity to practice creating user interfaces according to specific standards.

If you need an interface for a Pythonista project, I would like to make an attempt at it. I am mainly using the UI module.

So far here are the projects I have made:
https://github.com/TutorialDoctor/Pythonista-Projects

If I decide to work on a request, I will up vote it.

Phuket2

@TutorialDoctor , in my opinion the number one ui element that could be used in Pythonista that is missing is:
http://nshipster.com/uisplitviewcontroller/
When it all comes down to it, this is the view that is used most often on iOS native apps. With the addition of some tool bars here and there. I don't need it, but I love love to have a ui element like this that has been really hammered and could be relied upon. Would be nice if implemented as a custom view so could add it to other views. Also a nice abstraction to provide the data for the 'master' and 'detail' views, like the section/data dict concept used in dialogs.form_dialog.

Just, if you are asking 😁😈

TutorialDoctor

@Phuket2 I do see that UiSplitViewController is available via Objective C. Full list is available here:
https://gist.github.com/steventroughtonsmith/b6909d310f0b383ade8b

I have these gists in my site-packages folder, so they can be imported. I guess I have to dig into learning Objective C eh?

JonB

Here is a simple split view type controller class, implemented using ui rather than objc. You set the .mainview and .detailview attributes to your predefined views, it autosizes them, then dragging inside the view right or left shows/hides the detail menu. Also can be linked to a button, as shown in the example, or in general user can provide delegates that get called when detail is toggled. Rotation works as you'd expect.

Currently won't work quite right in panel, since panel hijacks gestures on custom views. I am remembering that I had to implement this with a scrollview as the touch interface, but this might get the ideas flowing anyway. Also, I realize this may need a close button on iPhone, or rotate to landscape,to dismiss the view, since tableviews steal the swipe gesture.

Phuket2

@JonB , nice and exiting. I got the script, the sliding is nice. I will try to make a later today. Thanks for sharing

Phuket2

@TutorialDoctor , I still struggle with Python, so no reason for me to start looking into objective c 😬

But I had seen it was available in oc. I have no idea of the reach of the objc_utils packagage in Pythonista. But would be super cool if some of these elements not included natively by omz could be somehow loaded into the existing framework, meaning as a ui.View. Maybe @omz will just include it in the next beta 😱🎉👍

JonB

I made an update which uses a scrollview instead of touch.
This plays nicer with other ui components and panel present style...now you can swipe over tableviews, textviews, etc and it works.

Phuket2

@JonB , there is something wrong with the update. If you show in a sheet, it's bouncing. No were near as good as the first version.

Phuket2

@JonB , another issue with the scroll view approach is the sliding on rows in a table. Eg, delete

JonB

tweaked again to fix bounce, or at least the overscroll in one direction (dragging left when detail is hidden, or right when shown).

JonB

ack, yes tables are broken in this approach.
i will experiment with a scrollview behind the other views, rather than a scrollview container.

Webmaster4o

@Phuket2 said:

@TutorialDoctor , I still struggle with Python, so no reason for me to start looking into objective c 😬

The main reason why I'm reluctant to learn Objective C is because I feel like it will be replaced by Swift.

Phuket2

@JonB , thanks. But it really doesn't work. What about not using the scroll view, using version 1 with a margin in between the 2 view. Well the margin/border also being a uiView that the width can also be defined in the params. Also access to the margin/drag view via method call or property to make it easier to load a custom pic etc to use.
If you did something like that, it would be very nice to keep the detail and main views still responsive to dragging. Will be times when a control is not taking up the whole view. I am sure I have seen this behaviour in apps before

@JonB, I don't just assume you will or want to make these changes. But If you don't mind working on it, I don't mind testing it and giving feed back. I don't want to dig into your code though. I mean I am reading it, but I am not good enough to run with your code myself. I would love to have this view in a rock solid form if possible. I am also happy to try and make helpers for simplifying the detail and main views.

Anyway, I will leave it to you.

Just in case a few items:
**style = 'slide' ** , if style is passed None, it still slides. If it's passed None, it would be great if the panes were just fixed. Ie touch events are negated

Layout , I noticed layout is not being called in your code. Maybe it's fine. I haven't had a chance to test that far. But maybe it's all being handled with flex

opening state, I know this can be changed with toggle_detail. But it would be nice to have a param for the opening state.

**menubar and status/footer views ** would be nice if there were properties to add a view for a menu_bar and/or a footer_bar (ui.Views). And the split view still takes care of the geometry

Food for thought 🎉😳😝
I am not Su

Phuket2

@Webmaster4o , I really have not read the press, rather just skimmed it. But from what I can see, it's not if swift will replace it, it's just when will it replace it. I seen a few months ago, swift lept way up there on the charts of language usage. As I say I have skimmed the articles, but I think there is no doubt about it, swift will replace objective c. But please note, I say , I think. But realistically, I think you will not find them too far apart. I think the hardest thing is getting your head around the apple framework more than the language in this case. I am guessing the objective c guys will not have such a hard time to make the transition.

Phuket2

working with version 1 touch events
@JonB, I wrote a class for both main view and detail view. All appears fine, expect for main is not receiving any touch began events. I put in a print statement.
But I made sure the print touch_enabled is set to True as well I also bring the view to the front.
Even with your main code with the simplest of class definitions like the one below, if I set your mainview var to TheMainView, touch stops working. I have tried all sorts of combinations, I can't work it out. It could be a bug, or something so simple I am doing wrong.
Do you have any ideas. I have looked through your code, I can't see any reason for it.

class TheMainView(ui.View):
    def __init__(self, **kwargs):
        ui.View.__init__(self, **kwargs)
        self.touch_enabled = True
        self.bring_to_front()
JonB

I guess I should have mentioned that this approach will not work touch enabled views. How would the system know which view you meant your gesture for? This is the same reason swiping over a tableview doesn't work. I suppose one approach would be to look for touch handlers within mainview, and then if the splitview decides the touch is not a swipe, it would call the mainview touch class. So you would be allowed to implement maybe touch_moved for vertical swipes, and touch_ended, touch_began would be delayed.

There is a splitview method show_detail and hide_detail and toggle_detail which let you hook this into other ui elements, like the menu button, or custom gestures within your main/detail view. So if we are willing to do without swipe to dismiss and instead have a close button, or implement within the custom views, this becomes very straightforward.

Alternatively, if we wish to dedicate a small area at the border or in the title bar for swiping, this could work. I updated the repo with an attempt at this approach. The gray color could be changed or not there at all. this implementation was a bit messy, but it shows the idea at least. I also gave you access to the mainview and detilview in the constructor, and the initial state.

The intention here was that one would write a separate NavigationView type class with optional top and bottom menu bars, which you would set as the splitview's mainview, and/or detailview. There it would make sense to implement a custom swipe action which could be hooked into the splitview. Alternatively, one could add this splitview as a subview to another view, for instance if you wanted the sliding container to only be a small portion of the view.

Note for changing the main or detail view, you simply set the attribute to point to the new View, and the SplitView class takes care or removing the old one, and adding the new as a subview, as well as (in the scrollview version) adding a splitview attribute to the main and detail views so you can more easily relate main and detail views ( i.e from the mainview you could write self.splitview.detailview to find the detailview).

TutorialDoctor

I also agree that the Apple framework is the harder thing to understand. I have been looking at the UIKit and Foundation framework references. Okay, so how do you use them?

I do however see similarities between how the Apple framework works and how Pythonista's own UI module work.

I wonder if there are analogous parts. Perhaps a class that extends the ui.View() module with Objective C controllers would do the trick. I would rather have it be authentic than try to fake it. If I do use Objective C (once I see how it works) I will try to make it as easy to understand and edit as possible.

If anyone has a solid solution to this one though, I will go ahead and use that.

Found a good source of information on how they work though

Tizzy

I tried to do a simple GET call using swift... and oh my it needed like 50 lines of code, nothing like our beautiful requests module in python. When I first saw it I though YES LOOKS LIKE PYTHON. Not the case.

I'm +1 for the split view. @jonB the behavior of the split view in your example has a slight oddity feel-wise. You can slide out from the left without paying attention to where you touch, but to slide it back you have to start EXACTLY on the grey vertical bar. Would it be possible to make it so that you can slide it back with a general purpose slide from the right? I feel like that would feel more natural.

Also, even if you select iPad mode, it seems to ignore it and just have the slide out panel. (iPhone 6s+)

JonB

The ipad/iphone mode was really intended to both be run on ipad, where you have the extra width, to see what it would look like on iPhone... Since things get resized for fullscreen, I suspect they would look the same. I don't actually have an iphone to test this out on though!

I agree I am not 100% happy with the behavior. One option which I think would work well would be a swipe on the title bar. I may try playing around with objc to see what can be done easily. The nice thing about the all ui module approach is that it will be easier to extend/modify for the average user, and is less likely to result in an ugly crash.

JonB

One approach which I recommend, is to start with a top level ui.View. Then, you use ObjCInstance(myview) to get the OBjC object. This makes it a little easier to present, since you can just use myview.present().

Note you don't actually have to use steven troughton's UIKit module or Foundation module, and in fact I would advise against it (since he is instantiation ObjCClasses of every possible class, most of which you don't need, plus not all of these are available on ios 8). Just use what you need.

In many cases it is easier to use the ui module version of things like buttons, etc, and using objccinstance if you need to add these to objc views, etc.

JonB

Ok, figured it out. I kept with the scrollview approach, but added a method which allows scrollviews/tableviews, etc to scroll inside the main scrollview. There was an objc method which allowed this. This lets tables use the delete row swipe.

(edit: Arg... so this works in sheet, but not in panel. back to the drawing board)

Phuket2

@JonB , I just tried the latest version. I am not sure we are seeing the same things or not. But on my ipad pro, I get like a slide, then like a snap to then a bounce type effect. Just running your example without any modifications whatsoever. What I see, I don't think a user would enjoy that interface. It's almost like you have to flick the screen rather than swipe it

Phuket2

@TutorialDoctor , did you pick a project to work on? Another idea I have had in the past is to make ui's based on iOS apps. I still think it should be done. Like, contacts, reminders, notes , system prefs etc... I am guessing generally these are the core interfaces. Hence my excitement for a slideview.

TutorialDoctor

@Phuket2 That is exactly what I have been thinking. If I can mimic the functionality of core IOS apps, then I should be able to do just about anything. The Text Editor UI I posted in the other thread was made to simulate the sort of split view concept. I had no former knowledge of the splitViewController at the time, but I am seeing it is pretty similar in structure to the way I tried to do the Text editor.

I am trying to see what is the real difference between that UI I made an a real splitViewController.

I think I am going to go ahead and take a crack at a splitViewController using only Python.

TutorialDoctor

I am finished with the splitViewController. I can't connect my iPad to the internet right now. I will upload it later.

Any more requests?

TutorialDoctor

Here is my splitViewController

It is based on my exploration of model view controllers

By definition I think I have finally understood what a View Controller is. A splitViewController isn't so complicated. It is just a view controller that controls two different view controllers, each of which have their own views.

A splitView controller doesn't necessarily have to bey laid out like we see in the Reminders or Mail app. It can even be split 3 ways or four ways.

RomSpy

Maybe it exists and I can't find it but I would like to see an example of a nav view that uses a .pyui file with buttons as the menu and changes between other .pyui files

TutorialDoctor

@RomSpy You may want to check out my navigation view tutorial here. I think that is what you are looking for?

RomSpy

I looked at that tutorial however the base menu is built using "ButtonItems" I was referring to one where the base menu was its own .pyui file. The answer is probably somewhere in there maybe I am just not fully understanding it.

TutorialDoctor

Ahh. Okay. I have done this before. You would simply:

  1. Create the .pyui file for the menu
  2. Add the that menu as a subview of the main screen like so:
main_view = ui.load_view("viewName")
menu_view = ui.load_view("menuViewName")
# If the view you want to load is in another directory named 'Views' you could do:
menu_view = ui.load_view("Views/menuViewName")

main_view.add_subview(menu_View)
main_view.present()

If you want me to make a sample of this, just upload a screenshot or drawing of how you want to look and I will make a demo version.

RomSpy

I used the example you referred to above to create a program that switches between the views using the ButtonItems the file I am trying to use for a menu instead looks like this http://www.jandlwebservices.com/screen.jpg

I can upload the .pyui file if that is easier.

TutorialDoctor

Okay. Cool. And you want these buttons to link to different .pyui files using a navigation view like in the tutorial correct?

I won't be near wifi much longer, but I will work on two different solutions and you can tell me which is more suitable.

RomSpy

Yes exactly! Thanks for the help!!

Phuket2

@TutorialDoctor , hey. Sorry for the lack of feedback. Lots of visitors at the moment. But I think we are talking about different things regards interfaces. Which is fine. I think you are focusing on a functional bare bones demo/tutorial of how to create ui's
My idea on the other hand is to create functional libs with hooks etc, so they they can be reused rather than from instructional perspective. It makes sense from your username 😎

I think both are valuable.

here is a gist example I was working on, look it's crappy, I am just not getting enough time to do anything in it at the moment. But it gives you an idea of what I mean. The intent is that it would give a iOS reminders style interface. Ultimately trying to hide the user interface detail and giving methods/properties for the appropriate data elements. As I say, this gist is just a start. I struggle structuring objects for reusabiliy. Doing things like this help me though. Even here, I am focusing on reminders. If I was good enough, I would write another layer above to facilitate doing all the standard iOS apps. More code reuse and style uniformity. Anyway, just to let you know my idea

TutorialDoctor

@Phuket2. Great start! Yes, the splitViewController I made was rather longwinded for clarity to those who have no idea how a splitViewController would be constructed. My aim for that project was to make it editable with hopes someone more savvy would take that and make a class from it for their needs.

I also agree that it should be more of a library or a wrapper around existing modules.

TutorialDoctor

@RomSpy Hopefully this is what you are requesting.

A menu with buttons pops up and you can push views into any view of your choice (in this case it is a view named main) by pressing the button.

The way I made it is that the name of the view has to be the same name as the title of the button. The function to do this was sorta simple.

def connect(sender):
    try:
        main.navigation_view.push_view(ui.load_view('Views/'+sender.title))
    except:
        None

Then you just make this the action for all buttons in the main view:

for item in main.subviews:
    item.action = connect

My views are stored in a folder called Views.

RomSpy

@TutorialDoctor yes that is exactly what I was looking for thank you!!!