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.
iPad Orientation Control help
-
from objc_util import * @on_main_thread def rotate(to_orientation): orientations={ 'Portrait' : 1, 'PortraitUpsideDown' : 2, 'LandscapeLeft' : 3, 'LandscapeRight' : 4 } device.setOrientation_(orientations[to_orientation]) return #def toggle_orientation_lock(): #can’t figure out how to implement this #need to find a way to remove supported orientations #that aren’t the current orientation device=ObjCClass('UIDevice').currentDevice()
This is all I could get to so far. As you can see in my comments, I haven’t been able to find a way to remove/change the supported orientations in a UIViewController object.
-
i found an answernat Stackoverflow but im sure this wont fix it.
found alot of people working around hisbin XCode but thats not an option for me..
But i think This might be where we start to find the answer..
-
Are you trying to prevent rotation?
Or force rotation when the device rotates, even when the rotation lock is set?
Or detect changes to rotation or split layout, to force a re-layout of your view?
-
@JonB said:
Are you trying to prevent rotation?
Or force rotation when the device rotates, even when the rotation lock is set?
Or detect changes to rotation or split layout, to force a re-layout of your view?
i would prefer to prevent any rotation andkeep landscape.. but i, for the most part, understand why i cannot just set
orientations
inpresent
so im assuming the best i can do without XCode isto detect a rotation starting and intercepy a force rotation to landscape..? -
i found this but what prints out from
inspect.getmembers
is not the same as on the developers website..Edit:
now that i look it over again it makes since y it didnt match lol.. but i should still be able to use
traitcollectiondidchange:
?or am i over thinking this and just use
ui.View.layout()
orscene.Scene.did_change_size()
-
I think what you want is this one
You would need to make a custom view controller class that implements this. Then present that view controller full screen and add your view as a subview... I think @cvp might have examples of how to present custom view controllers?
-
-
@JonB Seriously, the doc says it is an instance property but also says "The system calls this method when presenting the view controller full screen".
Could it be possible to swizzle it? -
Tried with this NY monkeypatching instead of swizzle because it is an instance method, not a class method. The def is called but no orientation change, and even no full screen.
Of course, it is not the main view controller. Sure, help will be needed.from objc_util import * import ui def preferredInterfaceOrientationForPresentation(_self):#, _sel): self = ObjCInstance(_self) # UIViewController print('preferredInterfaceOrientationForPresentation:',self) return 3 # UIInterfaceOrientationLandscapeLeft @on_main_thread def main(): UIViewController = ObjCClass('UIViewController') vc = UIViewController.alloc().init() # monkeypatch of UIViewController class instance method UIViewController.preferredInterfaceOrientationForPresentation = preferredInterfaceOrientationForPresentation(vc) vc.setModalPresentationStyle_(2) # full screen l = ui.Label() l.frame = (10,10,100,32) l.text = 'label' vc.view().addSubview_(ObjCInstance(l)) rootvc = UIApplication.sharedApplication().keyWindow().rootViewController() rootvc.presentViewController_animated_completion_(vc, True, None) if __name__ == '__main__': main()
-
@cvp Got this to work by create_objc_class on the view controller to override the method, and by letting the system choose the modal presentation style (setting to 0)
changed your method to:
def preferredInterfaceOrientationForPresentation(_self,_cmd): return 3
And changed creation of vc and set modal to:
vc=create_objc_class('vc',UIViewController,methods=[preferredInterfaceOrientationForPresentation]).alloc().init() vc.setModalPresentationStyle_(0)
edited
-
-
I think he meant to have an alloc().init() in there somewhere. You need an instance
-
Yea add an .alloc().init(). The anti-spam bot won’t let me add it on there. Sorry for the confusion
-
@mcriley821 yes, I already did it
-
@mcriley821 I tried this script. I'll let @stephen go on 😇
Thanks for your help. I'm happy we have now a new ObjectiveC guru because I only use it with a lot of tries.
Put in gist because refused as spam??? -
@jonb @mcriley821 I don't understand why my monkey patching was not good because the method was also called, proved by the print.
-
@cvp I’m no guru by any means lmao. It takes many crashes for me before I get something working. I’m steadily learning though.
My only guess on why monkey-patching didn’t work is because we already alloced and inited vc as a regular UIViewController and didn’t create another instance after overwriting the class method. But honestly I’ve never done monkey-patching so I’m not positive what I’m talking about
-
@mcriley821 But I was overriding an instance method, not a class method. And it worked because the def was called.
-
@mcriley821 I just tested with my old code and modal style 0, and it works in the same way as your code with the new objc class. The only difference is that the _cmd 2nd parameter is not accepted.
-
@cvp if you do
print(vc.preferredInterfaceOrientationForPresentation())
you still get 1, but if you
print(UIViewController.preferredInterfaceOrientationForPresentation())
You get 3.
Your monkey-patch overwrites the UIViewController object. But if you dovc.preferredInterfaceOrientationForPresentation=preferredInterfaceOrientationForPresentation(vc)
The print has an error 'int object is not callable'.
Maybe it thinks the method is an attribute, and instead of overwriting the function it just makes an attribute