IOS 8 में कंट्रोलर ओरिएंटेशन को कैसे मजबूर करें?


149

IOS 8 से पहले, हमने supportInterfaceOrientations और के साथ संयोजन में कोड का उपयोग किया shouldAutoRotate किसी विशेष उन्मुखीकरण के लिए एप्लिकेशन उन्मुखीकरण के लिए मजबूर करने प्रतिनिधि तरीकों। मैं प्रोग्राम स्निपेट के नीचे कोड का उपयोग करता था ताकि प्रोग्राम को वांछित अभिविन्यास में घुमाया जा सके। सबसे पहले, मैं स्टेटस बार ओरिएंटेशन बदल रहा हूं। और फिर बस प्रस्तुत करना और एक मोडल दृश्य को तुरंत खारिज करना वांछित अभिविन्यास के लिए दृश्य को घुमाता है।

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

लेकिन यह आईओएस 8 में विफल हो रहा है। इसके अलावा, मैंने स्टैक ओवरफ्लो में कुछ जवाब देखे हैं जहां लोगों ने सुझाव दिया कि हमें हमेशा आईओएस 8 से इस दृष्टिकोण से बचना चाहिए।

अधिक विशिष्ट होने के लिए, मेरा एप्लिकेशन एक सार्वभौमिक प्रकार का एप्लिकेशन है। कुल तीन नियंत्रक हैं।

  1. पहला नियंत्रक देखें - यह आईपैड में सभी अभिविन्यास और आईफोन में केवल पोर्ट्रेट (होम बटन डाउन) का समर्थन करना चाहिए।

  2. दूसरा दृश्य नियंत्रक - इसे सभी स्थितियों में केवल सही परिदृश्य का समर्थन करना चाहिए

  3. तीसरा दृश्य नियंत्रक - इसे सभी स्थितियों में केवल सही परिदृश्य का समर्थन करना चाहिए

हम पेज नेविगेशन के लिए नेविगेशन कंट्रोलर का उपयोग कर रहे हैं। पहले दृश्य नियंत्रक से, एक बटन क्लिक एक्शन पर, हम दूसरे को स्टैक पर धकेल रहे हैं। इसलिए, जब दूसरा दृश्य नियंत्रक आता है, तो डिवाइस अभिविन्यास के बावजूद, एप्लिकेशन को केवल परिदृश्य में लॉक करना चाहिए।

नीचे मेरा shouldAutorotateऔर supportedInterfaceOrientationsदूसरे और तीसरे दृश्य नियंत्रक के तरीके हैं।

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

आईओएस के लिए विशेष रूप से उन्मुखीकरण में एक दृश्य नियंत्रक को लॉक करने के लिए इस या किसी भी बेहतर तरीके से कोई समाधान नहीं है। कृपया मदद करें !!


प्रस्तुत वीसी में आपके द्वारा बताए गए तरीकों को लागू करना आम तौर पर काम करना चाहिए (कम से कम आईओएस 8 में मेरा अनुभव)। शायद आपका विशिष्ट सेटअप समस्याएँ पैदा कर रहा है?
व्लादिमीर ग्रिट्सेंको

हो सकता है मैं प्रश्न को थोड़ा स्पष्ट कर सकूं। मैं प्रश्न को थोड़ा संपादित करूंगा।
रश्मि रंजन मल्लिक

@VladimirGritsenko: कृपया अब जांचें। मैंने इसे संपादित किया है।
रश्मि रंजन मलिक

प्रश्न में कोड नेविगेशन कंट्रोलर के स्टैक का उपयोग नहीं करता है, बल्कि मोडल प्रस्तुति है, इसलिए यह अभी भी स्पष्ट नहीं है कि आप वास्तव में क्या कर रहे हैं। मैं कहूंगा कि हमारे कोड में, YES को shouldAutoRotate से लौटाना और प्रस्तुत VC में वांछितInterfaceOrientations से वांछित अभिविन्यास लौटना ठीक से कुलपति करता है।
व्लादिमीर ग्रिट्सेंको

