অটো লেআউট ব্যবহার করে ইউআইকোলিকেশনভিউতে কক্ষগুলির একটি মাত্রা নির্দিষ্ট করে


113

আইওএস 8- UICollectionViewFlowLayoutএ তাদের নিজস্ব সামগ্রীর আকারের ভিত্তিতে সেলগুলি স্বয়ংক্রিয়ভাবে আকার পরিবর্তন করতে সহায়তা করে। এটি তাদের বিষয়বস্তু অনুসারে প্রস্থ এবং উচ্চতা উভয় ক্ষেত্রেই ঘরগুলিকে পুনরায় আকার দেয়।

সমস্ত কক্ষের প্রস্থ (বা উচ্চতা) এর জন্য একটি নির্দিষ্ট মান নির্দিষ্ট করা এবং অন্যান্য মাত্রাগুলি পুনরায় আকার দেওয়ার অনুমতি দেওয়া কি সম্ভব?

একটি সাধারণ উদাহরণের জন্য একটি ঘরের একপাশে একাধিক-লাইন লেবেলকে সীমাবদ্ধ করে এটি ঘরের পাশের দিকগুলিতে বিবেচনা করুন। মাল্টি-লাইনের লেবেলটি পাঠ্যকে সংযুক্ত করার জন্য বিভিন্নভাবে পুনরায় আকার দেওয়া যেতে পারে। কক্ষটি সংগ্রহের প্রস্থের প্রস্থটি পূরণ করতে হবে এবং সেই অনুযায়ী তার উচ্চতা সামঞ্জস্য করতে হবে। পরিবর্তে, ঘরগুলি অলস আকারের আকারের হয় এবং এমনকি কোষের আকার সংগ্রহের দৃশ্যের অ-স্ক্রোলযোগ্য মাত্রার চেয়ে বড় হয়ে গেলে এটি ক্র্যাশ ঘটায়।


আইওএস 8 systemLayoutSizeFittingSize: withHorizontalFittingPriority: verticalFittingPriority:সংগ্রহটির প্রতিটি কক্ষের জন্য পদ্ধতিটি উপস্থাপন করে দেখুন লেআউটটি আনুমানিক আকারে পাস করে এই পদ্ধতিটি সেলটিতে কল করে। আমার কাছে কী বোঝাতে হবে তা হ'ল এই পদ্ধতিটি সেলটিতে ওভাররাইড করা, যে আকার দেওয়া হয়েছে তা পাস করে প্রয়োজনীয় অনুভূমিক সীমাবদ্ধতা এবং উল্লম্ব সীমাবদ্ধতার জন্য কম অগ্রাধিকার স্থাপন করা। এইভাবে অনুভূমিক আকারটি লেআউটে মান সেটকে স্থির করা হয়েছে এবং উল্লম্ব আকারটি নমনীয় হতে পারে।

এটার মতো কিছু:

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    UICollectionViewLayoutAttributes *attributes = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
    attributes.size = [self systemLayoutSizeFittingSize:layoutAttributes.size withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityFittingSizeLevel];
    return attributes;
}

এই পদ্ধতির দ্বারা প্রদত্ত মাপগুলি সম্পূর্ণ অদ্ভুত। এই পদ্ধতির ডকুমেন্টেশনটি আমার কাছে খুব অস্পষ্ট এবং ধ্রুবকগুলি ব্যবহার করে উল্লেখ করেছে UILayoutFittingCompressedSize UILayoutFittingExpandedSizeযা কেবল একটি শূন্য আকার এবং একটি দুর্দান্ত বৃহতকে উপস্থাপন করে।

sizeএই পদ্ধতির প্যারামিটারটি কি সত্যিই কেবল দুটি ধ্রুবকগুলিতে যাওয়ার একটি উপায়? প্রদত্ত আকারের জন্য উপযুক্ত উচ্চতা পাওয়ার জন্য যে আচরণটি আশা করি তা অর্জনের কোনও উপায় নেই?


বিকল্প সমাধান

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

