দেখে মনে হচ্ছে আপনি যা চাইছেন তা ইউআইটিএল ভিউয়ের মতো লেআউট তৈরির জন্য ইউআইকোলিকেশনভিউ ব্যবহার করার একটি উপায়। যদি এটি সত্যই আপনি চান তবে এটি করার সঠিক উপায়টি হ'ল একটি কাস্টম ইউআইকোলিকেশনভিউলাউআউট সাবক্লাস (সম্ভবত এসবিটিবেলআউট এর মতো কিছু )।
অন্যদিকে, আপনি যদি সত্যিই জিজ্ঞাসা করে থাকেন যে ডিফল্ট ইউআইকোলিকেশনভিউফ্লোলোআউটটি দিয়ে এটি করার কোনও পরিষ্কার উপায় আছে, তবে আমি বিশ্বাস করি এর কোনও উপায় নেই। এমনকি আইওএস 8 এর স্ব-আকারের কোষগুলির সাথেও এটি সোজা নয়। মৌলিক সমস্যা, যেমন আপনি বলেছেন, প্রবাহের বিন্যাসের যন্ত্রপাতিটি একটি মাত্রা ঠিক করতে এবং অন্যটিকে প্রতিক্রিয়া জানাতে কোনও উপায় সরবরাহ করে না। (এছাড়াও, আপনি এটি করতে পারলেও, বহু-লাইন লেবেল আকার দিতে দুটি লেআউট পাসের প্রয়োজনের অতিরিক্ত জটিলতা থাকতে পারে L এটি স্বতঃ-সাইজিং কোষগুলি কীভাবে সিস্টেমলাউটসাইজফাইটিংসাইজে একটি কলের মাধ্যমে সমস্ত আকারের গণনা করতে চায় তার সাথে এটি খাপ খায় না))
তবে, আপনি যদি এখনও নিজের আকার নির্ধারণ করে এমন কোষগুলির সাথে প্রবাহের বিন্যাস সহ একটি টেবিলভিউ-জাতীয় লেআউট তৈরি করতে চান এবং সংগ্রহের দৃশ্যের প্রস্থে প্রাকৃতিকভাবে প্রতিক্রিয়া জানান তবে অবশ্যই এটি সম্ভব। অগোছালো উপায় এখনও আছে। আমি এটি একটি "সাইজিং সেল" দিয়ে করেছি, অর্থাত্, একটি অ-প্রদর্শিত ইউআইকোলিকেশনভিউসেল যা নিয়ামক কেবল ঘরের আকার নির্ধারণের জন্য রাখে।
এই পদ্ধতির দুটি অংশ রয়েছে। প্রথম অংশটি হ'ল সংগ্রহের প্রতিনিধিটির জন্য সংগ্রহের দৃশ্যের প্রস্থ গ্রহণ করে এবং সেলটির উচ্চতা গণনা করার জন্য সাইজিং সেলটি ব্যবহার করে সঠিক ঘর আকার গণনা করা।
আপনার ইউআইসিকলিকেশনভিউডেলিগেটফ্লোএলআউটে আপনি এই জাতীয় পদ্ধতি প্রয়োগ করেছেন:
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
// NOTE: here is where we say we want cells to use the width of the collection view
let requiredWidth = collectionView.bounds.size.width
// NOTE: here is where we ask our sizing cell to compute what height it needs
let targetSize = CGSize(width: requiredWidth, height: 0)
/// NOTE: populate the sizing cell's contents so it can compute accurately
self.sizingCell.label.text = items[indexPath.row]
let adequateSize = self.sizingCell.preferredLayoutSizeFittingSize(targetSize)
return adequateSize
}
এটি সংযুক্তি সংলগ্ন দৃশ্যের ভিত্তিতে ঘরের প্রস্থ সেট করার জন্য সংগ্রহের ভিউ তৈরি করবে, তবে তারপরে সাইজিং সেলটি উচ্চতা গণনা করতে বলবে।
দ্বিতীয় অংশটি হ'ল উচ্চতা গণনা করার জন্য সাইজ সেলটি তার নিজস্ব AL সীমাবদ্ধতাগুলি ব্যবহার করতে। এটি যতটা হওয়া উচিত তার চেয়ে কঠিন হতে পারে, কারণ একাধিক-লাইন ইউআইএলবেলের কার্যকরভাবে দ্বি-পর্যায়ে বিন্যাস প্রক্রিয়া প্রয়োজন। কাজটি পদ্ধতিতে করা হয় preferredLayoutSizeFittingSize
, যা এর মতো:
/*
Computes the size the cell will need to be to fit within targetSize.
targetSize should be used to pass in a width.
the returned size will have the same width, and the height which is
calculated by Auto Layout so that the contents of the cell (i.e., text in the label)
can fit within that width.
*/
func preferredLayoutSizeFittingSize(targetSize:CGSize) -> CGSize {
// save original frame and preferredMaxLayoutWidth
let originalFrame = self.frame
let originalPreferredMaxLayoutWidth = self.label.preferredMaxLayoutWidth
// assert: targetSize.width has the required width of the cell
// step1: set the cell.frame to use that width
var frame = self.frame
frame.size = targetSize
self.frame = frame
// step2: layout the cell
self.setNeedsLayout()
self.layoutIfNeeded()
self.label.preferredMaxLayoutWidth = self.label.bounds.size.width
// assert: the label's bounds and preferredMaxLayoutWidth are set to the width required by the cell's width
// step3: compute how tall the cell needs to be
// this causes the cell to compute the height it needs, which it does by asking the
// label what height it needs to wrap within its current bounds (which we just set).
let computedSize = self.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
// assert: computedSize has the needed height for the cell
// Apple: "Only consider the height for cells, because the contentView isn't anchored correctly sometimes."
let newSize = CGSize(width:targetSize.width,height:computedSize.height)
// restore old frame and preferredMaxLayoutWidth
self.frame = originalFrame
self.label.preferredMaxLayoutWidth = originalPreferredMaxLayoutWidth
return newSize
}
("অ্যাডভান্সড কালেকশন ভিউ" তে ডাব্লুডাব্লুডিসি2014 সেশনের নমুনা কোড থেকে এই কোডটি অ্যাপল স্যাম্পল কোড থেকে গৃহীত হয়েছে))
একটি দম্পতি লক্ষ্য করুন। লেবেলের প্রস্থটি গণনা করতে এবং সেট করার জন্য এটি পুরো ঘরটির বিন্যাসকে জোর করতে লেআউটআইফনেড () ব্যবহার করে। তবে এটি যথেষ্ট নয়। আমি বিশ্বাস করি আপনাকেও সেট করতে হবে preferredMaxLayoutWidth
যাতে লেবেলটি সেই প্রস্থটি অটো লেআউট সহ ব্যবহার করবে। এবং কেবলমাত্র তখনই systemLayoutSizeFittingSize
আপনি লেবেলটিকে অ্যাকাউন্টে নেওয়ার সময় ঘরের উচ্চতা গণনা করার জন্য ব্যবহার করতে পারেন ।
আমি কি এই পদ্ধতির পছন্দ করি? কোন !! এটি বেশ জটিল অনুভূত হয় এবং এটি দুইবার বিন্যাস করে। তবে যতক্ষণ না পারফরম্যান্স কোনও সমস্যা হয়ে ওঠে না, আমি কোডটিতে দু'বার সংজ্ঞা দেওয়ার চেয়ে রানটাইমের সময় দু'বার লেআউট সম্পাদন করতাম, যা কেবলমাত্র অন্য বিকল্প হিসাবে মনে হয়।
আমার আশা এই যে শেষ পর্যন্ত স্ব-আকারের কোষগুলি আলাদাভাবে কাজ করবে এবং এগুলি আরও অনেক সহজ পাবে।
উদাহরণস্বরূপ প্রকল্প এটি কাজ করে।
তবে কেন কেবল স্ব-আকারের কোষ ব্যবহার করবেন না?
তত্ত্ব অনুসারে, "স্ব-আকার দেওয়ার কোষগুলির" জন্য iOS8 এর নতুন সুবিধাগুলি এটিকে অপ্রয়োজনীয় করে তুলবে। আপনি যদি অটো লেআউট (AL) দিয়ে কোনও ঘর নির্ধারণ করেন তবে সংগ্রহের দৃশ্যটি এটির আকার দিতে এবং সঠিকভাবে নিজেকে আচ্ছাদন করতে যথেষ্ট স্মার্ট হওয়া উচিত। অনুশীলনে, আমি এমন কোনও উদাহরণ দেখিনি যা মাল্টি-লাইন লেবেলগুলির সাথে কাজ করার জন্য এটি অর্জন করেছে। আমি মনে করি এই আংশিক কারণ স্ব-নির্ধারন সেল প্রক্রিয়া এখনও বগী হয়।
তবে আমি বাজি ধরতে পারি এটি বেশিরভাগ কারণেই অটো লেআউট এবং লেবেলের স্বাভাবিক কৌতূহলের কারণেই ইউআইএলএবেলগুলির মূলত দ্বি-পদক্ষেপের বিন্যাস প্রক্রিয়া প্রয়োজন require আপনি কীভাবে স্ব-আকার দেওয়ার কক্ষগুলি দিয়ে উভয় পদক্ষেপটি সম্পাদন করতে পারবেন তা আমার কাছে পরিষ্কার নয়।
এবং যেমনটি আমি বলেছিলাম, এটি সত্যিই একটি ভিন্ন বিন্যাসের কাজ। এটি প্রবাহের বিন্যাসের মূল অংশ যা এটি একটি প্রস্থ স্থির করে এবং তাদের উচ্চতা চয়ন করতে দেয় তার চেয়ে একটি আকারযুক্ত জিনিসগুলিকে রাখে।
এবং পছন্দসই লেআউটআট্রিবিউটস ফিটিংঅ্যাট্রিবিউটস সম্পর্কে কী?
preferredLayoutAttributesFittingAttributes:
পদ্ধতি একটি লাল হেরিং, আমি মনে করি। এটি কেবলমাত্র নতুন স্ব-আকার দেওয়ার সেল প্রক্রিয়াটির সাথে ব্যবহৃত হবে। সুতরাং যতক্ষণ না যে প্রক্রিয়াটি অবিশ্বাস্য ততক্ষণ এটি উত্তর নয়।
এবং সিস্টেমলেআউটসাইজ ফিটিংসাইজে কী হবে :?
আপনি ঠিক বলেছেন ডক্স বিভ্রান্ত করছে।
উপর ডক্স systemLayoutSizeFittingSize:
এবং systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:
উভয় সুপারিশ আপনি শুধুমাত্র পাস করা উচিত UILayoutFittingCompressedSize
এবং UILayoutFittingExpandedSize
যেমন targetSize
। তবে, পদ্ধতিটির স্বাক্ষর নিজেই, শিরোনামের মন্তব্যসমূহ এবং ফাংশনগুলির আচরণ ইঙ্গিত দেয় যে তারা targetSize
প্যারামিটারের সঠিক মানটিতে প্রতিক্রিয়া জানাচ্ছে ।
প্রকৃতপক্ষে, আপনি যদি UICollectionViewFlowLayoutDelegate.estimatedItemSize
নতুন স্ব-সাইজিং সেল প্রক্রিয়াটি সক্ষম করতে, সেট করে থাকেন তবে সেই মানটি টার্গেটসাইজ হিসাবে পাস হবে বলে মনে হয়। এবং UILabel.systemLayoutSizeFittingSize
ঠিক একই মান হিসাবে প্রত্যাবর্তন বলে মনে হচ্ছে UILabel.sizeThatFits
। এটি সন্দেহজনক, প্রদত্ত যুক্তিটি systemLayoutSizeFittingSize
একটি মোটামুটি টার্গেট sizeThatFits:
বলে মনে করা হচ্ছে এবং যুক্তিটি সর্বোচ্চ সংক্ষিপ্ত আকারের বলে মনে করা হচ্ছে given
আরও সংস্থান
যদিও এমনটি ভাবতে দুঃখ হয় যে এই জাতীয় রুটিন প্রয়োজনে "গবেষণা সংস্থান" প্রয়োজন, আমি মনে করি এটি এটি করে। ভাল উদাহরণ এবং আলোচনা হ'ল: