स्क्रीन की अभिविन्यास-निर्भर ऊंचाई और चौड़ाई कैसे प्राप्त करें?


96

मैं अपने आवेदन की वर्तमान ऊंचाई और चौड़ाई को प्रोग्रामेटिक रूप से निर्धारित करने की कोशिश कर रहा हूं। मैं इसका उपयोग करता हूं:

CGRect screenRect = [[UIScreen mainScreen] bounds];

लेकिन यह 320 की चौड़ाई और 480 की ऊँचाई पर निर्भर करता है, भले ही यह उपकरण पोर्ट्रेट या लैंडस्केप ओरिएंटेशन में हो। मैं अपनी मुख्य स्क्रीन की वर्तमान चौड़ाई और ऊंचाई (यानी डिवाइस ओरिएंटेशन पर निर्भर) कैसे निर्धारित कर सकता हूं ?

जवाबों:


164

आप UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)ओरिएंटेशन निर्धारित करने के लिए कुछ का उपयोग कर सकते हैं और फिर तदनुसार आयामों का उपयोग कर सकते हैं।

कैसे, UIViewController में एक अभिविन्यास परिवर्तन के दौरान

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
                                 duration:(NSTimeInterval)duration

toInterfaceOrientationUIApplication के स्टेटस के बाद से ओरिएंटेशन का उपयोग करें ।ऑरिजनेशन अभी भी पुराने ओरिएंटेशन को इंगित करेगा क्योंकि यह अभी तक नहीं बदला है (क्योंकि आप एक willइवेंट हैंडलर के अंदर हैं )।

सारांश

इसके लिए कई संबंधित पोस्ट हैं, लेकिन उनमें से प्रत्येक यह दर्शाता है कि आपको यह करना है:

  1. को देखो [[UIScreen mainScreen] bounds]आयाम प्राप्त करने के लिए,
  2. जांचें कि आप किस अभिविन्यास में हैं, और
  3. स्थिति बार ऊंचाई के लिए खाता (यदि दिखाया गया है)

लिंक

कार्य कोड

मैं आमतौर पर इससे दूर नहीं जाता, लेकिन आपने मेरी रुचि को बढ़ा दिया। निम्नलिखित कोड को चाल करना चाहिए। मैंने UIApplication पर एक श्रेणी लिखी। मैंने दिए गए अभिविन्यास में करंट साइज़ या साइज़ पाने के लिए क्लास मेथड्स जोड़े, जिसे आप UIViewController में कहेंगे willRotateToInterfaceOrientation:duration:

@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end

@implementation UIApplication (AppDimensions)

+(CGSize) currentSize
{
    return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
    CGSize size = [UIScreen mainScreen].bounds.size;
    UIApplication *application = [UIApplication sharedApplication];
    if (UIInterfaceOrientationIsLandscape(orientation))
    {
        size = CGSizeMake(size.height, size.width);
    }
    if (application.statusBarHidden == NO)
    {
        size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
    }
    return size;
}

@end

कोड सरल कॉल का उपयोग करने के लिए [UIApplication currentSize]। इसके अलावा, मैंने उपरोक्त कोड चलाया, इसलिए मुझे पता है कि यह काम करता है और सभी झुकावों में सही प्रतिक्रियाओं की रिपोर्ट करता है। ध्यान दें कि मैं स्थिति पट्टी में कारक हूं। दिलचस्प बात यह है कि मुझे स्टेटस बार की ऊंचाई और चौड़ाई को घटाना था।

उम्मीद है की यह मदद करेगा। : डी

अन्य विचार

आप UIWindow की rootViewControllerसंपत्ति को देखकर आयाम प्राप्त कर सकते हैं। मैंने इसे अतीत में देखा है और यह चित्र और परिदृश्य दोनों में समान आयामों की रिपोर्ट करता है, सिवाय इसके कि यह रोटेट ट्रांसफ़ॉर्म होने की रिपोर्ट करता है:

(gdb) पो [[[[[अपर साझाकरण

<UILayoutContainerView: 0xf7296f0; फ्रेम = (0 0; 320 480); रूपांतर = [0, -1, 1, 0, 0, 0]; autoresize = W + H; परत = <CALayer: 0xf729b80 >>

(gdb) पो [[[[[अपर साझाकरण

<UILayoutContainerView: 0xf7296f0; फ्रेम = (0 0; 320 480); autoresize = W + H; परत = <CALayer: 0xf729b80 >>

यह निश्चित नहीं है कि आपका ऐप कैसे काम करता है, लेकिन यदि आप किसी प्रकार के नेविगेशन नियंत्रक का उपयोग नहीं कर रहे हैं, तो आप अपने मुख्य दृश्य के तहत माता-पिता की अधिकतम ऊंचाई / चौड़ाई और माता-पिता के साथ बढ़ते / सिकुड़ सकते हैं। तब आप कर सकते हैं:[[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame] :। यह एक लाइन पर बहुत तीव्र लग रहा है, लेकिन आपको यह विचार मिलता है।

हालाँकि ... सारांश के तहत उपरोक्त 3 चरणों को करना अभी भी बेहतर होगा। UIWindows के साथ खिलवाड़ करना शुरू करें और आपको अजीब चीजें मिलेंगी, जैसे कि UIAlertView दिखाना UIApplication के कीविंडो को एक नए UIWindow पर इंगित करने के लिए बदल देगा जिसे UIAlertView ने बनाया है। किसे पता था? मैंने कीविन्दो पर निर्भर एक बग को खोजने के बाद किया और यह खोज की कि यह उस तरह बदल गया है!


5
यह ऐसे प्राथमिक कार्य की तरह लगता है कि मुझे विश्वास करने में परेशानी हो रही है कि मुझे इस तरह से कुछ निर्धारित करने के लिए अपना कोड हैक करना होगा।
मुसिएनेसिस

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

1
महान! (बीटीडब्लू, किसी की रुचि बढ़ी है) :-)
वमोस

1
यदि आप (यूआईस्क्रीन पर) के applicationFrameबजाय उपयोग boundsकरते हैं, तो आपको स्थिति बार की ऊंचाई को घटाना नहीं है।
अन्सफैन

2
stackoverflow.com/questions/24150359/… mainScreen().bounds.size iOS 8 के बाद से ओरिएंटेशन पर निर्भर हो गया है
गेराल्ड

39

यह मेरा समाधान कोड है! यह विधि NSObject वर्ग के वर्गीकृत में जोड़ सकती है, या आप एक शीर्ष कस्टम UIViewController वर्ग को परिभाषित कर सकते हैं, और अपने सभी अन्य UIViewControllers को इसे विरासत में दे सकते हैं।

-(CGRect)currentScreenBoundsDependOnOrientation
{  

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
    }
    return screenBounds ;
}

ध्यान दें , IOS8 के बाद, जैसा कि UIScreen की सीमा संपत्ति का Apple दस्तावेज़ कहता है:

विचार-विमर्श

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

इसलिए अनुकूलता के विचार के लिए, हमें IOS संस्करण का पता लगाना चाहिए और नीचे जैसा परिवर्तन करना चाहिए:

#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

-(CGRect)currentScreenBoundsDependOnOrientation
{  

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    if(IsIOS8){
        return screenBounds ;
    }
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
    }
    return screenBounds ;
}

मेरे जवाब के रूप में बहुत ही सुंदर, केवल यह याद आती है कि क्या यह पोर्ट्रेट में उल्टा है। यह केवल तभी मायने रखता है जब आप उस अभिविन्यास का समर्थन करते हैं।
रॉबर्ट वागस्टाफ

2
@Monjer आपको उन तरीकों का नाम नहीं देना चाहिए जो एक GET अनुरोध नहीं करते हैं, जो कि मुझे शब्द के साथ पहले से मिला हुआ है। currentScreenBoundsDependOnOrientation विधि का एक बेहतर नाम है
bogen

1
@ Hakonbogen.yes आप सही हो सकते हैं, क्योंकि "पेरोपर्टी" घोषणा स्वचालित रूप से सेटर / गेट्टर विधि उत्पन्न करती है, और इससे नामकरण संघर्ष हो सकता है, और objc के नामकरण सम्मेलनों के खिलाफ जा सकते हैं। आपकी सलाह के लिए धन्यवाद।
मन्जर

यह अच्छा है कि Apple ने अंततः स्वीकार किया है कि उनका रोटेशन कोड एक संपूर्ण गड़बड़ था, और बस हमें यह बताना शुरू कर दिया कि लानत आयाम वर्तमान अभिविन्यास में क्या हैं। वहां पहुंचने के लिए संस्करण 8 तक बहुत बुरा लगा।
मुसईनेसिस

30

यहाँ एक आसान मैक्रो है:

#define SCREEN_WIDTH (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)

14

IOS 8+ में आपको viewWillTransitionToSize:withTransitionCoordinatorविधि का उपयोग करना चाहिए :

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    // You can store size in an instance variable for later
    currentSize = size;

    // This is basically an animation block
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {

        // Get the new orientation if you want
        UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

        // Adjust your views
        [self.myView setFrame:CGRectMake(0, 0, size.width, size.height)];

    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        // Anything else you need to do at the end
    }];
}

यह पदावनत एनीमेशन विधि को प्रतिस्थापित करता है जिसने आकार के बारे में कोई जानकारी नहीं दी:

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration

यह स्वीकृत उत्तर होना चाहिए। आधुनिक और आज तक।
सर्पड्रेग सिप

Ios 8 और इसके बाद के संस्करण के लिए इस उत्तर का उपयोग करें।
iPhoneDeveloper

10

IOS के रूप में 8 स्क्रीन सीमाएं अब वर्तमान अभिविन्यास के लिए सही लौटी हैं। इसका मतलब है कि लैंडस्केप ओरिएंटेशन में एक iPad [UIScreen mainScreen] है। आईओएस 8 पर iOS <= 7 और 1024 पर 768 वापस आ जाएगा।

निम्नलिखित जारी किए गए सभी संस्करणों पर सही ऊंचाई और चौड़ाई देता है।

-(CGRect)currentScreenBoundsDependOnOrientation
{
    NSString *reqSysVer = @"8.0";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
        return [UIScreen mainScreen].bounds;

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
        NSLog(@"Portrait Height: %f", screenBounds.size.height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
        NSLog(@"Landscape Height: %f", screenBounds.size.height);
    }

    return screenBounds ;
}

8

यदि आप अभिविन्यास निर्भर आकार चाहते हैं और आपके पास एक दृश्य है, तो आप बस उपयोग कर सकते हैं:

view.bounds.size

महान! KISS समाधान = रखें यह सरल और बेवकूफ
bsorrentino

3
KISS मतलब नहीं है "यह सरल और बेवकूफ रखें" - हा हा हा! इसका अर्थ है "इसे सरल, मूर्ख बनाए रखें!" :-)
एरिक वैन डेर नीट

इसके अलावा, यह उत्तर स्पष्ट रूप से केवल तभी काम करता है जब आपका विचार पूरी तरह से पूर्ण स्क्रीन के लिए जाना जाता है। लेकिन, अगर ऐसा होता, तो शायद आपको ओपी द्वारा पोस्ट की गई मूल समस्या नहीं होती।
एरिक वैन डेर नीट

5

मैंने श्रेणी के लिए लिखा है UIScreen, जो सभी iOS संस्करणों पर काम करता है, इसलिए आप इसे इस तरह से उपयोग कर सकते हैं
[[UIScreen mainScreen] currentScreenSize]:।

@implementation UIScreen (ScreenSize)

- (CGSize)currentScreenSize {
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    CGSize screenSize = screenBounds.size;

    if ( NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1 ) {  
        UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
        if ( UIInterfaceOrientationIsLandscape(interfaceOrientation) ) {
            screenSize = CGSizeMake(screenSize.height, screenSize.width);
        }
    }

    return screenSize;
}

@end

1
यह मुझे सबसे साफ जवाब लगता है। ऊपर मतदान किया।
एरिक वैन डेर नीट

5

यहाँ अभिविन्यास निर्भर स्क्रीन आकार पाने के लिए एक स्विफ्ट तरीका है:

var screenWidth: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.width
    } else {
        return UIScreen.mainScreen().bounds.size.height
    }
}
var screenHeight: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.height
    } else {
        return UIScreen.mainScreen().bounds.size.width
    }
}
var screenOrientation: UIInterfaceOrientation {
    return UIApplication.sharedApplication().statusBarOrientation
}

ये एक परियोजना में एक मानक कार्य के रूप में शामिल हैं:

https://github.com/goktugyil/EZSwiftExtensions


0
float msWidth = [[UIScreen mainScreen] bounds].size.width*(IS_RETINA?2.0f:1.0f);
float msHeight = [[UIScreen mainScreen] bounds].size.height*(IS_RETINA?2.0f:1.0f);
if ( UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ) {
    os->setWidth(MIN(msWidth, msHeight));
    os->setHeight(MAX(msWidth, msHeight));
} else {
    os->setWidth(MAX(msWidth, msHeight));
    os->setHeight(MIN(msWidth, msHeight));
}

NSLog(@"screen_w %f", os->getWidth());
NSLog(@"screen_h %f", os->getHeight());

0

हालाँकि, iOS 8.0.2 पर:

+ (NSUInteger)currentWindowWidth
{
    NSInteger width = 0;
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    CGSize size = [UIScreen mainScreen].bounds.size;
   // if (UIInterfaceOrientationIsLandscape(orientation)) {
   //     width = size.height;
   // } else {
        width = size.width;
  //  }

    return width;
}

0

उपयोग -> setNeedsDisplay () उस दृश्य के लिए जिसे आप आकार बदलना चाहते हैं।

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