লেআউটসুভিউগুলি কখন বলা হয়?


264

আমার একটি কাস্টম ভিউ রয়েছে যা layoutSubviewঅ্যানিমেশনের সময় বার্তা পাচ্ছে না ।

আমার একটি দৃষ্টিভঙ্গি রয়েছে যা স্ক্রিনটি পূর্ণ করে। স্ক্রিনের নীচে এটিতে একটি কাস্টম সাবভিউ রয়েছে যা আমি এনএভি বারের উচ্চতা পরিবর্তন করলে ইন্টারফেস বিল্ডারে সঠিকভাবে আকার পরিবর্তন করে। layoutSubviewsযখন ভিউ তৈরি করা হয় তখন বলা হয়, তবে আর কখনও হবে না। আমার সাবভিউগুলি সঠিকভাবে নির্ধারণ করা হয়েছে। যদি আমি ইন-কল স্থিতি বারটি টগল করি layoutSubviewsতবে মূল দৃষ্টিভঙ্গিটি তার আকার পরিবর্তন করতে সক্ষম হওয়া সত্ত্বেও সাবউভিউগুলিকে মোটেই কল করা হবে না।

layoutSubviewsআসলে কোন পরিস্থিতিতে বলা হয়?

আমি আমার কাস্টম ভিউয়ের জন্য autoresizesSubviewsসেট NOকরেছি। এবং ইন্টারফেস বিল্ডারে আমার উপরের এবং নীচের স্ট্রट्स এবং উল্লম্ব তীর সেট রয়েছে।


ধাঁধার আর একটি অংশ হ'ল উইন্ডোটি কী তৈরি করতে হবে:

[window makeKeyAndVisible];

অন্যথায় সংক্ষিপ্তসারগুলি স্বয়ংক্রিয়ভাবে পুনরায় আকার দেওয়া হয় না।

উত্তর:


492

আমারও অনুরূপ প্রশ্ন ছিল, তবে উত্তরটির সাথে সন্তুষ্ট ছিলাম না (বা নেট থেকে আমি খুঁজে পেতে পারি), তাই আমি এটি বাস্তবে চেষ্টা করেছিলাম এবং এখানে যা পেয়েছি তা এখানে:

  • initবলা হয় না layoutSubviews(duh)
  • addSubview:layoutSubviewsভিউ যুক্ত করার জন্য ডেকে আনার কারণ , এটিকে (টার্গেট ভিউ) যুক্ত করা হচ্ছে এবং লক্ষ্যটির সমস্ত উপদর্শন
  • ফ্রেমটির আকারের প্যারামিটারটি ভিন্ন হলে ভিউটি setFrame বুদ্ধিমানের layoutSubviewsসাথে দৃশ্যের ফ্রেম সেট করা কল করে
  • কোনও ইউআইএসক্রোলভিউ স্ক্রোলিংয়ের ফলে layoutSubviewsস্ক্রোলভিউ এবং তার তত্ত্বাবধানে কল করার কারণ রয়েছে
  • একটি ডিভাইস ঘোরানো কেবল layoutSubviewপ্যারেন্ট ভিউতে কল করে (প্রতিক্রিয়াশীল ভিউ নিয়ন্ত্রণকারীদের প্রাথমিক ভিউ)
  • একটি ভিউ layoutSubviewsপুনরায় আকার দেওয়া তার তত্ত্বাবধানে কল করবে

আমার ফলাফল - http://blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get-called/


1
দুর্দান্ত উত্তর। আমি সবসময় সম্পর্কে ভাবছি layoutSubviews। ডেকে আনার initWithFrame:কারণ কি layoutSubviews?
রবার্ট

2
@ রবার্ট - আমি initWithFrame ব্যবহার করছিলাম ... তাই না।
BadPirate

8
@BadPirate: হ্যাঁ । আমার পরীক্ষায় মতে, যদি আপনি মাপ পরিবর্তন view1.1এটা কল layoutSubviewsএর view1এবং তারপর layoutSubviewsএর view1.1। এই কলটি তদারকি দর্শকদের কাছে অনির্দিষ্টকালের জন্য প্রচার করে না, view1.1.1কেবলমাত্র কল এবং এ কল layoutSubviewsকরে । এটির আকার পরিবর্তন না করে কেবল চলন তাদের কোনওটির জন্যই ডাকে না । view1.1view1.1.1layoutSubviews
জোও পোর্তেলা

1
ভিভিডিডলড ইউআইভিউতে (তবে ইউআইভিউকন্ট্রোলার) ডাকা হয় না। ইউআইভিউ'র সূচনা করার পরে ডিড লোড কল হবে।
BadPirate

