आईओएस 6 में पोर्ट्रेट ओरिएंटेशन के लिए एक UIViewController मजबूर करने के लिए कैसे


85

जैसा कि ShouldAutorotateToInterfaceOrientationआईओएस 6 में पदावनत किया गया है और मैंने इस्तेमाल किया है कि किसी विशेष दृश्य को केवल चित्र के लिए मजबूर किया जाए , आईओएस 6 में ऐसा करने का सही तरीका क्या है? यह केवल मेरे ऐप के एक क्षेत्र के लिए है, अन्य सभी दृश्य घूम सकते हैं।

जवाबों:


117

यदि आप चाहते हैं कि हमारे सभी नेविगेशन नियंत्रक शीर्ष दृश्य नियंत्रक का सम्मान करें तो आप एक श्रेणी का उपयोग कर सकते हैं ताकि आपको कक्षा के नामों का एक गुच्छा बदलने की ज़रूरत न पड़े।

@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

जैसा कि कुछ टिप्पणियां इंगित करती हैं, यह समस्या का त्वरित समाधान है। एक बेहतर समाधान है सबक्लास यूएनेविसीकंट्रोलर और इन तरीकों को वहां रखना। एक उपवर्ग भी 6 और 7 का समर्थन करने में मदद करता है।


3
मैं इस काम की पुष्टि कर सकता हूं। यदि आप चाहें तो "self.topViewController" के साथ "[self.viewControllers lastObject]" को भी बदल सकते हैं।
वेन लियू

3
यदि आप इस UINavigationController श्रेणी की तुलना में UITabBarController का उपयोग कर रहे हैं तो कोई मदद नहीं है। आपको इसके बजाय UITabBarController पर श्रेणी बनाना चाहिए ...
बोरुत टोमाज़िन

46
इस समाधान के साथ समस्या यह है कि यह तब काम नहीं करता है जब आप उस नियंत्रक को पॉप करते हैं जो आपके परिदृश्य में था और आपका नया शीर्ष नियंत्रक केवल चित्र (या इसके विपरीत) का समर्थन करता है, उन कॉलबैक को इस मामले में नहीं बुलाया जाता है और मुझे अभी तक कोई रास्ता नहीं मिला है कि कैसे सही अभिविन्यास में नए शीर्ष नियंत्रक को बाध्य करें। कोई विचार?
लोप

4
मैंने UINavigationController को उपवर्गित किया और इसे window.rootController के रूप में सेट किया। मैंने सभी 3 विधियों को लागू किया, यह बहुत अच्छा काम करता है जब आप डिवाइस के रोटेशन को बदलते हैं, समस्या यह है कि उन तरीकों (और रोटेशन से संबंधित कुछ भी नहीं) को कॉल किया जाता है जब आप पॉप व्यू कंट्रोलर
लोप

4
अगर मैं लैंडस्केप व्यू कंट्रोलर से पुश या पॉप कर रहा हूं तो यह बल UIViewController लैंडस्केप में बदल जाता है। हालाँकि अगर मैं चित्र में घूमता हूँ तो यह ठीक काम करता है और यह कभी भी परिदृश्य में नहीं बदलेगा। परिदृश्य से धक्का या पॉप करते समय एकमात्र समस्या। कृपया मदद करें
तारिक

63

IOS6 के लिए सबसे अच्छा तरीका विशेष रूप से Ray Wenderlich टीम - http://www.raywenderlich.com/ द्वारा "iOS6 By Tutorials" में नोट किया गया है और UINavigationControllerअधिकांश मामलों के लिए उपवर्ग से बेहतर है ।

मैं एक स्टोरीबोर्ड के साथ iOS6 का उपयोग कर रहा हूं जिसमें UINavigationControllerप्रारंभिक दृश्य नियंत्रक के रूप में एक सेट शामिल है ।

//AppDelegate.m - दुर्भाग्य से यह विधि पूर्व iOS6 उपलब्ध नहीं है

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m - जो भी झुकाव आप प्रत्येक के लिए समर्थन करना चाहते हैं वापस लौटाएं UIViewController

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

1
आईओएस 6 के लिए यह सबसे अच्छा समाधान है
होमम

2
@Phil, iOS 6 के लिए इसका काम ठीक है। लेकिन कुछ मामलों में, जैसे अगर आप लैंडस्केप से पोर्ट्रेट तक जाते हैं तो यह काम नहीं करता है। किसी भी विचार क्यों होता है?
कीर्ति निकम

1
बहुत उपयोगी समाधान। मेरे लिए, सबसे अच्छा।
ऑस्कर कैटेलन

1
IOS 7 बीटा 6 पर काम करना। मेरे मामले में परिदृश्य से पोर्ट्रेट तक काम करता है।
मार्टिन बर्गर 12

