2015-02-02 5 views
7

घुमाए जाने की इजाजत है, मेरे पास एक बच्चे दृश्य नियंत्रक के साथ एक व्यू कंट्रोलर है।फोर्स आईओएस दृश्य घुमाने के लिए नहीं, जबकि अभी भी बच्चे को

tab bar controller 
| 
| 
nav controller 
| 
| 
UIPageViewController (should rotate) 
| 
| 
A (Video Player) (shouldn't rotate) 
| 
| 
B (Controls overlay) (should rotate) 

ए को हमेशा पोर्ट्रेट रहने के लिए मजबूर होना चाहिए, लेकिन बी को स्वतंत्र रूप से घूमने की अनुमति दी जानी चाहिए।

मुझे पता है shouldAutorotate किसी भी व्यू कंट्रोलर और उसके बच्चों पर लागू होता है, लेकिन क्या इसके आसपास जाने का कोई तरीका है? ऐसा लगता है जैसे मैं shouldAutorotateToInterfaceOrientation इस्तेमाल कर सकते हैं, लेकिन यह आईओएस में अवरुद्ध है 8.

मैं एक वीडियो प्लेयर स्थिर रखना चाहते हैं, (ताकि क्षैतिज वीडियो हमेशा डिवाइस अभिविन्यास की परवाह किए बिना क्षैतिज कर रहे हैं), जबकि नियंत्रण परत subview ओवरले है स्वतंत्र रूप से घूमने की अनुमति दी।

मैं स्विफ्ट का उपयोग कर रहा हूं।

+0

आप ViewControllerA से ViewControllerB धक्का कर रहे हैं? –

+0

मैं इसे एक सबव्यूव के रूप में जोड़ रहा हूं। 'Self.view.addSubview (viewController.view)' – switz

उत्तर

17

मुझे यह सही समस्या थी, और तुरंत पता चला कि ऑटोरोटेशन के बारे में बहुत सारी बुरी सलाह है, खासकर क्योंकि आईओएस 8 पिछले संस्करणों की तुलना में अलग-अलग है।

सबसे पहले, आप मैन्युअल रूप से प्रतिवाद लागू करना चाहते हैं या अभिविन्यास परिवर्तनों की सदस्यता लेना चाहते हैं।एक counterrotation करना अभी भी एक भयानक एनीमेशन होगा, और डिवाइस अभिविन्यास हमेशा इंटरफ़ेस अभिविन्यास के समान नहीं है। आदर्श रूप से आप कैमरे के पूर्वावलोकन को वास्तव में जमे हुए रहने के लिए चाहते हैं, और आपके ऐप यूआई स्टेटस बार अभिविन्यास और आकार से मेल खाते हैं, जैसे वे मूल कैमरा ऐप की तरह बदलते हैं।

आईओएस 8 में एक अभिविन्यास परिवर्तन के दौरान, खिड़की स्वयं दृश्य (दृश्यों) के बजाय घूमती है। आप एकाधिक दृश्य नियंत्रकों के विचारों को एक UIWindow पर जोड़ सकते हैं, लेकिन केवल rootViewController को shouldAutorotate() के माध्यम से प्रतिक्रिया देने का अवसर मिलेगा। भले ही आप व्यू कंट्रोलर स्तर पर रोटेशन निर्णय लेते हैं, फिर भी यह मूल विंडो है जो वास्तव में घूमती है, इस प्रकार इसके सभी सबव्यूज़ (अन्य दृश्य नियंत्रकों के अलावा) को घुमाती है।

समाधान दो UIWindow एक दूसरे के शीर्ष पर ढंका हुआ है, प्रत्येक घूर्णन (या नहीं) अपने स्वयं के रूट व्यू कंट्रोलर के साथ। अधिकांश ऐप्स में केवल एक होता है, लेकिन ऐसा कोई कारण नहीं है कि आपके पास दो और नहीं हो सकते हैं और उन्हें किसी अन्य UIView सबक्लास की तरह ओवरले करें।

यहां एक कामकाजी प्रमाण-अवधारणा है, which I've also put on GitHub here। आपका विशेष मामला थोड़ा अधिक जटिल है क्योंकि आपके पास व्यू कंट्रोलर रखने का ढेर है, लेकिन मूल विचार समान है। मैं नीचे कुछ विशिष्ट बिंदुओं पर छूंगा।

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 
    var cameraWindow: UIWindow! 
    var interfaceWindow: UIWindow! 

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { 
     let screenBounds = UIScreen.mainScreen().bounds 
     let inset: CGFloat = fabs(screenBounds.width - screenBounds.height) 

     cameraWindow = UIWindow(frame: screenBounds) 
     cameraWindow.rootViewController = CameraViewController() 
     cameraWindow.backgroundColor = UIColor.blackColor() 
     cameraWindow.hidden = false 

     interfaceWindow = UIWindow(frame: CGRectInset(screenBounds, -inset, -inset)) 
     interfaceWindow.rootViewController = InterfaceViewController() 
     interfaceWindow.backgroundColor = UIColor.clearColor() 
     interfaceWindow.opaque = false 
     interfaceWindow.makeKeyAndVisible() 

     return true 
    } 
} 