2
আমার পরীক্ষা উপর ভিত্তি করে, দ্বিতীয় নিয়ম সঠিক নাও হতে পারে: যখন আমি যোগ view1.2মধ্যে view1, layoutSubviewsএর view1.2এবং view1বলা হয়, কিন্তু layoutSubviewsএর view1.1বলা হয় না। ( view1.1এবং view1.2এর সংক্ষিপ্তসারগুলি view1)। এটি হ'ল, লক্ষ্য দর্শনের সমস্ত পূর্বরূপগুলিকে layoutSubviewsপদ্ধতি বলা হয় না
হংকচাওজ্যাং 10

96

@ ব্যাডপাইরেটের পূর্ববর্তী উত্তরের ভিত্তিতে আমি আরও কিছুটা পরীক্ষা-নিরীক্ষা করে কিছু ব্যাখ্যা / সংশোধন নিয়ে এসেছি। আমি খুঁজে পেয়েছি যে layoutSubviews:একটি দৃশ্যে কল করা হবে যদি এবং শুধুমাত্র যদি:

  • এর নিজস্ব সীমানা (ফ্রেম নয়) পরিবর্তিত হয়েছে।
  • এর প্রত্যক্ষ প্রত্যক্ষদর্শনগুলির একটির সীমানা পরিবর্তন হয়েছে।
  • একটি সাবভিউ ভিউতে যুক্ত করা হয় বা ভিউ থেকে সরানো হয়।

কিছু প্রাসঙ্গিক বিবরণ:

  • নতুন মানটি ভিন্ন ভিন্ন সহ , কেবলমাত্র সীমাগুলি পরিবর্তন হিসাবে বিবেচিত হবে । বিশেষভাবে নোট করুন কেন layoutSubviews:তাই যখনই কোনও ইউআইএসক্রোলভিউ স্ক্রোলগুলি বলা হয়, কারণ এটি তার সীমানার উত্স পরিবর্তন করে স্ক্রোলিং সম্পাদন করে।
  • ফ্রেম পরিবর্তন করা হলে আকার পরিবর্তন হয়ে গেলে কেবল সীমানাগুলি পরিবর্তন হবে, কারণ এটিই কেবল সীমানা সম্পত্তিতে প্রচারিত।
  • দৃশ্য দেখার শ্রেণিবদ্ধে এখনও নেই এমন একটি দৃশ্যের সীমার পরিবর্তনের ফলে layoutSubviews: যখন ভিউটি হায়ারার্কিতে অবশেষে ভিউটি যুক্ত হয় তখন তার কল আসবে ।
  • এবং কেবল সম্পূর্ণতার জন্য: এই ট্রিগারগুলি সরাসরি লেআউটসুভিউগুলিকে কল করে না , বরং কল দেয় setNeedsLayoutযা একটি পতাকা সেট করে / উত্থাপন করে। রান লুপের প্রতিটি পুনরাবৃত্তি, ভিউ হায়ারার্কিতে সমস্ত দর্শনর জন্য , এই পতাকাটি চেক করা আছে। প্রতিটি দর্শনের জন্য যেখানে পতাকাটি উত্থাপিত পাওয়া যায়, layoutSubviews:সেখানে ডাকে এবং পতাকাটি পুনরায় সেট করা হয়। শ্রেনীর উচ্চতর দৃশ্যগুলি প্রথমে চেক / কল করা হবে।

5
এই উত্তর যথেষ্ট upvote করতে পারবেন না। এটি শীর্ষ উত্তর হওয়া উচিত। প্রদত্ত তিনটি বিধি আপনার প্রয়োজন। এই নিয়মগুলি নিখুঁতভাবে বর্ণনা না করে এমন কোনও লেআউটসুবিউর আচরণের মধ্যে আমি কখনও আসিনি।
পার্সার্ক

1
আমি মনে করি না যে যখন প্রত্যক্ষ সাবউভিউয়ের সীমা পরিবর্তন করা হয় তখন লেআউটসুভিউগুলি বলা হয়। আমি মনে করি লেআউটসুভিউগুলি কল করা আপনার পরীক্ষার কেবলমাত্র একটি পার্শ্ব প্রতিক্রিয়া। কিছু ক্ষেত্রে যখন একটি সংক্ষিপ্তসার সীমা পরিবর্তন হয় তখন লেআউটসুভিউগুলি কল হবে না। দয়া করে ব্যাঙের উত্তরটি পরীক্ষা করুন, কারণ তার আনসার কেবল পরীক্ষার পরিবর্তে অ্যাপলের ডকুমেন্টেশনের উপর ভিত্তি করে।
সাইমন ব্যাকেক্স

