यह प्रतीत होता है कि दोनों iPad के झुकावों को एक समान मानने के लिए Apple के इरादे हैं - लेकिन जैसा कि हम में से कई लोग पा रहे हैं, iPad पोर्ट्रेट बनाम iPad लैंडस्केप के लिए UI लेआउट को अलग करने के लिए बहुत वैध डिजाइन कारण हैं।
दुर्भाग्य से, वर्तमान ओएस इस अंतर के लिए समर्थन प्रदान करने के लिए प्रतीत नहीं होता है ... इसका मतलब है कि हम कोड या इसी तरह के वर्कअराउंड में हेरफेर करने के लिए वापस आ रहे हैं जिसे प्राप्त करने के लिए हम आदर्श रूप से अनुकूली UI का उपयोग करके मुफ्त में प्राप्त कर सकते हैं। ।
सुरुचिपूर्ण समाधान नहीं।
क्या उस जादू का लाभ उठाने का कोई तरीका नहीं है जो Apple ने पहले से ही एक दिए गए अभिविन्यास के लिए हमारे चयन के आकार वर्ग का उपयोग करने के लिए IB और UIKit में बनाया है ?
~
समस्या के बारे में अधिक उदारता से सोचने पर, मैंने महसूस किया कि 'आकार की कक्षाएं' आईबी में संग्रहीत कई लेआउट्स को संबोधित करने के तरीके हैं, ताकि उन्हें रनटाइम में आवश्यकतानुसार बुलाया जा सके।
वास्तव में, एक 'आकार वर्ग' वास्तव में केवल एक जोड़ी है, जो कि बहुत अधिक मूल्यवान है। UIInterface.h से:
typedef NS_ENUM(NSInteger, UIUserInterfaceSizeClass) {
UIUserInterfaceSizeClassUnspecified = 0,
UIUserInterfaceSizeClassCompact = 1,
UIUserInterfaceSizeClassRegular = 2,
} NS_ENUM_AVAILABLE_IOS(8_0);
तो चाहे जो भी हो Apple ने इन विभिन्न रूपों को नाम देने का फैसला किया है , मौलिक रूप से, वे एक पूर्णांक के एक जोड़े को एक विशिष्ट पहचानकर्ता के रूप में उपयोग करते हैं, एक लेआउट को दूसरे से अलग करने के लिए, आईबी में संग्रहीत।
अब, यह मानकर कि हम IB में एक वैकल्पिक लेआउट (अप्रयुक्त आकार वर्ग का उपयोग करके) बनाते हैं - कहते हैं, iPad पोर्ट्रेट के लिए ... क्या डिवाइस का उपयोग हमारी पसंद के आकार वर्ग (UI लेआउट) का उपयोग करना है जैसा कि रनटाइम में किया जाता है। ?
समस्या के कई अलग-अलग (कम सुरुचिपूर्ण) तरीकों की कोशिश करने के बाद, मुझे संदेह था कि डिफ़ॉल्ट आकार वर्ग को प्रोग्रामेटिक रूप से ओवरराइड करने का एक तरीका हो सकता है। और वहाँ (UIViewController.h में):
// Call to modify the trait collection for child view controllers.
- (void)setOverrideTraitCollection:(UITraitCollection *)collection forChildViewController:(UIViewController *)childViewController NS_AVAILABLE_IOS(8_0);
- (UITraitCollection *)overrideTraitCollectionForChildViewController:(UIViewController *)childViewController NS_AVAILABLE_IOS(8_0);
इस प्रकार, यदि आप अपने व्यू कंट्रोलर पदानुक्रम को 'चाइल्ड' व्यू कंट्रोलर के रूप में पैकेज कर सकते हैं, और इसे टॉप-लेवल पैरेंट व्यू कंट्रोलर में जोड़ सकते हैं ... तो आप बच्चे को सशर्त रूप से यह सोचकर ओवरराइड कर सकते हैं कि यह डिफॉल्ट से अलग साइज की क्लास है। ओएस से।
यहाँ एक नमूना कार्यान्वयन है जो ऐसा करता है, 'मूल' दृश्य नियंत्रक में:
@interface RDTraitCollectionOverrideViewController : UIViewController {
BOOL _willTransitionToPortrait;
UITraitCollection *_traitCollection_CompactRegular;
UITraitCollection *_traitCollection_AnyAny;
}
@end
@implementation RDTraitCollectionOverrideViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpReferenceSizeClasses];
}
- (void)setUpReferenceSizeClasses {
UITraitCollection *traitCollection_hCompact = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
UITraitCollection *traitCollection_vRegular = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular];
_traitCollection_CompactRegular = [UITraitCollection traitCollectionWithTraitsFromCollections:@[traitCollection_hCompact, traitCollection_vRegular]];
UITraitCollection *traitCollection_hAny = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
UITraitCollection *traitCollection_vAny = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassUnspecified];
_traitCollection_AnyAny = [UITraitCollection traitCollectionWithTraitsFromCollections:@[traitCollection_hAny, traitCollection_vAny]];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_willTransitionToPortrait = self.view.frame.size.height > self.view.frame.size.width;
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]
_willTransitionToPortrait = size.height > size.width;
}
-(UITraitCollection *)overrideTraitCollectionForChildViewController:(UIViewController *)childViewController {
UITraitCollection *traitCollectionForOverride = _willTransitionToPortrait ? _traitCollection_CompactRegular : _traitCollection_AnyAny;
return traitCollectionForOverride;
}
@end
एक त्वरित डेमो के रूप में यह देखने के लिए कि क्या यह काम करता है, मैंने विशेष रूप से आईबी में चाइल्ड कंट्रोलर लेआउट के 'रेगुलर / रेगुलर' और 'कॉम्पेक्ट / रेगुलर' वर्जन में कस्टम लेबल जोड़े।
और यहाँ क्या चल रहा है जैसा दिखता है, जब iPad दोनों झुकाव में है:
देखा! कस्टम आकार वर्ग विन्यास रनटाइम पर।
उम्मीद है कि Apple ओएस के अगले संस्करण में इसे अनावश्यक बना देगा। इस बीच, यह ऑटो-लेआउट बाधाओं के साथ प्रोग्रामिंग करने या कोड में अन्य जोड़तोड़ करने की तुलना में अधिक सुरुचिपूर्ण और स्केलेबल दृष्टिकोण हो सकता है।
~
EDIT (6/4/15): कृपया ध्यान रखें कि उपरोक्त नमूना कोड अनिवार्य रूप से तकनीक को प्रदर्शित करने के लिए अवधारणा का प्रमाण है। अपने स्वयं के विशिष्ट अनुप्रयोग के लिए आवश्यकतानुसार अनुकूलित करने के लिए स्वतंत्र महसूस करें।
~
EDIT (7/24/15): यह समझ में आता है कि उपरोक्त स्पष्टीकरण समस्या को ध्वस्त करने में मदद करता है। जबकि मैंने इसका परीक्षण नहीं किया है, mohamede1945 द्वारा कोड [नीचे] व्यावहारिक उद्देश्यों के लिए एक सहायक अनुकूलन जैसा दिखता है। बेझिझक इसका परीक्षण करें और हमें बताएं कि आप क्या सोचते हैं। (पूर्णता के हित में, मैं नमूना कोड को इस प्रकार छोड़ दूँगा।)