uiscreen applicationframe إرجاع مستطيل غير صحيح على إطلاق تطبيق المشهد (iPhone/iPad)
-
27-09-2019 - |
سؤال
تواجه مشكلة في الحصول على الحدود الصحيحة لتطبيق iPad الخاص بي عند تشغيله في وضع المناظر الطبيعية. لديّ المفاتيح المناسبة في ملف info.plist الخاص بي ، وتشغيل وحدات التحكم في العرض الخاصة بي بشكل صحيح في المناظر الطبيعية (وصورة ، natch).
في applicationDidFinishLaunching:
الطريقة التي أتصل بها محددًا بعد تأخير 3 ثانية ، وهذه الطريقة تقوم بالاتصال بـ [[UIScreen mainScreen] applicationFrame]
, ، لكنها تعيد لي إطارًا صورة (أي ارتفاع> عرض).
هل يعرف اي احد كيفية اصلاح هذا؟ تنبعث منه رائحة خطأ بالنسبة لي (إذا كان الأمر كذلك ، فسأقدم رادارًا) ، ولكن إذا كان السلوك المقصود ، فأين يتم توثيقه؟
المحلول
عندما تمسك جهاز iPad في اتجاه المناظر الطبيعية وتطلق تطبيقًا ، ترى وحدة التحكم في العرض في البداية حدود لعرض صورة (على الرغم من أن توجيه المشهد). ستحصل وحدة تحكم العرض بعد ذلك على رسالة للتدوير إلى اتجاه المناظر الطبيعية قبل ظهورها.
نصائح أخرى
أنا لا أعتمد على [[UIScreen mainScreen] applicationFrame]
, ، خاصة أثناء إطلاق التطبيق.
عند إنشاء طرق عرض في التعليمات البرمجية ، استخدم الإشراف لتعيين إطارك.
إذا كنت تستخدم XIBS مع "عناصر واجهة محاكاة" ، فستكون حجمها بشكل صحيح وسيعمل كل شيء بشكل رائع.
تطبيقات uinavigationController القائمة
في حالة تطبيق قائم على uinavigationscontroller ، احصل على الإطار مباشرة من self.navigationController.view
, ، لا تحاول استخدام [self loadView]
و self.view.superview
. يستخدم UinavigationScontroller عمليات عرض فرعية "Hidden" للقيام بعملها-لذلك لن تنجح الرؤية المباشرة.
uinavigationController مميز لأنه أثناء إطلاق التطبيق ، تقوم وحدة تحكم التنقل بتغيير تغيير وجهات نظرك بعد loadView
يتم استدعاء. عندما ينتهي بك المطاف بهامش صغير في أسفل الشاشة.
لماذا لا uiscreen
[[UIScreen mainScreen] applicationFrame]
لا يعمل بشكل موثوق (خاصة أثناء إطلاق التطبيق في المناظر الطبيعية). تجربتي هي أن ViewController interfaceOrientation
العقار لن يتطابق مع applicationFrame
اتجاه.
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
هذه هي الطريقة التي أحصل بها على CGRECT الصحيحة عندما تكون وحدة تحكم العرض في المناظر الطبيعية:
CGRect landscapeBounds;
if (self.view.frame.size.width < self.view.frame.size.height)
landscapeBounds = CGRectMake(self.view.frame.origin.y, self.view.frame.origin.x, self.view.frame.size.height, self.view.frame.size.width);
else
landscapeBounds = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
هذا كما هو مصمم. يجب عليك الاستعلام عن حجم الرؤية الإشرافية والضبط حسب الضرورة.
[[UIScreen mainScreen] applicationFrame]
سيعود دائمًا إلى مستطيل الصورة حتى لو كان التطبيق في وضع المناظر الطبيعية. هذا مرتبط بحقيقة أن UIWindow
أبداً في الواقع يدور ، ولكن فقط يغير تحويل rootViewController.view
في حين أن.
للتأكد ، يمكنك طباعة كائن عرض الجذر في أوضاع الصورة والمناظر الطبيعية ، وسترى شيئًا كهذا:
لَوحَة:
<UIView: 0x96290e0; frame = (0 20; 768 1004); ...
المناظر الطبيعيه:
<UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...
لذلك ، أضف صورة إطلاق ومنحها لاحقة -568 ساعة ، وفقًا لأدلة Apple.
لا أفهم لماذا سيجعل أي شخص لديه عقل سليم إعداد نظام يعتمد على رسم ؛ لكنني اختبرت للتو وعملت.
هنا هو المكان الذي علمتني بعد البحث السريع لم أر هذه الإجابة أعلاه ، وحسبت أنها ستكون مفيدة لشخص ما.
س
واجهت نفس المشكلة عند رفض العرض باستخدام DisissViewControllerAnimated في البرنامج المساعد Cordova. لقد قمت بتعديل رمز SingingAtom لطريقة ViewWillAppear في MainViewController ، والتي تم تغيير حجمها بعد رفض عرض الوسائط:
- (void)viewWillAppear:(BOOL)animated
{
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIDeviceOrientationLandscapeLeft == orientation ||
UIDeviceOrientationLandscapeRight == orientation)
{
if (appFrame.size.width < appFrame.size.height)
{
appFrame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width);
}
}
self.view.frame = appFrame;
[super viewWillAppear:animated];
}