19

https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1

নিচের পরিবর্তনগুলি ঘটতে পারে যখনই নীচের যেকোন ঘটনা ঘটতে দেখা যায়:

ক। একটি দৃশ্যের সীমা আয়তক্ষেত্রের আকার পরিবর্তন হয়।
খ। একটি ইন্টারফেস ওরিয়েন্টেশন পরিবর্তন ঘটে, যা সাধারণত রুট ভিউয়ের সীমানা আয়তক্ষেত্রের পরিবর্তনকে ট্রিগার করে।
গ। ভিউটির স্তরটির সাথে যুক্ত কোর অ্যানিমেশন সাবলেয়ার্সের সেট পরিবর্তিত হয় এবং লেআউট প্রয়োজন।
ঘ। আপনার অ্যাপ্লিকেশনটি  ভিউ setNeedsLayout বা  layoutIfNeededপদ্ধতিতে কল করে লেআউটটিকে ঘটতে বাধ্য করে  ।
ঙ। আপনার অ্যাপ্লিকেশনটি setNeedsLayout ভিউটির অন্তর্নিহিত স্তর অবজেক্টের পদ্ধতিতে কল করে লেআউটটিকে জোর করে  ।


এছাড়াও, উল্লেখ করার জন্য গুরুত্বপূর্ণ এটি হ'ল যখন ভিউ স্ট্যাকটিতে দৃশ্যটি যুক্ত করা হয়নি তখন events ইভেন্টগুলির কোনওটিই ডাকা হয় না। আপনি এটি "ক্যান" শব্দটির সাথে অন্তর্ভুক্ত করেন তবে বিশেষত এটিকে অ্যাপ্লিকেশনটির মূল থ্রেডের পরবর্তী উপলব্ধ চক্রে বলা হয় যখন এই ইভেন্টগুলির মধ্যে একটির দ্বারা এটির প্রয়োজনের লেআউট হিসাবে চিহ্নিত করা হয়।
ব্যবহারকারী1122069

13

ব্যাডপ্রেটারের উত্তরের কয়েকটি পয়েন্ট কেবল আংশিকভাবে সত্য:

  1. জন্য addSubViewবিন্দু

    addSubview লেআউটসুভিউগুলিকে ভিউটি যুক্ত করার জন্য ডেকে আনে, এটির লক্ষ্য (টার্গেট ভিউ) যুক্ত করা হচ্ছে এবং লক্ষ্যটির সমস্ত সাবভিউ দেখায় causes

    এটি ভিউ (টার্গেট ভিউ) অটোরসাইজ মাস্কের উপর নির্ভর করে। যদি এতে অটোরেসাইজ মাস্ক অন থাকে তবে প্রতিটিটিতে লেআউটসুভিউ কল করা হবে addSubview। যদি এতে অটোরেসাইজ মাস্ক না থাকে তবে লেআউটসুউভিউ কেবল তখনই বলা হবে যখন ভিউ (টার্গেট ভিউ) ফ্রেমের আকার পরিবর্তন হবে।

    উদাহরণ: আপনি যদি ইউআইভিউ প্রোগ্রামক্রমেটিকভাবে তৈরি করেন (এটির ডিফল্টরূপে কোনও স্বয়ংক্রিয় আকারের মুখোশ নেই), লেআউটসউভিউ কেবল তখনই বলা হবে যখন ইউআইভিউ ফ্রেমের প্রতিটিতে পরিবর্তন হয় না addSubview

    এই কৌশলটির মাধ্যমেই অ্যাপ্লিকেশনটির কার্যকারিতাও বৃদ্ধি পায়।

  2. ডিভাইস রোটেশন পয়েন্ট জন্য

    কোনও ডিভাইস ঘোরানো কেবল প্যারেন্ট ভিউতে লেআউটসউভিউকে কল করে (প্রতিক্রিয়াশীল ভিউ কনট্রোলারের প্রাথমিক ভিউ)

    এটি তখনই সত্য হতে পারে যখন আপনার ভিসি ভিসি হায়ারার্কিতে থাকে (রুট এট window.rootViewController), ভাল এটি সবচেয়ে সাধারণ ক্ষেত্রে। আইওএস 5-এ, আপনি যদি ভিসি তৈরি করেন তবে এটি অন্য কোনও ভিসিতে যুক্ত না করা হয়, তবে ডিভাইসটি ঘোরার সময় এই ভিসি কোনও নজরে আসবে না। সুতরাং লেআউটসুভিউগুলিতে কল করে এর ভিউটি নজরে আসবে না।