खैर, यह वास्तव में विफल नहीं है, यह अवधारणा में सिर्फ एक बड़ा बदलाव है। चाहे वह अच्छा बदलाव हो, पूरी तरह से एक अन्य विषय है।
केगलुनिक

जवाबों:


315

IOS 7 के लिए - 10:

उद्देश्य सी:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

स्विफ्ट 3:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()

बस इसे - viewDidAppear:प्रस्तुत दृश्य नियंत्रक में कॉल करें ।


61
यह निजी एपीआई नहीं है। यह एपीआई का असुरक्षित उपयोग है। आप किसी निजी तरीके का उपयोग नहीं कर रहे हैं, लेकिन 'आंतरिक चीजों' का उपयोग कर रहे हैं। यदि Apple "अभिविन्यास" के लिए मान बदलता है, तो यह विफल हो जाता है। इससे भी बदतर: यदि Apple "अभिविन्यास" मान का अर्थ बदलता है, तो आप नहीं जानते कि आप मूल्य-निर्धारण को क्या बदल रहे हैं।
sonxurxo

4
अक्षम एनीमेशन, कहें [UIView setAnimationsEnabled:NO];में viewWillAppearऔर [UIView setAnimationsEnabled:YES];में viewDidAppear:, संबंधित stackoverflow.com/a/6292506/88597
ohho

3
अच्छा हैक, लेकिन उस के साथ समस्या यह है कि नए अभिविन्यास मूल्य (आह) की स्थापना के बाद didRotateFromInterfaceOrientation फायरिंग नहीं है
loretoparisi

2
IOS 9.2 में, यह केवल ओरिएंटेशन बदल रहा है लेकिन लॉकिंग नहीं है।
मार्क 13426

2
हर किसी के लिए यह 90% अच्छा व्यवहार करता है और समय के अन्य 10% को छोटा कर देता है, इसे अभिविन्यास कुंजी सेट करने के बाद कॉल करें:[UINavigationController attemptRotationToDeviceOrientation];
अल्बर्ट रेनशॉ

93

यदि आप UINavigationControllerया के अंदर हैं तो ओरिएंटेशन रोटेशन थोड़ा अधिक जटिल हैUITabBarController । समस्या यह है कि अगर इन नियंत्रक में से एक में कोई व्यू कंट्रोलर एम्बेडेड है तो नेविगेशन या टैब बार कंट्रोलर पूर्वता लेता है और ऑटोरोटेशन और समर्थित झुकाव पर निर्णय लेता है।

मैं UINavigationController और UITabBarController पर निम्नलिखित 2 एक्सटेंशन का उपयोग करता हूं ताकि इन नियंत्रकों में से एक में देखे गए नियंत्रक निर्णय लेने के लिए मिल सकें।

पावर नियंत्रक देखें!

स्विफ्ट 2.3

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

extension UITabBarController {
    public override func supportedInterfaceOrientations() -> Int {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

स्विफ्ट 3

extension UINavigationController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return visibleViewController?.supportedInterfaceOrientations ?? super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        return visibleViewController?.shouldAutorotate ?? super.shouldAutorotate
    }
}

extension UITabBarController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

अब आप supportedInterfaceOrientationsविधि को ओवरराइड कर सकते हैं या आप ओवरराइड कर सकते हैंshouldAutoRotate उस व्यू कंट्रोलर में जिसे आप लॉक करना चाहते हैं अन्यथा आप अन्य व्यू कंट्रोलर में ओवरराइड को छोड़ सकते हैं जिसे आप अपने ऐप के प्लिस्ट में निर्दिष्ट डिफ़ॉल्ट अभिविन्यास व्यवहार को विरासत में प्राप्त करना चाहते हैं।

रोटेशन अक्षम करें

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

विशिष्ट अभिविन्यास के लिए ताला

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

सिद्धांत रूप में यह सभी जटिल दृश्य नियंत्रक पदानुक्रमों के लिए काम करना चाहिए, लेकिन मैंने UITabBarController के साथ एक मुद्दे पर ध्यान दिया है। किसी कारण से यह एक डिफ़ॉल्ट अभिविन्यास मूल्य का उपयोग करना चाहता है। निम्नलिखित ब्लॉग पोस्ट देखें यदि आप कुछ मुद्दों के आसपास काम करने के तरीके के बारे में जानने में रुचि रखते हैं:

लॉक स्क्रीन रोटेशन


1
मुझे पता है कि यह बहुत पुरानी पोस्ट है लेकिन आप एक्सटेंशन कोड कहां डालेंगे?
४६ पर dwinnbrown

7
नीचे एक स्विफ्ट के लिए अंकन केवल एक उद्देश्य-सी प्रश्न पर उत्तर देता है।
चार्ली स्कॉट-स्किनर

17
यह Swift और ObjC के लिए एक अच्छा उपाय है। समझ में नहीं आता कि लोग मतदान क्यों करें। आपको विचार मिला और फिर कोड लिखना आसान है। शिकायत क्यों?
झाओ

2
@ क्रोध, एक्सटेंशन में "-> Int" से "-> UIInterfaceOrientationMask" बदलने का प्रयास करें। मेरे लिए छल किया।
the_pantless_coder

2
विचार और कोड एकदम सही है, मैं इसे प्यार करता हूं, लेकिन UINavigationController का उपयोग करते समय एक मुद्दा है, और एक UIViewController से वापस परिदृश्य में प्रदर्शित किया जा रहा है जिसे चित्र में प्रदर्शित किया जाना है। कोई विचार?
संकटगृह

24

इसी से मेरा काम बना है:

https://developer.apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

इसे अपने viewDidAppear: विधि में कॉल करें।

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [UIViewController attemptRotationToDeviceOrientation];
}

3
बहुत उपयोगी है, अगर डिवाइस पहले से ही घुमाया गया है और आपको अपने दृश्य नियंत्रक को घुमाने की जरूरत है
avdyushin

2
बहुत बढ़िया जवाब। जब स्वीकार किए गए उत्तर के साथ संयोजन में उपयोग किया जाता है, तो यह स्विफ्ट और आईओएस 9+ में हर बार मेरे लिए अच्छा काम करता है।
एंडीडुन

1
हालांकि मुझे लगता है कि यह पूछे गए सवाल का जवाब नहीं है, लेकिन इसने वास्तव में मेरी मदद की।
अब्दुर्रहमान मुबीन अली 12

21

मैंने पाया कि अगर यह एक प्रस्तुत दृश्य नियंत्रक है, तो आप ओवरराइड कर सकते हैं preferredInterfaceOrientationForPresentation

स्विफ्ट:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
  return false
}

4
ऐसा लगता है कि स्वीकृत जवाब बस परिदृश्य के लिए एक अभिविन्यास परिवर्तन को ट्रिगर करता है। आपने यहां जो दिखाया है, वह यह है कि किसी व्यू कंट्रोलर को केवल लैंडस्केप में किस तरह से बाध्य किया जाए, और प्रेजेंटिंग व्यू कंट्रोलर को प्रभावित न किया जाए (जो वास्तव में आपकी जरूरत है)। धन्यवाद।
क्लिफ्टन लैब्रम

1
@CliftonLabrum क्या आपने केवल परिदृश्य को मजबूर करने के लिए कुछ और किया ? समान कोड का उपयोग करते हुए, व्यू कंट्रोलर अभी भी किसी अन्य ओरिएंटेशन को घुमाने में सक्षम है।
Crashalot

मुझे बाद में एहसास हुआ कि - आप सही हैं। मुझे अभी तक कोई फ़िक्स नहीं मिला है।
क्लिफ्टन लैब्रम

1
इसने मेरे लिए काम किया। मैं इस कोड का उपयोग करके पोर्ट्रेट मोड में एकल दृश्य नियंत्रक रखने में सक्षम था (पोर्ट्रेट के साथ लैंडस्केप की जगह)। +1
मार्क बैरासो

हाँ! यह मेरे लिए भी Xcode 7.3 और स्विफ्ट 2.2 में काम किया। लेकिन अभी भी AppDelegate में supportInterfaceOrientationsForWindow के लिए फंक एप्लिकेशन को परिभाषित करने की आवश्यकता है।
charles.cc.hsu 23