2) একটি টেবিল ভিউ ব্যবহার করুন। সারণি দর্শনগুলি বাক্সের বাইরে এইভাবে কাজ করে কারণ ঘরগুলির একটি নির্দিষ্ট প্রস্থ থাকে তবে এটি একাধিক কলামে স্থির প্রস্থের কক্ষগুলি সহ একটি আইপ্যাড লেআউটের মতো অন্যান্য পরিস্থিতিগুলিকে সামঞ্জস্য করে না।

উত্তর:


135

দেখে মনে হচ্ছে আপনি যা চাইছেন তা ইউআইটিএল ভিউয়ের মতো লেআউট তৈরির জন্য ইউআইকোলিকেশনভিউ ব্যবহার করার একটি উপায়। যদি এটি সত্যই আপনি চান তবে এটি করার সঠিক উপায়টি হ'ল একটি কাস্টম ইউআইকোলিকেশনভিউলাউআউট সাবক্লাস (সম্ভবত এসবিটিবেলআউট এর মতো কিছু )।

অন্যদিকে, আপনি যদি সত্যিই জিজ্ঞাসা করে থাকেন যে ডিফল্ট ইউআইকোলিকেশনভিউফ্লোলোআউটটি দিয়ে এটি করার কোনও পরিষ্কার উপায় আছে, তবে আমি বিশ্বাস করি এর কোনও উপায় নেই। এমনকি আইওএস 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

আরও সংস্থান

যদিও এমনটি ভাবতে দুঃখ হয় যে এই জাতীয় রুটিন প্রয়োজনে "গবেষণা সংস্থান" প্রয়োজন, আমি মনে করি এটি এটি করে। ভাল উদাহরণ এবং আলোচনা হ'ল:


আপনি কেন ফ্রেমটিকে পুরানো ফ্রেমের কাছে সেট করলেন?
vrwim

আমি এটি করি তাই ফাংশনটি কেবলমাত্র আপনি যে ভিউটিতে বলেছেন তার বিন্যাসের অবস্থাকে প্রভাবিত না করেই কেবলমাত্র ভিউর পছন্দসই বিন্যাসের আকার নির্ধারণ করতে ব্যবহার করা যেতে পারে ract ব্যবহারিকভাবে, আপনি যদি কেবলমাত্র এই উদ্দেশ্যে দেখেন তবে এই অপ্রাসঙ্গিক is বিন্যাস গণনা করা। এছাড়াও, আমি এখানে যা করি তা অপর্যাপ্ত। একমাত্র ফ্রেমটি পুনরুদ্ধার করা সত্যিই এটি আগের অবস্থাতে পুনরুদ্ধার করে না, যেহেতু সম্পাদনা বিন্যাসটি সাবউভিউগুলির লেআউটকে সংশোধন করতে পারে।
অ্যালগাল

1
এটি এমন কোনও কিছুর জন্য এমন গোলযোগ যা আইওএস 6-এর পর থেকে লোকেরা করে আসছে। অ্যাপল সর্বদা কোনও না কোনও উপায় নিয়ে বেরিয়ে আসে তবে এটি কখনও সঠিক নয়।
গ্রেগপ

1
আপনি ম্যানুয়ালি আকারে সাইজিং সেলটি ভিডডিলোডে ইনস্ট্যান্ট করতে পারেন এবং এটিতে একটি কাস্টম সম্পত্তি দেখুন। এটি কেবলমাত্র একটি ঘর যাতে এটি সস্তা। যেহেতু আপনি এটি কেবল আকারের জন্য ব্যবহার করছেন এবং আপনি এটির সাথে সমস্ত মিথস্ক্রিয়া পরিচালনা করছেন তাই এটি সংগ্রহের ভিউর ঘর পুনরায় ব্যবহারের পদ্ধতিতে অংশ নেওয়ার দরকার নেই, তাই আপনাকে সংগ্রহ ভিউ থেকে নিজেই এটি পাওয়ার দরকার নেই।
অ্যালগাল

1
পৃথিবীতে কীভাবে স্ব-আকারের কোষগুলি এখনও ভেঙে যেতে পারে ?!
রূবেন স্ক্র্যাটন

50

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

1. নিম্নলিখিত ফ্লো লেআউট সাবক্লাস তৈরি করুন

class HorizontallyFlushCollectionViewFlowLayout: UICollectionViewFlowLayout {

    // Don't forget to use this class in your storyboard (or code, .xib etc)

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
        let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)?.copy() as? UICollectionViewLayoutAttributes
        guard let collectionView = collectionView else { return attributes }
        attributes?.bounds.size.width = collectionView.bounds.width - sectionInset.left - sectionInset.right
        return attributes
    }

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let allAttributes = super.layoutAttributesForElementsInRect(rect)
        return allAttributes?.flatMap { attributes in
            switch attributes.representedElementCategory {
            case .Cell: return layoutAttributesForItemAtIndexPath(attributes.indexPath)
            default: return attributes
            }
        }
    }
}

2. স্বয়ংক্রিয় আকার দেওয়ার জন্য আপনার সংগ্রহ দর্শনটি নিবন্ধ করুন

// The provided size should be a plausible estimate of the actual
// size. You can set your item size in your storyboard
// to a good estimate and use the code below. Otherwise,
// you can provide it manually too, e.g. CGSize(width: 100, height: 100)

flowLayout.estimatedItemSize = flowLayout.itemSize

৩. আপনার ঘরের সাবক্লাসে পূর্বনির্ধারিত প্রস্থ + কাস্টম উচ্চতা ব্যবহার করুন

override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    layoutAttributes.bounds.size.height = systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
    return layoutAttributes
}

8
স্ব-আকার দেওয়ার বিষয়ে আমি এটি খুঁজে পেয়েছি। আপনাকে জর্ডান ধন্যবাদ!
haik.ampardjian

1
এটি আইওএস এ কাজ করতে পারে না (9.3)। 10 এ এটি সূক্ষ্ম কাজ করে। অ্যাপ্লিকেশনটি _আপডেটভিজিবলকেলস (অসীম পুনরাবৃত্তি?) এ ক্র্যাশ হয়ে গেছে। openradar.me/25303115
cristiano2lopes

@ ক্রিশ্চিয়ানো 2lopes এটি আইওএস 9.3 এ আমার পক্ষে ভাল কাজ করে। আপনি একটি যুক্তিসঙ্গত প্রাক্কলন সরবরাহ করছেন কিনা তা নিশ্চিত করুন এবং সঠিক আকারে সমাধানের জন্য আপনার ঘরের সীমাবদ্ধতাগুলি সেট আপ হয়েছে কিনা তা নিশ্চিত করুন।
জর্ডান স্মিথ

এটি আশ্চর্যজনক কাজ করে। আমি এক্সকোড 8 ব্যবহার করছি এবং আইওএস 9.3.3 (শারীরিক ডিভাইস) এ পরীক্ষা করেছি এবং এটি ক্রাশ হয় না! দুর্দান্ত কাজ করে। আপনার অনুমানটি ঠিক আছে তা নিশ্চিত করুন!
হামলা হয়েছে

1
@ জোর্দানস্মিথ এটি আইওএস ১০ এ কাজ করছে না। আপনার কি কোনও নমুনা ডেমো আছে? আমি এর সামগ্রীর উপর ভিত্তি করে কক্ষ সংগ্রহের উচ্চতা সংগ্রহ করার জন্য অনেক কিছুই চেষ্টা করেছি তবে কিছুই নয়। আমি আইওএস 10 এ অটো লেআউটটি ব্যবহার করছি এবং দ্রুত 3 ব্যবহার করছি
একতা পাদালিয়া

6

কোডের কয়েকটি লাইনে আইওএস 9 এ এটি করার একটি সহজ উপায় - অনুভূমিক উপায় উদাহরণস্বরূপ (এর সংগ্রহটি দেখার উচ্চতায় এর উচ্চতা স্থির করে):

estimatedItemSizeস্ব-আকারের সেলটি সক্ষম করতে আপনার সংগ্রহ দেখুন ফ্লো লেআউটটি শুরু করুন :

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.estimatedItemSize = CGSizeMake(1, 1);

