سؤال

لدي عرض مخصص وهذا لا يحصل layoutSubview الرسائل أثناء الرسوم المتحركة.

لدي رأي يملأ الشاشة. يحتوي على مجموعة فرعية مخصصة في الجزء السفلي من الشاشة التي يتم تغيير حجمها بشكل صحيح في منشئ الواجهة إذا قمت بتغيير ارتفاع شريط NAV. layoutSubviews يتم استدعاء عند إنشاء العرض، ولكن لم يحدث مرة أخرى. يتم وضع فرعياتي الفرعية بشكل صحيح. إذا قمت بتبديل شريط الحالة أثناء الاتصال، فإن الفرعي الفرعي layoutSubviews لا يتم استدعاء على الإطلاق، على الرغم من أن النظرة الرئيسية تقوم بتحريك تغيير حجمها.

تحت أي ظروف layoutSubviews دعا فعلا؟

لدي autoresizesSubviews ضبط ل NO لعرضي المخصص الخاص بي. وفي منشئ الواجهة لدي الدعامات العلوية والسفلية ومجموعة السهم الرأسي.


جزء آخر من اللغز هو أن النافذة يجب أن تصنع المفتاح:

[window makeKeyAndVisible];

وإلا يتم تغيير حجم الفرعين الفرعيين تلقائيا.

هل كانت مفيدة؟

المحلول 5

قمت بتتبع الحل لأسفل إلى إصرار "باني الواجهة" أن الينابيع لا يمكن تغييرها على طريقة عرض تحتوي على عناصر الشاشة المحاكاة قيد التشغيل (شريط الحالة، إلخ). نظرا لأن الينابيع كانت من أجل الرأي الرئيسي، فإن هذا العرض لا يمكن تغيير الحجم وتم تمرير من ذلك، حيث تم التمرير في مجمله عند ظهور شريط الدخول أثناء الاتصال.

قم بإيقاف تشغيل الميزات المحاكاة، ثم تغيير حجم الرأي وإعداد الينابيع بشكل صحيح تسبب في حدوث الرسوم المتحركة وطريقتي التي سيتم استدعاؤها.

مشكلة إضافية في تصحيح الأخطاء وهذا هو أن محاكاة إنهاء التطبيق عند تبديل حالة الاتصال عبر القائمة. إنهاء التطبيق = لا مصحح.

نصائح أخرى

كان لدي سؤال مماثل، لكنني لم يكن راضيا عن الإجابة (أو أي ما يمكنني العثور عليه على الشبكة)، لذلك جربته في الممارسة العملية وهنا ما حصلت عليه:

  • init لا يسبب layoutSubviews أن يسمى (DUH)
  • addSubview: أسبابlayoutSubviews أن يتم استدعاء العرض الذي تمت إضافته، وتم إضافته إلى (عرض الهدف)، وجميع فروع الهدف
  • رأي setFrameمكالمات بذكاء layoutSubviews على العرض الذي يحتوي على إطار إطاره فقط إذا كان معلمة حجم الإطار مختلف
  • التمرير أسباب uiscrollview layoutSubviews أن يتم استدعاؤها على التمرير، ومظهرها
  • تدوير الجهاز يدعو فقطlayoutSubview على طريقة العرض الأصل (عرض الاستجابة ViewControllers الأساسي)
  • سيتم تغيير حجم الرأي layoutSubviews على superview.

نتائجي - http://blog.logichigh.com/2011/03/16/When-Does-layoutsubviews-get-called/

بناء على الإجابة السابقة من Badpadate، جربت بعض الشيء وتوصلت إلى بعض التوضيحات / التصحيحات. لقد وجدت أن layoutSubviews: سيتم استدعاء على طريقة عرض إذا وفقط إذا:

  • ملكه حدود (غير إطار) تغيرت.
  • تغيرت حدود أحد فرعيات فرعية مباشرة.
  • تتم إضافة نظرة فرعية إلى العرض أو إزالتها من العرض.

بعض التفاصيل ذات الصلة:

  • تعتبر الحدود متغيرة فقط إذا كانت القيمة الجديدة مختلفة، بما في ذلك أصل مختلف. وبعد ملاحظة على وجه التحديد لهذا السبب layoutSubviews: يتم استدعاء وقت الاختطاف uiscrollview، لأنه يؤدي التمرير عن طريق تغيير أصل حدوده.
  • سيؤدي تغيير الإطار إلى تغيير الحدود فقط إذا تغير الحجم، لأن هذا هو الشيء الوحيد الذي تم نشره إلى خاصية الحدود.
  • التغيير في حدود الرأي الذي ليس بعد التسلسل الهرمي لن يؤدي إلى دعوة إلى layoutSubviews: عندما يتم إضافة طريقة العرض في النهاية إلى التسلسل الهرمي.
  • وفقط الاكتمال: هذه المشغلات لا مباشرة استدعاء LayoutsubViews، ولكن دعوة setNeedsLayout, ، الذي يحدد / يثير العلم. كل تكرار من حلقة المدى، لجميع وجهات النظر في عرض التسلسل الهرمي, ، يتم فحص هذه العلامة. لكل عرض حيث تم العثور على العلم مرفوع، layoutSubviews: يسمى ذلك ويتم إعادة تعيين العلم. المشاهدات أعلى صعودا التسلسل الهرمي سيتم فحص / تسمى أولا.