15

इस तरह से मेरे लिए स्विफ्ट 2 आईओएस 8.x में काम करें:

पुनश्च (इस विधि को हर दृष्टिकोण पर कंधे के नीचे की तरह उन्मुखीकरण कार्यों को ओवरराइड करने की आवश्यकता नहीं है, केवल Appelelets पर एक विधि)

सामान्य जानकारी प्रोजेक्ट में "पूर्ण स्क्रीन की आवश्यकता है" की जाँच करें। यहाँ छवि विवरण दर्ज करें

तो, AppDelegate.swift पर एक चर बनाएं:

var enableAllOrientation = false

तो, इस फंक को भी लगाएं:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

इसलिए, अपनी परियोजना के हर वर्ग में आप इस संस्करण को व्यूप्लेयर में सेट कर सकते हैं:

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

यदि आपको डिवाइस प्रकार के आधार पर चुनाव करने की आवश्यकता है तो आप ऐसा कर सकते हैं:

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }

बहुत अच्छी व्याख्या
मिहिर ओझा

11

सबसे पहले - यह एक बुरा विचार है, सामान्य तौर पर, आपके ऐप आर्किटेक्चर के साथ कुछ गलत हो रहा है, लेकिन sh..t happens, यदि हां, तो आप नीचे कुछ बनाने की कोशिश कर सकते हैं:

final class OrientationController {

    static private (set) var allowedOrientation:UIInterfaceOrientationMask = [.all]

    // MARK: - Public

    class func lockOrientation(_ orientationIdiom: UIInterfaceOrientationMask) {
        OrientationController.allowedOrientation = [orientationIdiom]
    }

    class func forceLockOrientation(_ orientation: UIInterfaceOrientation) {
        var mask:UIInterfaceOrientationMask = []
        switch orientation {
            case .unknown:
                mask = [.all]
            case .portrait:
                mask = [.portrait]
            case .portraitUpsideDown:
                mask = [.portraitUpsideDown]
            case .landscapeLeft:
                mask = [.landscapeLeft]
            case .landscapeRight:
                mask = [.landscapeRight]
        }

        OrientationController.lockOrientation(mask)

        UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
    }
}

तुलना में AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // do stuff
    OrientationController.lockOrientation(.portrait)
    return true
}

// MARK: - Orientation

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return OrientationController.allowedOrientation
}

और जब भी आप अभिविन्यास को बदलना चाहते हैं, जैसे:

OrientationController.forceLockOrientation(.landscapeRight)

नोट: कभी-कभी, डिवाइस इस तरह के कॉल से अपडेट नहीं हो सकता है, इसलिए आपको अनुसरण करने की आवश्यकता हो सकती है

OrientationController.forceLockOrientation(.portrait)
OrientationController.forceLockOrientation(.landscapeRight)

बस इतना ही


9

यह iOS 6 से ऊपर की तरफ काम करना चाहिए, लेकिन मैंने केवल iOS 8 पर इसका परीक्षण किया है। उपवर्ग UINavigationControllerऔर निम्नलिखित विधियों को ओवरराइड करें:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return NO;
}

या दृश्य दृश्य नियंत्रक से पूछें

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.visibleViewController.preferredInterfaceOrientationForPresentation;
}

- (BOOL)shouldAutorotate {
    return self.visibleViewController.shouldAutorotate;
}

और वहां के तरीकों को लागू करें।


मैंने अभी-अभी अपने ऐप पर Xcode 8.2.1 में iOS 10.0 पर चलने वाले ऐप का परीक्षण किया और यह काम करता है। मेरा गेम मेनू पहली स्क्रीन है और यह घूमती नहीं है; अन्य सभी दृश्य घूमते हैं। उत्तम! यह एक दिया। मुझे केवल Mojo66 द्वारा दिए गए 'पसंदीदाइंटरफेस ऑप्रेशन फ़ॉरप्रेशन' समारोह की आवश्यकता थी।
फिलिप बोर्गेस

9

यह सिड शाह के उत्तर में टिप्पणियों के लिए एक प्रतिक्रिया है , का उपयोग करते हुए एनिमेशन को अक्षम करने के बारे में:

[UIView setAnimationsEnabled:enabled];

कोड:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    [UIView setAnimationsEnabled:NO];

    // Stackoverflow #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}

मैं इसे पोर्ट्रेट के लिए कैसे उपयोग कर सकता हूं।
मुजु

6

यदि आप नेवीगेशन व्यूकंट्रोलर का उपयोग कर रहे हैं, तो आपको इसके लिए अपना सुपरक्लास बनाना चाहिए और ओवरराइड करना चाहिए:

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

यह सेकंडव्यूकंट्रोलर में रोटेशन को अक्षम कर देगा लेकिन यदि आप अपने डिवाइस को पोर्ट्रेट ओरिएंटेशन पर रखते हुए अपना सेकंड व्यू कॉन्ट्रोलर पुश करते हैं तो आपका सेकेंडव्यूकंट्रोलर पोर्ट्रेट मोड में दिखाई देगा।

मान लें कि आप स्टोरीबोर्ड का उपयोग कर रहे हैं। आपको मैनुअल सेग ( कैसे ) और अपने "ऑनक्लिक" विधि में बनाना होगा:

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

यह आपके सुपरक्लास अक्षम ऑटोरोटेट फीचर से पहले लैंडस्केप ओरिएंटेशन को मजबूर करेगा।


6

पर Xcode 8तरीकों गुण के लिए परिवर्तित कर रहे हैं, इसलिए साथ निम्नलिखित काम करता है Swift:

override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override public var shouldAutorotate: Bool {
    return true
}

क्या यह अभिविन्यास को लॉक करता है?
बानुसे सिप २16

1
@bnussey मैं ऑटो रोटेशन को रोकना चाहता था और हमेशा portraitमोड पर रहा, कोई फर्क नहीं पड़ता कि iPad पर ओरिएंटेशन है, shouldAutorotateसच के साथ मैंने इसे हासिल किया।
अली मोमन सानी

4

मैंने कई समाधानों की कोशिश की है, लेकिन जो काम किया है वह निम्नलिखित है:

info.plistआईओएस 8 और 9 में एडिट करने की जरूरत नहीं है ।

- (BOOL) shouldAutorotate {
    return NO;
}   

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}

Apple प्रलेखन से संभावित अभिविन्यास :

UIInterfaceOrientationUnknown

डिवाइस का ओरिएंटेशन निर्धारित नहीं किया जा सकता है।

UIInterfaceOrientationPortrait

डिवाइस पोर्ट्रेट मोड में है, डिवाइस को सीधा और होम बटन को नीचे की तरफ रखा गया है।

UIInterfaceOrientationPortraitUpsideDown

डिवाइस पोर्ट्रेट मोड में है, लेकिन ऊपर की तरफ डिवाइस और ऊपर की तरफ होम बटन है।

UIInterfaceOrientationLandscapeLeft

डिवाइस लैंडस्केप मोड में है, डिवाइस को सीधा रखा गया है और बाईं ओर होम बटन है।

UIInterfaceOrientationLandscapeRight

यह डिवाइस लैंडस्केप मोड में है, डिवाइस सीधे ऊपर की ओर है और दाईं ओर होम बटन है।


3

Sids और Koreys जवाब के संयोजन ने मेरे लिए काम किया।

नेविगेशन नियंत्रक का विस्तार:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

फिर एकल दृश्य पर रोटेशन को अक्षम करना

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

और सेगमेंट से पहले उपयुक्त अभिविन्यास के लिए घूर्णन

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}

क्या आप जानते हैं कि क्या इससे मेरी समस्या का समाधान हो सकता है, जहाँ प्रदर्शित होने वाला दृश्य नियंत्रक एक सेकंड के लिए परिदृश्य में है, इससे पहले कि यह हमेशा हो सकता है जैसे चित्र के लिए घूमता है? सवाल यहाँ है: stackoverflow.com/questions/30693964/…
dwinnbrown

3

ऊपर का हल:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

मेरे लिए didnt'work जब मैंने इसे viewDidAppear में प्रस्तुत दृश्य नियंत्रक में बुलाया। हालांकि यह तब काम आया जब मैंने इसे प्रेजेंट व्यू कंट्रोलर में तैयारीफॉरग्यूग में बुलाया।

(क्षमा करें, उस समाधान पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा अंक नहीं हैं, इसलिए मुझे इसे इस तरह जोड़ना पड़ा)


मुझे यह काम मिल गया है, लेकिन जब परिदृश्य दृश्य नियंत्रक से पोर्ट्रेट व्यू कंट्रोलर के लिए जा रहा है, तो दृश्य नियंत्रक जो पोर्ट्रेट में दिखना चाहिए, उसे अपने आप घुमाने से पहले परिदृश्य में संक्षेप में दिखाया गया है। अगर किसी को पता है कि मेरे सवाल में मदद कैसे की जाए: stackoverflow.com/questions/30693964/…
dwinnbrown

viewdidAppear पर @dwinnbrown दृश्य नियंत्रक पहले से ही दिखाई दे रहा है। हो सकता है कि इसके बजाय viewDidLoad से प्रयास करें?
क्रैशलॉट

@ चरसालोट मैंने अब यह तय कर दिया है। कृपया मेरे द्वारा दिए गए उत्तर को सही के रूप में देखें।
dwinnbrown

@dwinnbrown आपके प्रश्न का लिंक मृत है। अपडेट करें? धन्यवाद!
Crashalot

@ समुदायशालोट ने इसे हटा दिया लेकिन मैंने इसे हटाने के लिए मतदान किया है। मैं जल्द ही आपको
बता दूंगा

3

[iOS9 +] अगर किसी ने भी नीचे दिए गए सभी तरीकों को ऊपर नहीं खींचा, जैसा कि ऊपर दिए गए समाधानों में से किसी ने भी काम नहीं किया है, और यदि आप उस दृश्य को प्रस्तुत करते हैं जिसे आप segue द्वारा अभिविन्यास बदलना चाहते हैं, तो आप यह जाँच सकते हैं।

अपने सेगमेंट की प्रस्तुति का प्रकार जांचें। मेरा 'वर्तमान संदर्भ में' था। जब मैंने इसे फुलस्क्रीन में बदला, तो इसने काम किया।

@GabLeRoux के लिए धन्यवाद, मुझे यह समाधान मिला।

  • यह परिवर्तन केवल तब काम करता है जब ऊपर के समाधानों के साथ जोड़ा जाता है।

2

मेरी आवश्यकताएं हैं

  1. पोर्ट्रेट मोड में सभी दृश्य लॉक करें
  2. AVPlayerViewControllerवीडियो चलाने के लिए उपयोग करें

जब वीडियो चल रहा है, अगर यह एक लैंडस्केप है तो स्क्रीन को लैंडस्केप राइट और लैंडस्केप बाएं घूमने दें। यदि यह एक पोर्ट्रेट है तो केवल पोर्ट्रेट मोड में व्यू को लॉक करें।

सबसे पहले, को परिभाषित supportedInterfaceOrientationsForWindowमेंAppDelegate.swift

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

दूसरे, अपने मुख्य दृश्य नियंत्रक में, निम्नलिखित कार्यों को परिभाषित करें

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

override func shouldAutorotate() -> Bool {
    return false
}

फिर, आपको उपवर्ग करने की आवश्यकता है AVPlayerViewController

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

इन तीन कार्यों को ओवरराइड करें MyPlayerViewController.swift

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

क्योंकि उपयोगकर्ता डिवाइस लैंडस्केप को बाएँ या दाएँ दाएँ घुमा सकता है, हमें सही होने के लिए ऑटो रोटेट सेट करना होगा

override func shouldAutorotate() -> Bool {
    return true
}

अंत में, MyPlayerViewControllerअपने दृश्य नियंत्रक में उदाहरण बनाएं और संपत्ति का आकार निर्धारित करें।

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

अपने खिलाड़ी को उचित के साथ आरंभ करें videoUrl, फिर अपने खिलाड़ी को असाइन करें playerViewController। हैप्पी कोडिंग!



1