interfaceWindow पर एक नकारात्मक इनसेट स्थापना प्रभावी ढंग से आप मुखौटा अन्यथा देखना चाहते हैं काले आयताकार छुपा है, यह थोड़ा स्क्रीन सीमा से बड़ा बना देता है। आम तौर पर आप ध्यान नहीं देंगे क्योंकि मुखौटा खिड़की के साथ घूमता है, लेकिन जब से कैमरा खिड़की तय की जाती है तो रोटेशन के दौरान कोनों में मुखौटा दिखाई देता है।

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

वास्तव में आप यहाँ क्या उम्मीद थी, बस AVCapturePreviewLayer के लिए अपने स्वयं के सेटअप जोड़ें।

class InterfaceViewController: UIViewController { 
    var contentView: UIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     contentView = UIView(frame: CGRectZero) 
     contentView.backgroundColor = UIColor.clearColor() 
     contentView.opaque = false 

     view.backgroundColor = UIColor.clearColor() 
     view.opaque = false 
     view.addSubview(contentView) 
    } 

    override func viewWillLayoutSubviews() { 
     super.viewWillLayoutSubviews() 

     let screenBounds = UIScreen.mainScreen().bounds 
     let offset: CGFloat = fabs(screenBounds.width - screenBounds.height) 

     view.frame = CGRectOffset(view.bounds, offset, offset) 
     contentView.frame = view.bounds 
    } 

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

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

पिछले चाल नकारात्मक इनसेट हम खिड़की के लिए आवेदन किया है, जो हम view offsetting एक ही राशि और मुख्य दृश्य के रूप में contentView इलाज को प्राप्त नाश कर रहा है।

अपने अनुप्रयोग के लिए, interfaceWindow.rootViewController अपने टैब बार नियंत्रक, जो बारी में एक नेविगेशन नियंत्रक होता है, आदि इन विचारों के सभी जब अपने कैमरे नियंत्रक दिखाई देता है तो कैमरा खिड़की के नीचे इसे माध्यम से दिखा सकते हैं पारदर्शी होने की जरूरत होगी। प्रदर्शन कारणों से आप उन्हें अपारदर्शी छोड़ने पर विचार कर सकते हैं और कैमरे वास्तव में उपयोग में होने पर केवल पारदर्शी होने के लिए सब कुछ सेट कर सकते हैं, और कैमरा विंडो को hidden पर सेट कर सकते हैं जब यह नहीं है (कैप्चर सत्र को बंद करते समय)।

एक उपन्यास पोस्ट करने के लिए खेद है; मैंने इसे कहीं और संबोधित नहीं देखा है और मुझे पता लगाने में थोड़ी देर लग गई है, उम्मीद है कि यह आपको और किसी और को मदद करता है जो एक ही व्यवहार करने की कोशिश कर रहा है। यहां तक ​​कि ऐप्पल का AVCam नमूना ऐप भी इसे ठीक से संभाल नहीं करता है।

The example repo I posted में पहले से सेट किए गए कैमरे के साथ एक संस्करण भी शामिल है। सौभाग्य!

+0

मुझे लगता है कि खिड़की पर एक PreviewView और सबसे बढ़कर एक UIViewController शीर्ष पर अन्य विचारों के लिए रोटेशन संभाल करने के साथ ऐसा करने के तरीके के रूप MainWindow उपयोग करने की कोशिश। यह आईओएस 7 से पहले काम करता था लेकिन 7 के साथ तोड़ दिया। मैंने आईओएस 8 की कोशिश नहीं की है। क्या आपने आईओएस 7 के साथ अपना कोड आजमाया है? दो खिड़कियों का उपयोग करना; प्रतिभाशाली! – mahboudz

+0