কালেকশন ভিউ লেআউট ডেলিগেটটি প্রয়োগ করুন (বেশিরভাগ সময় আপনার ভিউ কন্ট্রোলারে) collectionView:layout:sizeForItemAtIndexPath:,। সংগ্রহটি লক্ষ্য মাত্রায় স্থির উচ্চতা (বা প্রস্থ) সেট করা এখানে লক্ষ্য। 10 মানটি যে কোনও হতে পারে, তবে আপনার এটি এমন কোনও মানতে সেট করা উচিত যা সীমাবদ্ধতাগুলি ভঙ্গ করবে না:

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return CGSizeMake(10, CGRectGetHeight(collectionView.bounds));
}

আপনার কাস্টম সেল preferredLayoutAttributesFittingAttributes:পদ্ধতিটিকে ওভাররাইড করুন , এই অংশটি আপনার অটো লেআউট সীমাবদ্ধতা এবং আপনি যে উচ্চতাটি সবেমাত্র সেট করেছেন তার উপর ভিত্তি করে আপনার গতিশীল কক্ষের প্রস্থটি গণনা করে:

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
    UICollectionViewLayoutAttributes *attributes = [layoutAttributes copy];
    float desiredWidth = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].width;
    CGRect frame = attributes.frame;
    frame.size.width = desiredWidth;
    attributes.frame = frame;
    return attributes;
}

আপনি কি জানেন যে আইওএস 9-তে এই সহজ পদ্ধতিটি সঠিকভাবে কাজ করে যখন সেলটিতে একটি বহু-লাইন থাকে UILabel, যার লাইন-ব্রেকিং কোষের অভ্যন্তরীণ উচ্চতাকে প্রভাবিত করে? এটি এমন একটি সাধারণ কেস যা আমার বর্ণনা করা সমস্ত ব্যাকফ্লিপগুলির প্রয়োজন হত। আমি ভাবছি আমার উত্তর থেকে আইওএস এটি স্থির করেছে কিনা।
অ্যালগাল

2
@ এলগাল দুঃখজনকভাবে, উত্তরটি হ'ল না।
জামেস্ক

4

পছন্দসই লেআউট বৈশিষ্ট্যে আপনার প্রস্থকে ঠিক করার চেষ্টা করুন:

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    UICollectionViewLayoutAttributes *attributes = [[super preferredLayoutAttributesFittingAttributes:layoutAttributes] copy];
    CGSize newSize = [self systemLayoutSizeFittingSize:CGSizeMake(FIXED_WIDTH,layoutAttributes.size) withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityFittingSizeLevel];
    CGRect newFrame = attr.frame;
    newFrame.size.height = size.height;
    attr.frame = newFrame;
    return attr;
}

স্বাভাবিকভাবেই আপনি নিশ্চিত করতে চান যে আপনি নিজের বিন্যাসটি সঠিকভাবে সেটআপ করেছেন:

UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *) self.collectionView.collectionViewLayout;
flowLayout.estimatedItemSize = CGSizeMake(FIXED_WIDTH, estimatedHeight)];

এখানে আমি রাখি এমন কিছু যা ধ্রুবক প্রস্থের ঘরগুলি ব্যবহার করে এবং গতিশীল প্রকারকে সমর্থন করে যাতে সিস্টেমের ফন্টের আকার পরিবর্তনের সাথে সাথে ঘরের উচ্চতা আপডেট হয়।


এই স্নিপেটে আপনি সিস্টেমলআউটসাইজ ফিটিংসাইজ কল করুন:। আপনি কোথাও পছন্দসইম্যাক্স লেআউটউইথ সেট না করে এটিকে কাজ করতে সক্ষম হয়েছেন? আমার অভিজ্ঞতায়, আপনি যদি পছন্দসইম্যাক্স লেআউটউইথকেই সেট না করে থাকেন তবে আপনার অতিরিক্ত ম্যানুয়াল লেআউটটি করা দরকার, যেমন আকারের ওভাররাইড করেThatFits: অন্য কোথাও সংজ্ঞায়িত স্বয়ংক্রিয় বিন্যাসের সীমাবদ্ধতার যুক্তিকে পুনরুত্পাদনকারী গণনা সহ।
অ্যালগাল