https://developer.apple.com/library/prerelease/tvos/documentation/windowsviews/conceptual/viewpg_iphoneos/creatingviews/creatingviewsh.html#//apple_ref/doc/uid/tp40009503-ch5-sw1.

يمكن أن تحدث تغييرات التخطيط كلما حدث أي من الأحداث التالية في عرض:

أ. حجم تغييرات مستطيل الرأي.
ب. يحدث تغيير اتجاه واجهة، مما يؤدي عادة إلى تغيير في مستطيل حدود الرؤية الجذرية.
ج. مجموعة من الطبقات المتحركة الأساسية المرتبطة بتغييرات طبقة العرض وتتطلب تخطيط.
د. تخطيط قوات التطبيق الخاص بك تحدث عن طريق الاتصالsetNeedsLayoutأوlayoutIfNeededطريقة عرض.
ه. تخطيط قوات التطبيق الخاص بك عن طريق الاتصالsetNeedsLayoutطريقة كائن طبقة الرأي الأساسي.

بعض النقاط في عنادة الإجابة صحيح جزئيا فقط:

  1. بالنسبة addSubView نقطة

    addSubview يتسبب في تم استدعاء LayoutSubJviews على العرض الذي تمت إضافته، وتم إضافته إلى (عرض الهدف)، وجميع المجموعات الفرعية للهدف.

    ذلك يعتمد على قناع الرأي (عرض الهدف). إذا كان يحتوي على قناع تلقائي، فسيتم استدعاء LayoutsubView addSubview. وبعد إذا لم يكن لديه قناع التلقائي، فسيتم استدعاء LayoutsubView إلا عند تغيير حجم إطار العرض (عرض الهدف).

    مثال: إذا قمت بإنشاء Uiview برمجيا (لا يوجد لديه قناع تلقائي افتراضيا)، فسيتم استدعاء LayoutsubView عند تغييرات Uiview Frame على كل addSubview.

    من خلال هذه التقنية أن أداء التطبيق يزداد أيضا.

  2. لجهاز دوران الجهاز

    تدوير الجهاز لا يدعو فقط layoutsubView على طريقة العرض الأصل (عرض الاستجابة ViewController الأساسي)

    يمكن أن يكون هذا صحيحا فقط عندما يكون VC في التسلسل الهرمي VC (الجذر في window.rootViewController)، حسنا، هذه هي الحالة الأكثر شيوعا. في iOS 5، إذا قمت بإنشاء VC، ولكن لا تتم إضافته إلى أي VC آخر، فلن يحصل هذا VC على أي لاحظ عند تدوير الجهاز. لذلك لن يتم ملاحظة رأيها عن طريق استدعاء LayoutSubViews.

دعا[self.view setNeedsLayout]; في ViewController يجعلها لاستدعاء viewdidlayoutsubviews

هل نظرت إلى Layoutifneeded؟

مقتطف الوثائق أدناه. هل يعمل الرسوم المتحركة إذا استدعيت هذه الطريقة بشكل صريح أثناء الرسوم المتحركة؟

وضع LayOutifneeded وضع الفرعين الفرعيين إذا لزم الأمر.

- (void)layoutIfNeeded

استخدام المناقشة هذه الطريقة لإجبار تخطيط الفرعين الفرعيين قبل الرسم.

التوفر متوفر في iPhone OS 2.0 والإصدارات الأحدث.

عند ترحيل تطبيق OpenGL من SDK 3 إلى 4، لم يتم استدعاء LayoutsubViews بعد الآن. بعد الكثير من المحاكمة والخطأ فتح أخيرا Mainwindow.xib، حدد كائن النافذة، في علامة التبويب "المفتش" سمات نافذة "(أقصى اليسار) والحصى" المرئي في الإطلاق ". يبدو أنه في SDK 3، ما زالت تستخدم تسبب دعوة LayoutSubView، ولكن ليس في 4.

6 ساعات من الإحباط وضعت إلى نهايته.

غامضة إلى حد ما، ولكن من المحتمل أن تكون مهمة محتملة عندما layoutSubviews لا يسمى أبدا هو:

import UIKit

class View: UIView {

    override class var layerClass: AnyClass { return Layer.self }

    class Layer: CALayer {
        override func layoutSublayers() {
            // if we don't call super.layoutSublayers()...
            print(type(of: self), #function)
        }
    }

    override func layoutSubviews() {
        // ... this method never gets called by the OS!
        print(type(of: self), #function)
    }
}

let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top