क्या आप उम्मीद करते हैं कि फिक्स्ड व्यू कंट्रोलर के लिए कोई उपयोगकर्ता-इंटरैक्टिव आइटम जैसे बटन या इशारा पहचानकर्ता होस्ट करने का कोई तरीका हो? – mahboudz

+0

यह शायद 7 के लिए बॉक्स से बाहर काम नहीं करेगा, लेकिन यह थोड़ा संशोधन के साथ हो सकता है (मैं केवल 8 लक्ष्यीकरण कर रहा हूं)। FixedViewController पर उपयोगकर्ता सहभागिता सामान्य रूप से काम करता है क्योंकि मुख्य दृश्य लाइन के साथ इनसेट हो जाता है 'view.frame = CGRectOffset (view.bounds, ऑफसेट, ऑफसेट)' (आप अभी भी अपने वास्तविक सामग्री के लिए 'contentView' उपयोग करने के लिए, हालांकि चाहता हूँ) । – jstn

0

मुझे यकीन नहीं है, लेकिन मुझे लगता है कि आप अपने सबव्यू के लिए अपनी कक्षा बना सकते हैं और shouldAutorotate विधि इत्यादि को ओवरराइड कर सकते हैं। इस तरह इसे पेरेंट-व्यू कंट्रोलर से shouldAutorotate ओवरराइड करना चाहिए।

1

आप इस कोशिश कर सकते हैं -

उद्देश्य -सी कोड अगर आप तेजी से अपने विकल्प हैं:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
    if()//Place your condition here like if A is visible 
    { 
    return UIInterfaceOrientationMaskPortrait; 
    } 
    return UIInterfaceOrientationMaskAll; 
} 
1

आप रोटेशन परिवर्तन सूचनाओं के लिए सदस्यता ले सकते हैं, और मैन्युअल रूप से रोटेशन subview पर मैट्रिक्स को बदलने के लिए सेट आप घूमना चाहते हैं।

0

संक्षिप्त उत्तर: नहीं, सभी दृश्य नियंत्रक और विचार एक साथ घूमते हैं (या घूमते नहीं हैं)।

लांग जवाब:

सबसे पहले, आप जड़ नियंत्रक में autorotate निर्णय कार्यों को लागू करना चाहिए; इसका मतलब है कि एक एनवी नियंत्रक उपclass बनाना।

आप पैरेंट व्यू ऑटोरोटेट करके अपने वांछित व्यवहार को हैक कर सकते हैं - लेकिन इसे अनियमित दिखाई देने के लिए मैन्युअल रूप से वापस घुमाएं।

या, आप autorotate नहीं कर सकते हैं, लेकिन नोटिफिकेशन कि भौतिक डिवाइस घुमाया के लिए सुनो, और मैन्युअल रूप से बारी बारी से जो कुछ दृश्यों में आप, उदाहरण के लिए करना चाहते हैं: Replicate camera app rotation to landscape IOS 6 iPhone

भी देखें, FYI:

How to force a UIViewController to Portrait orientation in iOS 6

shouldAutoRotate Method Not Called in iOS6

iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates)

How to implement UIViewController rotation in response to orientation changes?

0

इस प्रश्न का सबसे सरल, सबसे सीधा-आगे जवाब ऐप्पल के AVCam नमूना कोड को देखना है। मेरे लिए मुख्य भागों थे यह है कि:

  1. एक दृश्य जिसका layerClassAVCaptureVideoPreviewLayer है उपयोग करता है।
  2. दृश्य प्रस्तुत होने पर एप्लिकेशन के statusBarOrientation से मेल खाने के लिए AVCaptureVideoPreviewLayer के कनेक्शन के videoOrientation सेट करता है, अनिवार्य रूप से viewWillAppear(_:)
  3. videoOrientationviewWillTransitionToSize(_:withTransitionCoordinator:) में UIDevice.currentDevice().orientation मिलान करने के लिए सेट करता है।
  4. ऑटोरोटेशन सक्षम करता है और सभी इंटरफ़ेस उन्मुखताओं का समर्थन करता है।

मैंने जेएसटीएन द्वारा वर्णित पृष्ठभूमि विंडो दृष्टिकोण को कार्यान्वित किया और यह काफी अच्छी तरह से काम किया, लेकिन वास्तविकता यह है कि यह आवश्यक से कहीं अधिक जटिल है। एवीकैम बहुत अच्छा काम करता है और अपेक्षाकृत सरल दृष्टिकोण है।

संबंधित मुद्दे