@ এলগাল পছন্দসই ম্যাক্সলাউটউইথ ইউআইএলবেলের কোনও সম্পত্তি? কীভাবে প্রাসঙ্গিক তা পুরোপুরি নিশ্চিত নন?
ড্যানিয়েল গালাস্কো

ওহো! ভাল কথা, তাই না! আমি কখনই এটি কোনও ইউআইটিেক্সটভিউ দিয়ে পরিচালনা করি নি, তাই বুঝতে পারিনি যে তাদের API গুলি সেখানে আলাদা fe UITextView.sisstmLayoutSizeFittingSize এর ফ্রেমটিকে শ্রদ্ধার সাথে দেখায় যেহেতু এর কোনও অন্তর্নিবিজ্ঞতা নেই। তবে ইউআইআইএলবেল.সিসটেমলআউটসাইজ ফিটিংসাইজ ফ্রেমটিকে উপেক্ষা করে, যেমন এটির একটি অন্তর্নিহিত কনসেন্টসাইজ রয়েছে, তাই পছন্দের ম্যাক্স লেআউটউইথটি তার মোড়কানো উচ্চতাটি আ.লীগের কাছে প্রকাশ করার জন্য অন্তর্নিবিজ্ঞান পেতে প্রয়োজন। এখনও ইউআইটিেক্সটভিউয়ের মতো দুটি পাস বা ম্যানুয়াল লেআউটের প্রয়োজন হবে বলে মনে হচ্ছে, তবে আমি মনে করি না যে আমি এটি পুরোপুরি বুঝতে পেরেছি।
অ্যালগাল

@ অ্যালগাল আমি সম্মত হতে পারি, ইউআইএলবেল ব্যবহার করার সময় আমি কিছু লোমশ ছিনতাইয়ের অভিজ্ঞতাও পেয়েছি। সেটিংস এর পছন্দসই প্রস্থটি সমস্যার সমাধান করে তবে আরও বেশি গতিশীল পন্থা থাকা ভাল হবে কারণ এই প্রস্থটির তত্ত্বাবধানের সাথে স্কেল করা দরকার। আমার বেশিরভাগ প্রকল্প পছন্দসই সম্পত্তি ব্যবহার করে না, আমি সাধারণত তা দ্রুত সমাধান হিসাবে ব্যবহার করি কারণ সবসময় আরও গভীর সমস্যা থাকে
ড্যানিয়েল গালাসকো

0

হ্যাঁ প্রোগ্রামটিমেটিকভাবে অটো লেআউটটি ব্যবহার করে এবং স্টোরিবোর্ড বা এক্সিবায় সীমাবদ্ধতা সেট করে এটি করা যেতে পারে। স্থির থাকতে এবং প্রস্থের চেয়ে বড় বা সমান উচ্চতা নির্ধারণ করতে আপনাকে প্রস্থের আকার বাড়াতে হবে।
http://www.thinkandbuild.it/learn-to-love-auto-layout-programmatic//

http://www.cocoanetics.com/2013/08/variable-sized-items-in-uicollectionview/
আশা করি এটি হবে সহায়ক এবং আপনার সমস্যা সমাধান করুন।


3
এটি একটি নিখুঁত প্রস্থের মানের জন্য কাজ করা উচিত তবে আপনি যে ক্ষেত্রে সেলটি সর্বদা সংগ্রহের দৃশ্যের পুরো প্রস্থ হয়ে থাকতে চান তা কাজ করবে না।
মাইকেল জলপ্রপাত 23

@ মিশেলওয়াটারফল আমি অটোলাউট ব্যবহার করে এটি পুরো প্রস্থের সাথে কাজ করার ব্যবস্থা করেছিলাম। আমি আমার কক্ষের কন্টেন্ট ভিউতে প্রস্থের সীমাবদ্ধতা যুক্ত করেছি। তারপর cellForItemAtIndexPathবাধ্যতা আপডেট করুন: cell.constraintItemWidth.constant = UIScreen.main.bounds.width। আমার অ্যাপ্লিকেশনটি কেবল পোর্টেইট। reloadDataসীমাবদ্ধতা আপডেট করার জন্য আপনি সম্ভবত ওরিয়েন্টেশন পরিবর্তনের পরে চান ।
ফ্লিটসিকিকার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.