इस कार्य को पूरा करने के लिए अभी भी कुछ बहस हो रही है, इसलिए मुझे लगा कि मैं अपना (काम करने का) तरीका साझा करूंगा। अपने UIViewControllerकार्यान्वयन में निम्नलिखित कोड जोड़ें :

- (void) viewWillAppear:(BOOL)animated
{
    [UIViewController attemptRotationToDeviceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}

इस उदाहरण के लिए, आपको अपनी अनुमत डिवाइस को अपनी परियोजना सेटिंग्स (या सीधे info.plist) में 'लैंडस्केप लेफ्ट' पर सेट करने की आवश्यकता होगी । यदि आप इसके अलावा कुछ और चाहते हैं तो केवल उस विशिष्ट अभिविन्यास को बदलें जिसे आप बाध्य करना चाहते हैंLandscapeLeft.

मेरे लिए कुंजी attemptRotationToDeviceOrientationकॉल था viewWillAppear- इसके बिना डिवाइस को भौतिक रूप से घुमाने के बिना दृश्य ठीक से नहीं घूमेगा।


पदावनत विधि।
साकिब ओमर

1

कोरी हिंटन के जवाब के अनुसार

स्विफ्ट 2.2:

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return visibleViewController!.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController!.shouldAutorotate()
    }
}


extension UITabBarController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

रोटेशन अक्षम करें

override func shouldAutorotate() -> Bool {
    return false
}

विशिष्ट अभिविन्यास के लिए ताला

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}

1

मैंने यहां कुछ समाधानों की कोशिश की और समझने की महत्वपूर्ण बात यह है कि यह रूट व्यू कंट्रोलर है जो यह निर्धारित करेगा कि यह घूमेगा या नहीं।

मैंने निम्नलिखित उद्देश्य-सी प्रोजेक्ट github.com/GabLeRoux/RotationLockInTabbedViewChild बनाया है, TabbedViewControllerजहां काम करने के उदाहरण के साथ एक बच्चे के दृश्य को घुमाने की अनुमति है और दूसरे बच्चे के दृश्य को चित्र में बंद किया गया है।

यह सही नहीं है, लेकिन यह काम करता है और एक ही विचार को अन्य तरह के मूल विचारों के लिए काम करना चाहिए जैसे कि NavigationViewController। :)

चाइल्ड व्यू पैरेंट ओरिएंटेशन को लॉक करता है


0

@ साइड-शा द्वारा दिखाए गए समाधान के अनुसार आपको सब कुछ viewDidAppear:विधि में रखना होगा, अन्यथा आपको didRotateFromInterfaceOrientation:निकाल नहीं दिया जाएगा, इसलिए कुछ इस प्रकार है:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}

0

मेरा समाधान

इन AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if let topController = UIViewController.topMostViewController() {
        if topController is XXViewController {
            return [.Portrait, .LandscapeLeft]
        }
    }
    return [.Portrait]
}

XXViewController आप परिदृश्य मोड का समर्थन करना चाहते हैं ViewController है।

फिर सनी शाह का समाधान आपके XXViewControllerकिसी भी iOS संस्करण पर काम करेगा :

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

यह सबसे अधिक ViewController खोजने के लिए उपयोगिता समारोह है।

extension UIViewController {

    /// Returns the current application's top most view controller.
    public class func topMostViewController() -> UIViewController? {
        let rootViewController = UIApplication.sharedApplication().windows.first?.rootViewController
        return self.topMostViewControllerOfViewController(rootViewController)
    }



    /// Returns the top most view controller from given view controller's stack.
    class func topMostViewControllerOfViewController(viewController: UIViewController?) -> UIViewController? {
        // UITabBarController
        if let tabBarController = viewController as? UITabBarController,
           let selectedViewController = tabBarController.selectedViewController {
            return self.topMostViewControllerOfViewController(selectedViewController)
        }

        // UINavigationController
        if let navigationController = viewController as? UINavigationController,
           let visibleViewController = navigationController.visibleViewController {
            return self.topMostViewControllerOfViewController(visibleViewController)
        }

        // presented view controller
        if let presentedViewController = viewController?.presentedViewController {
            return self.topMostViewControllerOfViewController(presentedViewController)
        }