मैं iOS 6 में हूँ, लेकिन यह काम नहीं करता है। यह "UIViewController * प्रस्तुत ViewController" लाइन पर टूट जाता है।
मार्सेल मारिनो

39

यह उत्तर ओपी की पोस्ट की टिप्पणियों में पूछे गए प्रश्नों से संबंधित है:

किसी दिए गए ओरिएंटेशन में दिखाई देने के लिए एक दृश्य को देखने के लिए मजबूर करना

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
    UIViewController *c = [[UIViewController alloc]init];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

यह एक हैक की एक बिट है, लेकिन यह UIViewControllerपिछले पोर्ट कंट्रोलर के लैंडस्केप होने पर भी पोर्ट्रेट में प्रस्तुत करने के लिए मजबूर करता है

IOS7 के लिए अद्यतन

ऊपर दिए गए तरीके अब समाप्त हो गए हैं, इसलिए iOS 7 के लिए निम्नलिखित का उपयोग करें:

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
     UIViewController *c = [[UIViewController alloc]init];
     [c.view setBackgroundColor:[UIColor redColor]];
     [self.navigationController presentViewController:c animated:NO completion:^{
            [self.navigationController dismissViewControllerAnimated:YES completion:^{
            }];
     }];
}

दिलचस्प है, लेखन के समय, या तो वर्तमान या खारिज करना एनिमेटेड होना चाहिए। यदि नहीं हैं, तो आपको एक सफेद स्क्रीन मिलेगी। पता नहीं क्यों यह काम करता है, लेकिन यह करता है! दृश्य प्रभाव अलग है जिसके आधार पर एनिमेटेड है।


धन्यवाद, मैं इसे एक कोशिश दे दूँगा जब मुझे खाली समय के कुछ मिनट मिलेंगे
लोप

@ रोहनअगरवाल यह विज्ञापन के रूप में काम करता है, मैं यहाँ इसका उपयोग कर रहा हूँ। लेकिन आपको स्वीकृत उत्तर का कोड भी लागू करना होगा, या यह काम नहीं करेगा।
डेनिस मुंसी

2
क्या किसी ने सोचा है कि एक ही समय में सही रोटेशन एनीमेशन के साथ यह काम कैसे किया जाए? यह एनीमेशन के बिना चित्र से परिदृश्य में स्विच करने के लिए देखने के लिए थोड़ा परेशान है। यह काम करता है, बस इसे थोड़ा बेहतर बनाने की उम्मीद है।
डेनिस मुंसी

@ क्रेग वाटकिंसन स्टोरीबोर्ड में काम नहीं कर रहा है। और presentModalViewController और बर्खास्तModalViewControllerAnimated अगर वर्तमान iVirecontroller का उपयोग कर iam पदावनत है तो यह काम नहीं करेगा। कृपया मेरी मदद करें
कल्पेश

1
Ios8 के लिए बर्खास्तगी दृश्य नियंत्रक केवल दुर्घटनाग्रस्त हो गया। मैंने पाया कि कॉलिंग [NWSAppDelegate sharedInstance] .window.rootViewController = nil; [NWSAppDelegate sharedInstance] .window.rootViewController = पिछलेRootController अच्छा काम करता है।
एलेक्सी

36

इसलिए मैं एक ही समस्या में भाग गया जब चित्र केवल मोडल दृश्य प्रदर्शित कर रहा था। आम तौर पर, मैं एक बनाता हूँ UINavigationController, के viewControllerरूप में सेट rootViewController, तो UINavigationControllerएक modal दृश्य के रूप में प्रदर्शित करते हैं। लेकिन आईओएस 6 के साथ, viewControllerअब अपने समर्थित इंटरफ़ेस ओरिएंटेशन के लिए नेविगेशनकंट्रोलर से पूछेगा (जो कि डिफ़ॉल्ट रूप से, अब सभी iPad के लिए है और iPhone के लिए उल्टा है)।

समाधान : मुझे UINavigationControllerऑटोरोटेशन विधियों को उप-वर्ग और ओवरराइड करना था। लंगड़ा की तरह।