9

আমি ইন্টারফেস বিল্ডারের জেদ থেকে সমাধানটি সন্ধান করেছি যে সিমুলেটেড স্ক্রিন উপাদানগুলি (স্ট্যাটাস বার, ইত্যাদি) চালু করা হয়েছে এমন দৃশ্যে স্প্রিংস পরিবর্তন করা যাবে না। যেহেতু স্প্রিংস মূল দর্শনটির জন্য বন্ধ ছিল তাই সেই দর্শনটি আকার পরিবর্তন করতে পারেনি এবং তাই ইন-কল বারটি উপস্থিত হওয়ার কারণে এটি সম্পূর্ণরূপে স্ক্রোল হয়ে যায়।

সিমুলেটেড বৈশিষ্ট্যগুলি বন্ধ করে দেওয়া, তারপরে দৃশ্যটির আকার পরিবর্তন করে এবং স্প্রিংসটি সঠিকভাবে সেট করার কারণে অ্যানিমেশনটি ঘটেছিল এবং আমার পদ্ধতিটি কল হতে পারে।

এটি ডিবাগ করার ক্ষেত্রে একটি অতিরিক্ত সমস্যা হ'ল মেনুটির মাধ্যমে ইন-কল স্থিতি টগল করা অবস্থায় সিমুলেটর অ্যাপটি ছাড়ায়। প্রস্থান করুন অ্যাপ = কোনও ডিবাগার নেই।


আপনি কি বলছেন যে ভিউটি পুনরায় আকার দেওয়া হলে লেআউটসুভিউগুলি বলা হয়? আমি সবসময় ধরে
নিয়েছিলাম

এইটা. যখন কোন দৃশ্যের আকার পরিবর্তন করা হয় তখন এর সংক্ষিপ্তসারগুলি সহ কিছু করা দরকার। আপনি যদি এটি সরবরাহ না করেন তবে ঝর্ণা, স্ট্রটস ইত্যাদি ব্যবহার করে এটি স্বয়ংক্রিয়ভাবে তাদেরকে সরিয়ে দেয়
স্টিভ ওয়েলার

8

কলিং [self.view setNeedsLayout]; viewController কল viewDidLayoutSubviews তা তোলে


5

আপনি কি লেআউটটি দেখেছেন?

ডকুমেন্টেশন স্নিপেট নীচে। অ্যানিমেশন চলাকালীন আপনি যদি এই পদ্ধতিটি স্পষ্টভাবে কল করেন তবে অ্যানিমেশনটি কী কাজ করবে?

বিন্যাস যদি প্রয়োজন হয় তবে সাবউভিউগুলি রাখে।

- (void)layoutIfNeeded

আলোচনা অঙ্কনের আগে সাবউভিউগুলির বিন্যাসকে জোর করতে এই পদ্ধতিটি ব্যবহার করুন।

আইফোন ওএস ২.০ এবং তারপরে উপলভ্যতা উপলব্ধ।


2

এসডিকে 3 থেকে 4 এ কোনও ওপেনলএল অ্যাপ্লিকেশন স্থানান্তরিত করার সময়, লেআউটসুভিউগুলি আর কল করা হয়নি। অনেকগুলি পরীক্ষার এবং ত্রুটির পরে অবশেষে আমি মাইনউইন্ডো.এক্সিব খুললাম, উইন্ডো অবজেক্টটি নির্বাচন করেছি, পরিদর্শক উইন্ডো বৈশিষ্ট্য ট্যাবটি বেছে নিয়েছেন (বামদিকে) এবং "লঞ্চে দৃশ্যমান" পরীক্ষা করেছেন। দেখে মনে হয় যে এসডিকে 3-তে এটি এখনও একটি লেআউটসউভিউস কলের কারণ হিসাবে ব্যবহৃত হয়েছিল, তবে 4-এ নয়।

হতাশা 6 ঘন্টা অবসান।


আপনি কি উইন্ডো কী তৈরি করেছেন? যদি তা না হয় তবে এটি সমস্ত ধরণের আকর্ষণীয় জিনিস ঘটতে পারে না।
স্টিভ ওয়েলার

-2

একটি অস্পষ্ট, তবুও সম্ভাব্য গুরুত্বপূর্ণ ক্ষেত্রে যখন 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))

1
এই উত্তর এখানে কেন?
ডোমিনিক বুচার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.