        // child view controller
        for subview in viewController?.view?.subviews ?? [] {
            if let childViewController = subview.nextResponder() as? UIViewController {
                return self.topMostViewControllerOfViewController(childViewController)
            }
        }

        return viewController
    }

}

0

IOS 9 पर परीक्षण किए गए व्यू कंट्रोलर ओरिएंटेशन को लॉक करने के लिए इसका उपयोग करें:

// लैंडस्केप राइट के लिए ओरिएंटेशन लॉक करें

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}

0

मेरे पास एक ही समस्या है और इसके लिए बहुत समय बर्बाद करना है। इसलिए अब मेरे पास मेरा हल है। मेरा ऐप सेटिंग सिर्फ समर्थन चित्र है only.However, मेरे ऐप में कुछ स्क्रीन परिदृश्य only.I करके इसे ठीक एक चर राशि है जरूरत isShouldRotate पर AppDelegate । और AppDelegate में समारोह :

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

और अंत में जब एक ViewControllerA परिदृश्य राज्य की जरूरत है। बस ऐसा करें: पुश करने से पहले / देखने के लिए ViewControllerA असाइन करें ishouldRotate to true । भूल जाते हैं जब पॉप / असाइन कि नियंत्रक खारिज न करें isShouldRotate को झूठे पर viewWillDisappear


0

मेरे लिए, शीर्ष स्तर के वीसी को अभिविन्यास को लागू करने की आवश्यकता है। यदि वीसी शीर्ष वीसी को लागू नहीं कर रहा है तो वीसी के डाउन का उपयोग करने से कोई प्रभाव नहीं पड़ेगा।

VC-main
    |
    -> VC 2
        |
        -> VC 3

केवल वीसी-मेन की सुनी जाती है, अनिवार्य रूप से मेरे परीक्षण में।


0

ऐसा लगता है कि यहां तक ​​कि आप यहां इतने जवाब हैं कि कोई भी मेरे लिए पर्याप्त नहीं था। मैं ओरिएंटेशन को मजबूर करना चाहता था और फिर वापस जाकर डिवाइस ओरिएंटेशन पर वापस जाता हूं लेकिन[UIViewController attemptRotationToDeviceOrientation]; बस काम नहीं करता था। यह भी जटिल था कि पूरी बात यह है कि मैंने कुछ उत्तर के आधार पर झूठी बात जोड़ दी थी और सभी परिदृश्यों में सही तरीके से घूमने के लिए वांछित प्रभाव नहीं प्राप्त कर सका।

तो यही वह है जो मैंने किया:

अपने इनिट कंस्ट्रक्टर में कॉल में कंट्रोलर को पुश करने से पहले:

_userOrientation = UIDevice.currentDevice.orientation;
[UIDevice.currentDevice setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
[self addNotificationCenterObserver:@selector(rotated:)
                               name:UIDeviceOrientationDidChangeNotification];

इसलिए मैं अंतिम डिवाइस ओरिएंटेशन को सहेजता हूं और ओरिएंटेशन चेंज इवेंट के लिए रजिस्टर करता हूं। अभिविन्यास परिवर्तन घटना सरल है:

- (void)rotated:(NSNotification*)notification {
    _userOrientation = UIDevice.currentDevice.orientation;
}

और यह देखते हुए कि मैं उपयोगकर्ता के रूप में मेरे पास किसी भी अभिविन्यास के लिए मजबूर करता हूं:

- (void)onViewDismissing {
    super.onViewDismissing;
    [UIDevice.currentDevice setValue:@(_userOrientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

और यह वहाँ भी है:

- (BOOL)shouldAutorotate {
    return true;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

और नेविगेशन कंट्रोलर को भी शोकेस करना होगा।

पुनश्च: क्षमा करें, मैं कुछ एक्सटेंशन और आधार कक्षाओं का उपयोग करता हूं, लेकिन नाम काफी सार्थक हैं, इसलिए अवधारणा समझ में आती है, और भी अधिक विस्तार कर देगा क्योंकि यह अब बहुत अधिक नहीं है।

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