- (BOOL)shouldAutorotate {
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

1
मेरा काम नहीं करता है। मेरे पास यह कोड वैश्विक था जिसमें सभी
झुकावों के लिए बसे हुए थे

2
supportInterfaceOrientations को एक NSUInteger को वापस करना चाहिए, न कि BOOL को। डेवलपर
।apple.com

इसके लिए काम किया, मेरे लिए इसकी
tabbarcontroller

एफडब्ल्यूआईडब्ल्यू, मुझे इस मार्ग पर भी जाना था ... और कुछ नहीं काम किया। धन्यवाद।
स्टीव एन

15

आईओएस 5

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

आईओएस 6

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations{

    //    UIInterfaceOrientationMaskLandscape;
    //    24
    //
    //    UIInterfaceOrientationMaskLandscapeLeft;
    //    16
    //
    //    UIInterfaceOrientationMaskLandscapeRight;
    //    8
    //
    //    UIInterfaceOrientationMaskPortrait;
    //    2

    //    return UIInterfaceOrientationMaskPortrait; 
    //    or
          return 2;
}

अति उत्कृष्ट! इस धागे के शीर्ष पर अधिकतम होने की आवश्यकता है। क्योंकि यह समस्या को हल करने का सबसे सरल तरीका है
एलेक्स

@ रोशन जलगांवकर इनोस 6 में यह मेरे लिए काम नहीं करता है, मुझे नीचे दिए गए होम बटन के साथ केवल पोर्ट्रेट की जरूरत है कि मैं यह कैसे सेट कर सकता हूं ....
कार्तिक

@ कार्तिक आपको काम करने के लिए अपने ऐप के लक्ष्य में समर्थित रोटेशन को सक्षम करना होगा।
अलेजांद्रो इवान

@ एलेजांद्रोइवान k thnx
कार्तिक

10

मैं @aprato के उत्तर से असहमत हूं, क्योंकि UIViewController रोटेशन के तरीके स्वयं श्रेणियों में घोषित किए गए हैं, इस प्रकार अपरिभाषित व्यवहार के परिणामस्वरूप यदि आप किसी अन्य श्रेणी में ओवरराइड करते हैं। एक UINavigationController (या UITabBarController) उपवर्ग में उन्हें ओवरराइड करने के लिए सुरक्षित

इसके अलावा, यह परिदृश्य को कवर नहीं करता है जहां आप लैंडस्केप दृश्य से केवल वीसी या इसके विपरीत में धक्का / वर्तमान / पॉप करते हैं। इस कठिन मुद्दे को हल करने के लिए (कभी भी Apple द्वारा संबोधित नहीं), आपको चाहिए:

IOS <= 4 और iOS> = 6 में:

UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];

IOS 5 में:

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];

ये वास्तव में UIKit को आपके सभी कंधों का पुनर्मूल्यांकन करने के लिए बाध्य करेंगे, समर्थितInterfaceOrientations, आदि।


2
IOS वर्जन की परवाह किए बिना इनमें से पहला मेरे लिए क्रैश है। बर्खास्तगी को वर्तमान समाप्त होने से पहले नहीं बुलाया जाना चाहिए।
आर्सेनियस

@arsenius क्या आप यह बता सकते हैं कि आप इसका उपयोग कैसे कर रहे हैं? जब तक यह एनिमेटेड नहीं होता है, तब तक यह समस्या आपके पास नहीं होनी चाहिए
राफेल नोब्रे

मैंने दूसरा स्निपेट व्यूडिडऐपियर में भी डाल दिया है और यह iOS 6 पर मेरी स्थिति में मदद करने के लिए कुछ भी नहीं करता है। प्रश्न यहां है: stackoverflow.com/questions/15654339/…
arsenius

क्षमा करें, यहां एक अंतिम टिप्पणी। देखने के लिए iOS 5 कोड को स्थानांतरित करने से डीडीएपियर इस आउटपुट के साथ कुछ अनंत लूप बनाता है: - [UIApplication startIgnoringInteractionEvents] अतिप्रवाह। की उपेक्षा।
आर्सेनियस

3

मेरे पास https://stackoverflow.com/a/13982508/2516436 और https://stackoverflow.com/a/17578272/2516436 को मिलाने का एक बहुत अच्छा तरीका है

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;


    if(self.window.rootViewController){
        UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
        orientations = [presentedViewController supportedInterfaceOrientations];
    }

    return orientations;
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController* tabBarController = (UITabBarController*)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

और जो भी झुकाव आप प्रत्येक UIViewController के लिए समर्थन करना चाहते हैं उसे वापस करें

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

1

मेरे पास UISplitViewController और UISegmentedController का उपयोग करते हुए एक अपेक्षाकृत जटिल सार्वभौमिक ऐप है, और कुछ विचार हैं जो लैंडस्केप का उपयोग करके प्रस्तुत किए जाने चाहिए presentViewController । ऊपर बताए गए तरीकों का उपयोग करके, मैं iPhone ios 5 और 6 को स्वीकार्य रूप से काम करने में सक्षम था, लेकिन किसी कारण से iPad ने बस लैंडस्केप के रूप में पेश करने से इनकार कर दिया। अंत में, मुझे एक सरल समाधान मिला (पढ़ने और परीक्षण और त्रुटि के घंटों के बाद कार्यान्वित) जो दोनों उपकरणों और ios 5 और 6 के लिए काम करता है।

चरण 1) नियंत्रक पर, आवश्यक अभिविन्यास निर्दिष्ट करें (अधिक या कम जैसा कि ऊपर उल्लेख किया गया है)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    NSInteger mask = UIInterfaceOrientationMaskLandscape;
    return mask;

}

चरण 2) एक सरल UINavigationController उपवर्ग बनाएं और निम्नलिखित विधियों को लागू करें

-(BOOL)shouldAutorotate {
        return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskLandscape;
}

चरण 3) अपना दृष्टिकोण प्रस्तुत करें

vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];

आशा है कि यह किसी के लिए उपयोगी है।


1

यहां सुस्त नहीं होना चाहिए, लेकिन क्या आप अपने उपवर्ग को साझा करने के लिए इतने दयालु होंगे? धन्यवाद।

संपादित करें: ठीक है, मैं अंत में यह किया था, उपवर्ग आसान करने के लिए मर गया था। मैं बस की घोषणा करने के लिए किया था navigationControllerमें AppDelegateके रूप में UINavigationControllerSubclassके बजाय डिफ़ॉल्ट UINavigationController, तो साथ अपने उपवर्ग संशोधित:

- (BOOL)shouldAutorotate {
    return _shouldRotate;
}

इसलिए मैं कोई भी दृश्य सेट कर सकता हूं जिसे मैं कॉल करके या घुमाकर नहीं करना चाहता viewDidLoad

_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]

आशा है कि यह ट्विक दूसरों की भी मदद करेगा, आपके टिप के लिए धन्यवाद!

टिप: का उपयोग करें

- (NSUInteger)supportedInterfaceOrientations

आपके दृश्य नियंत्रकों में, इसलिए आप परिदृश्य या इसके विपरीत में एक चित्र वांछित दृश्य होने से समाप्त नहीं होते हैं।


0

मैंने खुद इसका परीक्षण नहीं किया, लेकिन प्रलेखन में कहा गया है कि अब आप उन तरीकों को ओवरराइड कर सकते हैं: supportedInterfaceOrientationsऔर preferredInterfaceOrientationForPresentation

आप संभवतः उन तरीकों से केवल जो अभिविन्यास चाहते हैं उसे प्राप्त करना चाहते हैं जो आप प्राप्त कर सकते हैं।


0

उप-वर्ग या श्रेणियों का उपयोग करके उत्तर UINavigationController और UITabBarController कक्षाओं में कुलपतियों की अनुमति देता है। लैंडस्केप टैब बार कंट्रोलर से पोर्ट्रेट-केवल मोडल लॉन्च करना विफल रहा। यदि आपको ऐसा करने की आवश्यकता है, तो एक गैर-एनिमेटेड मोडल दृश्य को प्रदर्शित करने और छिपाने की चाल का उपयोग करें, लेकिन इसे व्यूडाईपियर विधि में करें । यह मेरे लिए व्यूडलड या viewWillAppear में काम नहीं किया।

इसके अलावा, उपरोक्त समाधान ठीक काम करते हैं।


0

Monotouch के लिए आप इसे इस तरह से कर सकते हैं:

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
    {
    return UIInterfaceOrientationMask.LandscapeRight;
}

public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
    {
    return UIInterfaceOrientation.LandscapeRight;
}

0

मैं कई उत्तर देखता हूं, लेकिन अभिविन्यास के बारे में विशेष विचार और उत्तर नहीं मिलता है, लेकिन लिंक को अच्छी तरह से देखें उन्मुखीकरण को समझें और ios6 के लिए बलपूर्वक रोटेशन को हटा दें।

http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/

मुझे लगता है कि यह पूरी मदद है।


-1

बस Project.plist पर जाएं और फिर सपोर्टेड इंटरफेस ओरिएंटेशन जोड़ें और उसके बाद केवल पोर्ट्रेट (नीचे होम बटन) और पोर्ट्रेट (टॉप होम बटन) जोड़ें।

आप अपनी परियोजना की आवश्यकता के अनुसार वहाँ अभिविन्यास जोड़ या हटा सकते हैं।

धन्यवाद


1
पूरे आवेदन के लिए विशेष रूप से देखने के नियंत्रक के बारे में।
मुहम्मद रिज़वान

-2

1) अपनी परियोजना सेटिंग्स और info.plist की जाँच करें और सुनिश्चित करें कि केवल उन्हीं झुकावों का चयन करें जो आप चाहते हैं।

2) अपने सर्वोच्च दृश्य नियंत्रक (नेविगेशन कंट्रोलर / टैब्बर कंट्रोलर) में निम्नलिखित विधियाँ जोड़ें

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

3) अपने ऐप प्रतिनिधि को निम्नलिखित तरीके जोड़ें

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait;

}

-3

इसे उन सभी की .m फ़ाइल में रखें जिन्हें ViewControllerआप घुमाना नहीं चाहते:

- (NSUInteger)supportedInterfaceOrientations
{
    //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
    return UIInterfaceOrientationMaskPortrait;
}

अधिक जानकारी के लिए यहाँ देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.