ডায়নামিক সেল লেআউট এবং ভেরিয়েবল সারি উচ্চতার জন্য ইউআইটিএবলভিউতে অটো লেআউট ব্যবহার করা


1501

UITableViewCellমসৃণ স্ক্রোলিং কার্যকারিতা বজায় রেখে প্রতিটি ঘরের সামগ্রী এবং সংক্ষিপ্তসারগুলি সারির উচ্চতা (নিজেই / স্বয়ংক্রিয়ভাবে) নির্ধারণ করতে আপনি কীভাবে একটি টেবিল দৃশ্যে অটো লেআউট ব্যবহার করবেন ?



মাল্টিলাইন ইউআইএলবেল থাকার ক্ষেত্রে বেশিরভাগ উত্তর বুঝতে আপনার কীভাবে contentSizeএবং কীভাবে preferredMaxLayoutWidthকাজ করা যায় তার একটি সম্পূর্ণ বোঝার প্রয়োজন । এখানে দেখুন । বলা হচ্ছে যদি আপনি নিজের সীমাবদ্ধতাগুলি সঠিকভাবে সেটআপ করেন তবে আপনার প্রয়োজন হবে না preferredMaxLayoutWidthএবং প্রকৃতপক্ষে অপ্রত্যাশিত ফলাফল তৈরি করতে পারে।
মধু

উত্তর:


2386

টিএল; ডিআর: পড়া পছন্দ করেন না? গিটহাবের সরাসরি নমুনা প্রকল্পগুলিতে ঝাঁপুন:

ধারণামূলক বিবরণ

আপনি যে আইওএস সংস্করণটির জন্য বিকাশ করছেন তা বিবেচনা না করে নীচের প্রথম 2 টি পদক্ষেপ প্রযোজ্য।

1. সেট আপ করুন এবং সীমাবদ্ধতা যুক্ত করুন

আপনার UITableViewCellসাবক্লাসে, সীমাবদ্ধতাগুলি যুক্ত করুন যাতে ঘরের সাবউভিউগুলি তাদের প্রান্তটি কক্ষের কন্টেন্টভিউ (সবচেয়ে গুরুত্বপূর্ণভাবে উপরের এবং নীচের প্রান্তে) প্রান্তগুলিতে পিন করে দেয় । দ্রষ্টব্য: সেলটিতে নিজের মতামতগুলি পিন করবেন না; শুধু সেল এর contentView! এই সংক্ষিপ্তসারগুলির অভ্যন্তরীণ সামগ্রীর আকারটি প্রতিটি সাবউভিউয়ের জন্য উল্লম্ব মাত্রায় সামগ্রী সংক্ষেপণ প্রতিরোধের এবং সামগ্রী আলিঙ্গন সীমাবদ্ধতাগুলি আপনি যুক্ত করেছেন এমন উচ্চ-অগ্রাধিকারের সীমাবদ্ধতাগুলিকে ওভাররাইড করা হচ্ছে না তা নিশ্চিত করে টেবিল ভিউ সেলটির সামগ্রী ভিউটির উচ্চতা চালায় । ( হুঁ? এখানে ক্লিক করুন। )

মনে রাখবেন, ধারণাটি হ'ল যে ঘরের সাবভিউগুলি ঘরের সামগ্রীর দৃশ্যের সাথে উল্লম্বভাবে সংযুক্ত করা উচিত যাতে তারা "চাপ প্রয়োগ করতে" এবং সামগ্রীগুলির দৃষ্টিভঙ্গিগুলি তাদের ফিট করার জন্য প্রসারিত করতে পারে। কয়েকটি সাবভিউ সহ উদাহরণ সেলটি ব্যবহার করা, এখানে আপনার সীমাবদ্ধতার কিছু (সমস্ত নয়!) দেখতে কী প্রয়োজন হবে তার চাক্ষুষ চিত্রণ এখানে দেওয়া হয়েছে :

সারণী দর্শন কক্ষে বাধার উদাহরণের উদাহরণ

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

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

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

2. অনন্য সারণী দেখুন ঘর পুনরায় ব্যবহার সনাক্তকারীদের নির্ধারণ করুন

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

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

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

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

আইওএস 8 - স্ব-আকারের আকারের ঘরগুলির জন্য

3. সারি উচ্চতা অনুমান সক্ষম করুন

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

অ্যাপল: সেল্ফ-সাইজিং টেবিল ভিউ সেলগুলির সাথে কাজ করা

আইওএস ৮ এর সাহায্যে অ্যাপল আইওএস ৮ এর পূর্বে আপনার দ্বারা কার্যকর করা অনেক কাজ অভ্যন্তরীণ করে তুলেছে the স্ব-আকার দেওয়ার সেল প্রক্রিয়াটি কাজ করতে দেওয়ার জন্য, আপনাকে প্রথমে rowHeightটেবিলের দৃশ্যে সম্পত্তিটি স্থির করে রাখতে হবে UITableViewAutomaticDimension। তারপরে, আপনাকে কেবল সারণি প্রদর্শনের estimatedRowHeightসম্পত্তিটি কোনও ননজারো মানতে সেট করে সারি উচ্চতা অনুমান সক্ষম করতে হবে , উদাহরণস্বরূপ:

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average" cell height is

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

সাধারণভাবে বলতে গেলে, আপনি যে অনুমান সরবরাহ করেছেন তা খুব সঠিক হতে হবে না - এটি কেবলমাত্র সারণী দৃশ্যে স্ক্রল সূচকটি সঠিকভাবে আকারে ব্যবহার করতে ব্যবহৃত হয় এবং টেবিল ভিউটি আপনার হিসাবে ভুল অনুমানের জন্য স্ক্রোল সূচককে সামঞ্জস্য করার একটি ভাল কাজ করে স্ক্রিন সেল অনস্ক্রিন। estimatedRowHeightআপনার টেবিল ভিউতে সম্পত্তি ( viewDidLoadযেমন বা অনুরূপ) একটি ধ্রুবক মানতে সেট করা উচিত যা "গড়" সারি উচ্চতা। কেবলমাত্র যদি আপনার সারি উচ্চতায় চূড়ান্ত পরিবর্তনশীলতা থাকে (উদাহরণস্বরূপ প্রস্থের ক্রম অনুসারে পৃথক) এবং আপনি যখন স্ক্রোল করবেন তখন আপনি স্ক্রল সূচকটি "জাম্পিং" লক্ষ্য করেন আপনি tableView:estimatedHeightForRowAtIndexPath:প্রতিটি সারির জন্য আরও নির্ভুল অনুমান ফিরিয়ে আনতে প্রয়োজনীয় ন্যূনতম গণনা করার জন্য প্রয়োগকে বিরক্ত করবেন।

আইওএস 7 সাপোর্টের জন্য (স্বয়ংক্রিয় কক্ষ স্বয়ংক্রিয় আকার নির্ধারণ)

৩. একটি লেআউট পাস করুন এবং সেল উচ্চতা পান

প্রথমে, টেবিল ভিউ সেলটির প্রতিটি স্ক্রিন ইনস্টল করুন, প্রতিটি পুনরায় ব্যবহারকারীর শনাক্তকারীর জন্য একটি উদাহরণ , যা উচ্চতার গণনার জন্য কঠোরভাবে ব্যবহৃত হয়। (অফস্ক্রিন মানে সেল রেফারেন্সটি ভিউ কন্ট্রোলারের কোনও সম্পত্তি / আইভারে সঞ্চিত থাকে এবং tableView:cellForRowAtIndexPath:টেবিল ভিউ থেকে আসলে অনস্ক্রিনে রেন্ডার করতে কখনই ফিরে আসে না )) এরপরে, ঘরটি অবশ্যই সঠিক সামগ্রী (যেমন পাঠ্য, চিত্র ইত্যাদি) দিয়ে কনফিগার করা উচিত এটি যদি টেবিল ভিউতে প্রদর্শিত হয় তবে এটি ধরে রাখবে।

তারপরে, ঘরটি অবিলম্বে তার সংক্ষিপ্তসারগুলি বিন্যাস করতে বাধ্য করুন এবং তারপরে ঘরের প্রয়োজনীয় উচ্চতা কী তা নির্ধারণ করার জন্য এর systemLayoutSizeFittingSize:পদ্ধতিটি ব্যবহার করুন । কক্ষের সমস্ত বিষয়বস্তু ফিট করার জন্য প্রয়োজনীয় ক্ষুদ্রতম আকারটি পেতে ব্যবহার করুন । তারপরে ডেলিগেট পদ্ধতি থেকে উচ্চতাটি ফেরানো যেতে পারে ।UITableViewCellcontentViewUILayoutFittingCompressedSizetableView:heightForRowAtIndexPath:

4. আনুমানিক সারি উচ্চতা ব্যবহার করুন

যদি আপনার টেবিল ভিউটিতে কয়েক ডজন সারি বেশি থাকে, তবে আপনি দেখতে পাবেন যে অটো লেআউট সীমাবদ্ধতা সমাধানের ফলে প্রথম টেবিলের দৃশ্যটি লোড করার সময় মূল থ্রেডটি দ্রুত ছিটকে যেতে পারে, যেমন tableView:heightForRowAtIndexPath:প্রতিটি লোডের উপর প্রতিটি সারিতে বলা হয় ( স্ক্রোল সূচকটির আকার গণনা করার জন্য)।

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

সাধারণভাবে বলতে গেলে, আপনি যে অনুমান সরবরাহ করেছেন তা খুব সঠিক হতে হবে না - এটি কেবলমাত্র সারণী দৃশ্যে স্ক্রল সূচকটি সঠিকভাবে আকারে ব্যবহার করতে ব্যবহৃত হয় এবং টেবিল ভিউটি আপনার হিসাবে ভুল অনুমানের জন্য স্ক্রোল সূচককে সামঞ্জস্য করার একটি ভাল কাজ করে স্ক্রিন সেল অনস্ক্রিন। estimatedRowHeightআপনার টেবিল ভিউতে সম্পত্তি ( viewDidLoadযেমন বা অনুরূপ) একটি ধ্রুবক মানতে সেট করা উচিত যা "গড়" সারি উচ্চতা। কেবলমাত্র যদি আপনার সারি উচ্চতায় চূড়ান্ত পরিবর্তনশীলতা থাকে (উদাহরণস্বরূপ প্রস্থের ক্রম অনুসারে পৃথক) এবং আপনি যখন স্ক্রোল করবেন তখন আপনি স্ক্রল সূচকটি "জাম্পিং" লক্ষ্য করেন আপনি tableView:estimatedHeightForRowAtIndexPath:প্রতিটি সারির জন্য আরও নির্ভুল অনুমান ফিরিয়ে আনতে প্রয়োজনীয় ন্যূনতম গণনা করার জন্য প্রয়োগকে বিরক্ত করবেন।

৫. (যদি প্রয়োজন হয়) সারি উচ্চতা ক্যাচিং যুক্ত করুন

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

আইওএস 7 জেনেরিক নমুনা কোড (প্রচুর সরস মন্তব্য সহ)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Determine which reuse identifier should be used for the cell at this 
    // index path, depending on the particular layout required (you may have
    // just one, or may have many).
    NSString *reuseIdentifier = ...;

    // Dequeue a cell for the reuse identifier.
    // Note that this method will init and return a new cell if there isn't
    // one available in the reuse pool, so either way after this line of 
    // code you will have a cell with the correct constraints ready to go.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

    // Configure the cell with content for the given indexPath, for example:
    // cell.textLabel.text = someTextForThisCell;
    // ...

    // Make sure the constraints have been set up for this cell, since it 
    // may have just been created from scratch. Use the following lines, 
    // assuming you are setting up constraints from within the cell's 
    // updateConstraints method:
    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];

    // If you are using multi-line UILabels, don't forget that the 
    // preferredMaxLayoutWidth needs to be set correctly. Do it at this 
    // point if you are NOT doing it within the UITableViewCell subclass 
    // -[layoutSubviews] method. For example: 
    // cell.multiLineLabel.preferredMaxLayoutWidth = CGRectGetWidth(tableView.bounds);

    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Determine which reuse identifier should be used for the cell at this 
    // index path.
    NSString *reuseIdentifier = ...;

    // Use a dictionary of offscreen cells to get a cell for the reuse 
    // identifier, creating a cell and storing it in the dictionary if one 
    // hasn't already been added for the reuse identifier. WARNING: Don't 
    // call the table view's dequeueReusableCellWithIdentifier: method here 
    // because this will result in a memory leak as the cell is created but 
    // never returned from the tableView:cellForRowAtIndexPath: method!
    UITableViewCell *cell = [self.offscreenCells objectForKey:reuseIdentifier];
    if (!cell) {
        cell = [[YourTableViewCellClass alloc] init];
        [self.offscreenCells setObject:cell forKey:reuseIdentifier];
    }

    // Configure the cell with content for the given indexPath, for example:
    // cell.textLabel.text = someTextForThisCell;
    // ...

    // Make sure the constraints have been set up for this cell, since it 
    // may have just been created from scratch. Use the following lines, 
    // assuming you are setting up constraints from within the cell's 
    // updateConstraints method:
    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];

    // Set the width of the cell to match the width of the table view. This
    // is important so that we'll get the correct cell height for different
    // table view widths if the cell's height depends on its width (due to 
    // multi-line UILabels word wrapping, etc). We don't need to do this 
    // above in -[tableView:cellForRowAtIndexPath] because it happens 
    // automatically when the cell is used in the table view. Also note, 
    // the final width of the cell may not be the width of the table view in
    // some cases, for example when a section index is displayed along 
    // the right side of the table view. You must account for the reduced 
    // cell width.
    cell.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

    // Do the layout pass on the cell, which will calculate the frames for 
    // all the views based on the constraints. (Note that you must set the 
    // preferredMaxLayoutWidth on multiline UILabels inside the 
    // -[layoutSubviews] method of the UITableViewCell subclass, or do it 
    // manually at this point before the below 2 lines!)
    [cell setNeedsLayout];
    [cell layoutIfNeeded];

    // Get the actual height required for the cell's contentView
    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    // Add an extra point to the height to account for the cell separator, 
    // which is added between the bottom of the cell's contentView and the 
    // bottom of the table view cell.
    height += 1.0;

    return height;
}

// NOTE: Set the table view's estimatedRowHeight property instead of 
// implementing the below method, UNLESS you have extreme variability in 
// your row heights and you notice the scroll indicator "jumping" 
// as you scroll.
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Do the minimal calculations required to be able to return an 
    // estimated row height that's within an order of magnitude of the 
    // actual height. For example:
    if ([self isTallCellAtIndexPath:indexPath]) {
        return 350.0;
    } else {
        return 40.0;
    }
}

নমুনা প্রকল্প

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

জামারিন (সি # /। নেট)

আপনি Xamarin ব্যবহার করেন, তাহলে এই চেক আউট নমুনা প্রকল্পের দ্বারা একত্র করা @KentBoogaart


1
এটি ভালভাবে কাজ করার সময়, আমি এটি প্রয়োজনীয় মাপের সামান্য পরিমাণে অনুমান করেছি (সম্ভবত বিভিন্ন গোলাকার সমস্যাগুলির কারণে) এবং আমার সমস্ত পাঠ্য লেবেলের ভিতরে ফিট করার জন্য আমাকে চূড়ান্ত উচ্চতায় কয়েকটি পয়েন্ট যুক্ত করতে হবে
ডিবিডি

5
@ অ্যালেক্স ৩১১ অত্যন্ত আকর্ষণীয়, এই উদাহরণটি দেওয়ার জন্য ধন্যবাদ। আমি আমার শেষের দিকে একটু পরীক্ষা করেছিলাম এবং এখানে কিছু মন্তব্য লিখেছিলাম: github.com/Alex311/TableCellWithAutoLayout/commit/…
স্মাইলিবার্গ

3
আমি দৃ each়ভাবে প্রতিটি কক্ষ পুনরায় ব্যবহারকার্য শনাক্তকারী ধরণের জন্য সেলটি ক্যাশে করার সুপারিশ করব। প্রতিবার উচ্চতার জন্য আপনি যখন প্রস্থান করলেন তখন আপনি সারির বাইরে একটি ঘর নিচ্ছেন যা আর ফিরে পাওয়া যাচ্ছে না। ক্যাচিং আপনার টেবিল কোষগুলির জন্য ইনিশিয়ালার হিসাবে কল করার পরিমাণকে উল্লেখযোগ্যভাবে হ্রাস করতে পারে। কোনও কারণে, যখন আমি ক্যাশে করছিলাম না, তখন স্ক্রোল করার সাথে সাথে মেমরির পরিমাণটি বাড়ছে growing
Alex311

1
স্টোরিবোর্ডগুলি, আসলে। আমি মনে করি না যে প্রোটোটাইপ সেলগুলির জন্য কাজ করে (কমপক্ষে পুরো ভিসিকে পুনরায় ইনস্ট্যান্ট না করে)। heightForRowAtIndexPathকোষটি রেখে, পরের বার cellForRowAtIndexPathডেকে আনা এবং ডেকে এনে পুরোপুরিভাবে ফাঁস এড়ানো সম্ভব হবে ।
এনএসচাম

2
iOS8বাস্তবায়ন কি এখনও এর জন্য প্রস্তাবিত iOS9এবং iOS10, বা এই উত্তর প্রকাশের পরে নতুন কোন পন্থা রয়েছে?
Koen

175

উপরে আইওএস 8 এর জন্য এটি সত্যিই সহজ:

override func viewDidLoad() {  
    super.viewDidLoad()

    self.tableView.estimatedRowHeight = 80
    self.tableView.rowHeight = UITableView.automaticDimension
}

অথবা

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableView.automaticDimension
}

তবে আইওএস 7 এর জন্য কীটি স্বয়ংক্রিয়আউটয়ের পরে উচ্চতা গণনা করে:

func calculateHeightForConfiguredSizingCell(cell: GSTableViewCell) -> CGFloat {
    cell.setNeedsLayout()
    cell.layoutIfNeeded()
    let height = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize).height + 1.0
    return height
}

গুরুত্বপূর্ণ

  • যদি একাধিক লাইনের লেবেল, সেট ভুলবেন না numberOfLinesকরতে 0

  • ভুলে যাবেন না label.preferredMaxLayoutWidth = CGRectGetWidth(tableView.bounds)

পুরো উদাহরণ কোড এখানে


7
আমি মনে করি আমাদের ওএস 8 মামলায় উচ্চতারোআউট ইন্ডেক্সপথ ফাংশনটি প্রয়োগ করার দরকার নেই
jpulikkottil

@ অ্যাডউইনপাজ যেমন অন্য উত্তরে লিখিত হয়েছে, এটি গুরুত্বপূর্ণ যে সারি উচ্চতায় লক করতে ব্যবহৃত প্রতিবন্ধকরা মার্জিনের অন্তর্ভুক্ত না করে।
রিচার্ড

1
"যদি একাধিক লাইনের লেবেল থাকে তবে অফলাইনস 0 তে সেট করে ভুলে যাবেন না" এটি আমার কোষগুলিকে আকারে গতিশীল রাখার কারণ ছিল।
ইয়ান-ফোগেলম্যান

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

যখন আমরা স্ক্রোল করব, লেবেল একাধিক লাইনে প্রদর্শিত শুরু করবে এবং সারির উচ্চতাও বাড়বে না
সিং

93

পরিবর্তনশীল উচ্চতার UITableViewCell এর সুইফ্ট উদাহরণ

সুইফট 3-এর জন্য আপডেট করা হয়েছে

উইলিয়াম হুয়ের সুইফট উত্তরটি ভাল, তবে প্রথমবারের জন্য কিছু করতে শিখলে এটি আমাকে কিছু সহজ তবে বিস্তারিত পদক্ষেপ নিতে সহায়তা করে। UITableViewভেরিয়েবল সেল হাইটের সাহায্যে একটি তৈরি করতে শেখার সময় নীচের উদাহরণটি আমার পরীক্ষার প্রকল্প । আমি এটিকে সুইফটের জন্য এই বেসিক ইউআইটিএবলভিউ উদাহরণের ভিত্তিতে তৈরি করেছি ।

সমাপ্ত প্রকল্পটি দেখতে এইরকম হওয়া উচিত:

এখানে চিত্র বর্ণনা লিখুন

একটি নতুন প্রকল্প তৈরি করুন

এটি কেবলমাত্র একক ভিউ অ্যাপ্লিকেশন হতে পারে।

কোড যুক্ত করুন

আপনার প্রকল্পে একটি নতুন সুইফ্ট ফাইল যুক্ত করুন। নাম রাখুন মাই কাস্টমসেল। আপনি স্টোরিবোর্ডে আপনার ঘরে যোগ করেছেন এমন দর্শনগুলির জন্য এই শ্রেণিটি আউটলেটগুলিকে ধারণ করবে। এই মৌলিক উদাহরণে আমাদের প্রতিটি ঘরে একটি মাত্র লেবেল থাকবে।

import UIKit
class MyCustomCell: UITableViewCell {
    @IBOutlet weak var myCellLabel: UILabel!
}

আমরা এই আউটলেটটি পরে সংযুক্ত করব।

ভিউকন্ট্রোল.আরউইফ্টটি খুলুন এবং আপনার নীচের সামগ্রীটি নিশ্চিত করুন:

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // These strings will be the data for the table view cells
    let animals: [String] = [
        "Ten horses:  horse horse horse horse horse horse horse horse horse horse ",
        "Three cows:  cow, cow, cow",
        "One camel:  camel",
        "Ninety-nine sheep:  sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep baaaa sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep sheep",
        "Thirty goats:  goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat goat "]

    // Don't forget to enter this in IB also
    let cellReuseIdentifier = "cell"

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // delegate and data source
        tableView.delegate = self
        tableView.dataSource = self

        // Along with auto layout, these are the keys for enabling variable cell height
        tableView.estimatedRowHeight = 44.0
        tableView.rowHeight = UITableViewAutomaticDimension
    }

    // number of rows in table view
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.animals.count
    }

    // create a cell for each table view row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell:MyCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MyCustomCell
        cell.myCellLabel.text = self.animals[indexPath.row]
        return cell
    }

    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You tapped cell number \(indexPath.row).")
    }
}

গুরুত্বপূর্ণ তথ্য:

  • এটি নীচের দুটি লাইন কোড (স্বয়ংক্রিয় বিন্যাস সহ) যা ভেরিয়েবল সেল উচ্চতাকে সম্ভব করে তোলে:

    tableView.estimatedRowHeight = 44.0
    tableView.rowHeight = UITableViewAutomaticDimension

স্টোরিবোর্ড সেটআপ করুন

আপনার দেখার নিয়ামকটিতে একটি সারণী দর্শন যুক্ত করুন এবং এটিকে চার পাশে পিন করতে স্বয়ংক্রিয় বিন্যাস ব্যবহার করুন। তারপরে টেবিল ভিউতে একটি টেবিল ভিউ সেল টেনে আনুন। এবং প্রোটোটাইপ সেলে একটি লেবেল টেনে আনুন। সারণী দর্শন ঘরের কনটেন্ট ভিউয়ের চারটি প্রান্তে লেবেলটি পিন করতে স্বয়ংক্রিয় বিন্যাস ব্যবহার করুন।

এখানে চিত্র বর্ণনা লিখুন

গুরুত্বপূর্ণ তথ্য:

  • অটো লেআউটটি উপরে উল্লিখিত গুরুত্বপূর্ণ দুটি লাইনের কোডের সাথে একত্রে কাজ করে। আপনি যদি স্বয়ংক্রিয় বিন্যাস ব্যবহার না করেন তবে এটি কার্যকর হবে না।

অন্যান্য আইবি সেটিংস

কাস্টম শ্রেণীর নাম এবং সনাক্তকারী

টেবিল ভিউ সেলটি নির্বাচন করুন এবং কাস্টম ক্লাসটি সেট করুন MyCustomCell(আমরা যুক্ত সুইফট ফাইলে শ্রেণীর নাম)। সনাক্তকারীকে সেট করতেও cell( cellReuseIdentifierউপরের কোডে আমরা একই স্ট্রিংটি ব্যবহার করেছি ।

এখানে চিত্র বর্ণনা লিখুন

লেবেলের জন্য জিরো লাইনস

আপনার লেবেলে লাইনের সংখ্যা সেট করুন 0। এর অর্থ মাল্টি-লাইন এবং তার সামগ্রীর উপর ভিত্তি করে লেবেলটিকে নিজেরাই আকার পরিবর্তন করতে দেয়।

এখানে চিত্র বর্ণনা লিখুন

আউটলেট হুক আপ

  • স্টোরবোর্ডের টেবিল ভিউ থেকে কোডের tableViewভেরিয়েবলটিতে টানুন ControlViewController
  • আপনার প্রোটোটাইপ সেলে লেবেলের জন্য ক্লাসের myCellLabelপরিবর্তনশীল হিসাবে একই করুন MyCustomCell

সমাপ্ত

আপনার এখনই আপনার প্রকল্প চালানো এবং পরিবর্তনশীল উচ্চতা সহ ঘর পেতে সক্ষম হওয়া উচিত।

মন্তব্য

  • এই উদাহরণটি কেবল আইওএস 8 এবং তার পরে কাজ করে। যদি আপনার এখনও আইওএস 7 সমর্থন করার প্রয়োজন হয় তবে এটি আপনার পক্ষে কাজ করবে না।
  • আপনার ভবিষ্যতের প্রকল্পগুলিতে আপনার নিজস্ব কাস্টম সেলগুলিতে সম্ভবত একক লেবেলের বেশি থাকতে হবে। নিশ্চিত হয়ে নিন যে আপনি সবকিছু ঠিকভাবে পিন করেছেন যাতে অটো লেআউটটি সঠিকভাবে উচ্চতাটি ব্যবহার করতে পারে। আপনাকে উল্লম্ব সংকোচন প্রতিরোধ এবং আলিঙ্গনও ব্যবহার করতে হতে পারে। সে সম্পর্কে আরও জানতে এই নিবন্ধটি দেখুন ।
  • আপনি যদি শীর্ষস্থানীয় এবং পিছনের (বাম এবং ডান) প্রান্তগুলি পিন না করে থাকেন তবে আপনার লেবেলটি সেট করার প্রয়োজনও হতে পারে preferredMaxLayoutWidthযাতে কখন জড়োতে হবে। উদাহরণস্বরূপ, আপনি যদি শীর্ষস্থানীয় এবং অনুসরণকারী প্রান্তগুলি পিন করার পরিবর্তে উপরের প্রকল্পের লেবেলে একটি কেন্দ্র অনুভূমিকভাবে সীমাবদ্ধতা যুক্ত করেছিলেন, তবে আপনাকে tableView:cellForRowAtIndexPathপদ্ধতিতে এই লাইনটি যুক্ত করতে হবে :

     cell.myCellLabel.preferredMaxLayoutWidth = tableView.bounds.width

আরো দেখুন


প্রকৃতপক্ষে preferredMaxLayoutWidthঘরের বিপরীতে সেট করা ভাল না contentSize? এইভাবে যদি আপনার অ্যাকসেসরিভিউ থাকে বা এটি সম্পাদনার জন্য সোয়াইপ করা হয় তবে এটি এখনও বিবেচনায় নেওয়া হবে?
মধু

@ মধু, আপনি খুব ভাল হতে পারে। আমি এখন প্রায় এক বছর ধরে আইওএস এ রাখি নি এবং এই মুহুর্তে আপনাকে ভাল উত্তর দিতে আমি খুব মরিয়া।
সুরগাচ

65

আমি @ স্মাইলিবার্গের আইওএস 7 সমাধানটি একটি বিভাগে গুটিয়ে রেখেছি

আমি এই চতুর সমাধানটি @ স্মাইলিবার্গ দ্বারা একটি UICollectionViewCell+AutoLayoutDynamicHeightCalculationবিভাগে গুটিয়ে রাখার সিদ্ধান্ত নিয়েছি ।

বিভাগটি @ ওয়াইল্ডমনকি'র উত্তরে বর্ণিত বিষয়গুলিও সংশোধন করে (একটি নিব থেকে একটি সেল লোড করে systemLayoutSizeFittingSize:ফেরত CGRectZero)

এটি কোনও ক্যাচিংয়ের বিষয়টি বিবেচনা করে না তবে এই মুহূর্তে আমার প্রয়োজন অনুসারে। এটি অনুলিপি অনুলিপি, আটকান এবং হ্যাক করুন।

UICollectionViewCell + + AutoLayoutDynamicHeightCalculation.h

#import <UIKit/UIKit.h>

typedef void (^UICollectionViewCellAutoLayoutRenderBlock)(void);

/**
 *  A category on UICollectionViewCell to aid calculating dynamic heights based on AutoLayout contraints.
 *
 *  Many thanks to @smileyborg and @wildmonkey
 *
 *  @see stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights
 */
@interface UICollectionViewCell (AutoLayoutDynamicHeightCalculation)

/**
 *  Grab an instance of the receiving type to use in order to calculate AutoLayout contraint driven dynamic height. The method pulls the cell from a nib file and moves any Interface Builder defined contrainsts to the content view.
 *
 *  @param name Name of the nib file.
 *
 *  @return collection view cell for using to calculate content based height
 */
+ (instancetype)heightCalculationCellFromNibWithName:(NSString *)name;

/**
 *  Returns the height of the receiver after rendering with your model data and applying an AutoLayout pass
 *
 *  @param block Render the model data to your UI elements in this block
 *
 *  @return Calculated constraint derived height
 */
- (CGFloat)heightAfterAutoLayoutPassAndRenderingWithBlock:(UICollectionViewCellAutoLayoutRenderBlock)block collectionViewWidth:(CGFloat)width;

/**
 *  Directly calls `heightAfterAutoLayoutPassAndRenderingWithBlock:collectionViewWidth` assuming a collection view width spanning the [UIScreen mainScreen] bounds
 */
- (CGFloat)heightAfterAutoLayoutPassAndRenderingWithBlock:(UICollectionViewCellAutoLayoutRenderBlock)block;

@end

UICollectionViewCell + + AutoLayoutDynamicHeightCalculation.m

#import "UICollectionViewCell+AutoLayout.h"

@implementation UICollectionViewCell (AutoLayout)

#pragma mark Dummy Cell Generator

+ (instancetype)heightCalculationCellFromNibWithName:(NSString *)name
{
    UICollectionViewCell *heightCalculationCell = [[[NSBundle mainBundle] loadNibNamed:name owner:self options:nil] lastObject];
    [heightCalculationCell moveInterfaceBuilderLayoutConstraintsToContentView];
    return heightCalculationCell;
}

#pragma mark Moving Constraints

- (void)moveInterfaceBuilderLayoutConstraintsToContentView
{
    [self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
        [self removeConstraint:constraint];
        id firstItem = constraint.firstItem == self ? self.contentView : constraint.firstItem;
        id secondItem = constraint.secondItem == self ? self.contentView : constraint.secondItem;
        [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:firstItem
                                                                     attribute:constraint.firstAttribute
                                                                     relatedBy:constraint.relation
                                                                        toItem:secondItem
                                                                     attribute:constraint.secondAttribute
                                                                    multiplier:constraint.multiplier
                                                                      constant:constraint.constant]];
    }];
}

#pragma mark Height

- (CGFloat)heightAfterAutoLayoutPassAndRenderingWithBlock:(UICollectionViewCellAutoLayoutRenderBlock)block
{
    return [self heightAfterAutoLayoutPassAndRenderingWithBlock:block
                                            collectionViewWidth:CGRectGetWidth([[UIScreen mainScreen] bounds])];
}

- (CGFloat)heightAfterAutoLayoutPassAndRenderingWithBlock:(UICollectionViewCellAutoLayoutRenderBlock)block collectionViewWidth:(CGFloat)width
{
    NSParameterAssert(block);

    block();

    [self setNeedsUpdateConstraints];
    [self updateConstraintsIfNeeded];

    self.bounds = CGRectMake(0.0f, 0.0f, width, CGRectGetHeight(self.bounds));

    [self setNeedsLayout];
    [self layoutIfNeeded];

    CGSize calculatedSize = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

    return calculatedSize.height;

}

@end

ব্যবহারের উদাহরণ:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MYSweetCell *cell = [MYSweetCell heightCalculationCellFromNibWithName:NSStringFromClass([MYSweetCell class])];
    CGFloat height = [cell heightAfterAutoLayoutPassAndRenderingWithBlock:^{
        [(id<MYSweetCellRenderProtocol>)cell renderWithModel:someModel];
    }];
    return CGSizeMake(CGRectGetWidth(self.collectionView.bounds), height);
}

কৃতজ্ঞতার সাথে আমরা এই জাজটি iOS8 এ করতে হবে না, তবে এটি এখনই রয়েছে!


2
আপনার কেবলমাত্র একটি ব্যবহার করতে সক্ষম হওয়া উচিত: [YourCell new]এবং এটি ডামি হিসাবে ব্যবহার করুন। যতক্ষণ সীমাবদ্ধতা বিল্ডিং কোডটি আপনার উদাহরণে সরিয়ে দেওয়া হয়, এবং আপনি কোনও লেআউট পাস প্রোগ্রামিকভাবে ট্রিগার করেন আপনার ভাল হওয়া উচিত।
অ্যাডাম ওয়েট

1
ধন্যবাদ! এইটা কাজ করে. আপনার বিভাগটি দুর্দান্ত। এটিই আমাকে বুঝতে পেরেছিল যে এই কৌশলটি UICollectionViewsপাশাপাশি কাজ করে ।
রিকার্ডো সানচেজ-সায়েজ

2
স্টোরিবোর্ডে সংজ্ঞায়িত প্রোটোটাইপ সেল ব্যবহার করে আপনি কীভাবে এটি করবেন?
ডেভিড পটার

57

এখানে আমার সমাধান:

আপনি বলতে প্রয়োজন আগেই দৃশ্য লোড করে। অন্যথায় এটি প্রত্যাশার মতো আচরণ করতে সক্ষম হবে না।TableViewestimatedHeight

উদ্দেশ্য গ

- (void)viewWillAppear:(BOOL)animated {
    _messageField.delegate = self;
    _tableView.estimatedRowHeight = 65.0;
    _tableView.rowHeight = UITableViewAutomaticDimension;
}

সুইফটে 4.2 আপডেট করুন

override func viewWillAppear(_ animated: Bool) {
    tableView.rowHeight = UITableView.automaticDimension
    tableView.estimatedRowHeight = 65.0
}

2
অডিওলেআউটটি সঠিকভাবে সেট আপ করা, এই কোডটি ভিউডিডলয়েডে যুক্ত হওয়ার সাথে সাথে কৌশলটি করেছে।
ব্রুস

1
তবে কি যদি estimatedRowHeightসারি সারি আলাদা হয়ে থাকে ? আমার কি অনুমান করা উচিত? আমি যে উচ্চতাটি ব্যবহার করি তার নূন্যতম বা সর্বাধিক ব্যবহার করি tableView?
জানোস

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

1
এটি এখন পর্যন্ত সবচেয়ে দৃ solution় সমাধান। উদ্বিগ্ন estimatedRowHeightহবেন না , এটি বেশিরভাগই স্ক্রোল বারের আকারকে প্রভাবিত করে, সত্যিকারের ঘরগুলির উচ্চতা কখনই নয়। আপনি যে উচ্চতা চয়ন করেছেন তাতে সাহসী হোন: এটি সন্নিবেশ / মোছার অ্যানিমেশনটিকে প্রভাবিত করবে।
সুইফট আরকিটেক্ট


47

@ স্মাইলিবার্গ প্রস্তাবিত সমাধানটি প্রায় নিখুঁত। যদি আপনার একটি কাস্টম সেল থাকে এবং আপনি UILabelগতিশীল উচ্চতা সহ এক বা একাধিকটি চান তবে অটোআলআউট সক্ষম হওয়া সাথে মিলিয়ে সিস্টেমলাউটসাইজ ফিটিংসাইজ পদ্ধতিটি CGSizeZeroযদি আপনি আপনার সমস্ত সেল সীমাবদ্ধতা সেল থেকে তার বিষয়বস্তায় না নিয়ে যান তবে (@ টমসুইফ্টের পরামর্শ অনুযায়ী এখানে কীভাবে তত্ত্বাবধানে পুনরায় আকার দেওয়া যায়) অটোলেআউট দিয়ে সমস্ত মতামত ফিট? )।

এটি করার জন্য আপনার কাস্টম ইউআইটিএবলভিউসেল বাস্তবায়নে আপনাকে নিম্নলিখিত কোডটি সন্নিবেশ করতে হবে (@ অ্যাড্রিয়ানকে ধন্যবাদ)

- (void)awakeFromNib{
    [super awakeFromNib];
    for (NSLayoutConstraint *cellConstraint in self.constraints) {
        [self removeConstraint:cellConstraint];
        id firstItem = cellConstraint.firstItem == self ? self.contentView : cellConstraint.firstItem;
        id seccondItem = cellConstraint.secondItem == self ? self.contentView : cellConstraint.secondItem;
        NSLayoutConstraint *contentViewConstraint =
        [NSLayoutConstraint constraintWithItem:firstItem
                                 attribute:cellConstraint.firstAttribute
                                 relatedBy:cellConstraint.relation
                                    toItem:seccondItem
                                 attribute:cellConstraint.secondAttribute
                                multiplier:cellConstraint.multiplier
                                  constant:cellConstraint.constant];
        [self.contentView addConstraint:contentViewConstraint];
    }
}

এটির সাথে @ স্মাইলিবার্গের উত্তর মিশ্রণের কাজ করা উচিত।


systemLayoutSizeFittingSizeকন্টেন্টভিউতে কল করা দরকার, সেল নয়
onwayway133

25

একটি গুরুত্বপূর্ণ যথেষ্ট গোটচা আমি উত্তর হিসাবে পোস্ট করার জন্য ছুটে এসেছি।

@ স্মাইলিবার্গের উত্তর বেশিরভাগ ক্ষেত্রেই সঠিক। তবে, যদি layoutSubviewsআপনার কাস্টম সেল শ্রেণীর পদ্ধতিতে কোনও কোড থাকে, উদাহরণস্বরূপ সেটিংস সেট করে preferredMaxLayoutWidth, তবে এটি এই কোড দিয়ে চালানো হবে না:

[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];

এটি আমাকে কিছুক্ষণের জন্য বিস্মিত করেছিল। তখন আমি বুঝতে পেরেছিলাম কারণ সেগুলি কেবলমাত্র contentViewসেল নয়, কেবলমাত্র লেআউটসুভিউগুলিকে ট্রিগার করছে।

আমার কাজের কোডটি দেখতে এমন দেখাচ্ছে:

TCAnswerDetailAppSummaryCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"TCAnswerDetailAppSummaryCell"];
[cell configureWithThirdPartyObject:self.app];
[cell layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return height;

মনে রাখবেন যে আপনি যদি একটি নতুন ঘর তৈরি করছেন তবে আমি নিশ্চিত যে setNeedsLayoutএটির আগে থেকেই সেট করা উচিত হওয়ায় আপনার কল করার দরকার নেই । আপনি যখন কোনও ঘরে কোনও রেফারেন্স সংরক্ষণ করেন সে ক্ষেত্রে আপনার সম্ভবত এটি কল করা উচিত। যেভাবেই কোনও কিছুতেই আঘাত করা উচিত নয়।

আপনি যেখানে সেল সাবক্ল্যাস ব্যবহার করছেন যেখানে আপনি পছন্দ মতো জিনিস সেট করছেন তা অন্য টিপস preferredMaxLayoutWidth। @ স্মাইলিবার্গের উল্লেখ হিসাবে, "আপনার টেবিল ভিউ সেলটি এখনও এর প্রস্থটি টেবিল দর্শনের প্রস্থের সাথে স্থির করে নি"। এটি সত্য এবং সমস্যাটি যদি আপনি নিজের সাবক্লাসে কাজ করছেন এবং ভিউ কন্ট্রোলারে নেই। তবে আপনি কেবল টেবিলের প্রস্থ ব্যবহার করে এই সময়ে সেল ফ্রেমটি সেট করতে পারেন:

উদাহরণস্বরূপ উচ্চতার জন্য গণনায়:

self.summaryCell = [self.tableView dequeueReusableCellWithIdentifier:@"TCAnswerDetailDefaultSummaryCell"];
CGRect oldFrame = self.summaryCell.frame;
self.summaryCell.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, self.tableView.frame.size.width, oldFrame.size.height);

(আমি পুনরায় ব্যবহারের জন্য এই নির্দিষ্ট কক্ষটি ক্যাশে করব, তবে তা অপ্রাসঙ্গিক)।


21

যদি লোকেরা এখনও এ নিয়ে সমস্যা করে থাকে। ডায়নামিক সেল হাইটের জন্য ইউআইটিএবলভিউস লিভারেজিং অটোলেআউট এর সাথে অটোলেআউট ব্যবহার করার বিষয়ে একটি দ্রুত ব্লগ পোস্ট লিখেছিলাম এবং এটিকে আরও বিমূর্ত এবং কার্যকর করার জন্য আরও সহজ করার জন্য একটি ওপেন সোর্স উপাদান রয়েছে। https://github.com/Raizlabs/RZCellSizeManager


19

যতক্ষণ না আপনার ঘরে আপনার লেআউটটি ভাল থাকে।

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];

    return [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
}

আপডেট: আপনার আইওএস 8 এ প্রবর্তিত ডায়নামিক পুনরায় আকার ব্যবহার করা উচিত।


এই IOS7 নেভিগেশন আমার জন্য কাজ করে যাচ্ছে, এটি এখন কল করতে ঠিক আছে tableView:cellForRowAtIndexPath:মধ্যে tableView:heightForRowAtIndexPath:এখন?
পিপড়া

ঠিক আছে এই তাই কাজ করছে না, কিন্তু যখন আমি কল systemLayoutSizeFittingSize:মধ্যে tableView:cellForRowAtIndexPath:এবং তারপর ফলাফলের ক্যাশে এবং তারপর ব্যবহার যে tableView:heightForRowAtIndexPath:এটা যতদিন ভাল কাজ করে যেমন সীমাবদ্ধতা সেটআপ অবশ্যই সঠিকভাবে হয়!
এন্টি

এটি কেবল তখনই কাজ করে যদি আপনি ডিকিউ রিজেজেবল সেল উইথ আইডেন্টিফায়ার: ডেকিউর পরিবর্তে পুনরায় ব্যবহারযোগ্য সেলভিথআইডেন্টিফায়ারের পরিবর্তে: ইনডেক্সপথ:
এন্টোইন

1
আমি টেবিল ভিউ: সেলফোর্ডআউটইন্টেক্সপথ: সরাসরি কল করা ভাল বলে মনে করি না।
Itachi

19

(Xcode 8.x / Xcode 9.x নীচে পড়ুন)

Xcode 7.x এ নিম্নলিখিত সমস্যা থেকে সাবধান থাকুন, যা বিভ্রান্তির কারণ হতে পারে:

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

উদাহরণস্বরূপ, কল্পনা করুন যে আপনি সবকিছু ঠিকঠাক করেছেন, কোনও সতর্কতা নেই, কোনও ত্রুটি নেই, সমস্ত কাজ রয়েছে।

এখানে চিত্র বর্ণনা লিখুন

এখন আপনি যদি ফন্টের আকার পরিবর্তন করেন (এই উদাহরণে আমি বর্ণনা লেবেলের ফন্টের আকার 17.0 থেকে 18.0 এ পরিবর্তন করছি)।

এখানে চিত্র বর্ণনা লিখুন

হরফ আকার বাড়ার কারণে লেবেলটি এখন 3 সারি দখল করতে চায় (এর আগে এটি 2 সারি দখল করে ছিল)।

যদি ইন্টারফেস বিল্ডার প্রত্যাশা অনুযায়ী কাজ করে তবে এটি নতুন লেবেলের উচ্চতা মিলে ঘরের উচ্চতার আকার পরিবর্তন করবে। তবে আসলে যা ঘটে তা হ'ল আইবি লাল অটো-লেআউট ত্রুটি আইকনটি প্রদর্শন করে এবং আপনাকে আলিঙ্গন / সংকোচন অগ্রাধিকারগুলি পরিবর্তন করার পরামর্শ দেয়।

এখানে চিত্র বর্ণনা লিখুন

আপনার এই সতর্কতাগুলি উপেক্ষা করা উচিত। পরিবর্তে আপনি যা করতে পারেন তা হ'ল ম্যানুয়ালি সারিটির উচ্চতা পরিবর্তন করা (সেল> আকার পরিদর্শক> সারি উচ্চতা নির্বাচন করুন)।

এখানে চিত্র বর্ণনা লিখুন

লাল তীরের ত্রুটিগুলি অদৃশ্য না হওয়া পর্যন্ত আমি একবারে এই উচ্চতাটিকে একবার ক্লিক করে (উপরে / নীচে স্টিপার ব্যবহার করে) পরিবর্তন করছি! (আপনি আসলে হলুদ সতর্কতা পাবেন, যে পর্যায়ে কেবল এগিয়ে যান এবং 'ফ্রেম আপডেট করুন', এটি সমস্ত কাজ করা উচিত)।

* নোট করুন যে আপনাকে আসলে এই লাল ত্রুটিগুলি বা ইন্টারফেস বিল্ডারে হলুদ সতর্কতাগুলি সমাধান করতে হবে না - রানটাইমের সময়, সবকিছু সঠিকভাবে কাজ করবে (এমনকি আইবি ত্রুটিগুলি / সতর্কতা দেখায়)। কেবল নিশ্চিত হয়ে নিন যে কনসোল লগের রানটাইমের সময় আপনি কোনও অটোলআউট ত্রুটি পাচ্ছেন না।

আসলে আইবিতে সারির উচ্চতা সর্বদা আপডেট করার চেষ্টা করা অত্যন্ত বিরক্তিকর এবং কখনও কখনও অসম্ভবের কাছে (ভগ্নাংশের মানগুলির কারণে)।

বিরক্তিকর আইবি সতর্কতা / ত্রুটিগুলি রোধ করতে, আপনি Size Inspectorসম্পত্তিটি Ambiguityবেছে নেওয়ার জন্য জড়িত এবং অন্তর্ভুক্ত মতামতগুলি নির্বাচন করতে পারেনVerify Position Only

এখানে চিত্র বর্ণনা লিখুন


Xcode 8.x / Xcode 9.x মনে হয় (কখনও কখনও) এক্সকোড x.x এর চেয়ে আলাদাভাবে কাজ করে তবে এখনও ভুলভাবে। উদাহরণস্বরূপ compression resistance priority/ যখন hugging priorityপ্রয়োজনীয় (1000) সেট করা থাকে, তখনও ইন্টারফেস বিল্ডার সেলটি ফিট করার জন্য একটি লেবেল প্রসারিত বা ক্লিপ করতে পারে (লেবেলের চারপাশে ফিট করার জন্য সেলের উচ্চতার আকার পরিবর্তনের পরিবর্তে)। এবং এই জাতীয় ক্ষেত্রে এটি কোনও অটোলআউট সতর্কতা বা ত্রুটিও না দেখায়। বা কখনও কখনও এটি Xcode 7.x ঠিক কি করেছিল, উপরে বর্ণিত does


হাই, গতিশীল কোষের সামগ্রী সহ কক্ষের সাথে টেবিলভিউ থাকা কক্ষের জন্য গতিশীল উচ্চতা দেওয়া সম্ভব?
জিগনেশ বি

18

সারি উচ্চতা এবং আনুমানিক সারি উচ্চতার জন্য স্বয়ংক্রিয় মাত্রা সেট করতে, সেল / সারি উচ্চতার বিন্যাসের জন্য স্বয়ংক্রিয় মাত্রা কার্যকর করার জন্য নিম্নলিখিত পদক্ষেপগুলি নিশ্চিত করুন।

  • টেবিলভিউ ডেটাসোর্স এবং প্রতিনিধি নির্ধারণ ও প্রয়োগ করুন
  • UITableViewAutomaticDimensionরো-হাইট এবং আনুমানিকরোহাইটের জন্য বরাদ্দ করুন
  • প্রতিনিধি / ডেটাসোর্স পদ্ধতিগুলি প্রয়োগ করুন (যেমন heightForRowAtএবং UITableViewAutomaticDimensionএটিতে কোনও মান ফেরত দিন)

-

উদ্দেশ্য গ:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return UITableViewAutomaticDimension;
}

সুইফট:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

ইউআইটিএবলভিউসেলতে লেবেলের উদাহরণের জন্য

  • লাইনের সংখ্যা = 0 নির্ধারণ করুন (& লাইন ব্রেক ব্রেক = টুকরো টুকরো)
  • এর তত্ত্বাবধান / সেল ধারক সম্পর্কিত সমস্ত প্রতিবন্ধকতা (উপরে, নীচে, ডান বাম) সেট করুন।
  • Alচ্ছিক : কোনও ডেটা না থাকলেও আপনি ন্যূনতম উল্লম্ব অঞ্চলটি লেবেল দ্বারা আচ্ছাদিত চাইলে লেবেলের জন্য সর্বনিম্ন উচ্চতা নির্ধারণ করুন।

এখানে চিত্র বর্ণনা লিখুন

দ্রষ্টব্য : যদি আপনার ডায়নামিক দৈর্ঘ্যের একাধিক লেবেল (UIE উপাদান) থাকে তবে এটির বিষয়বস্তুর আকার অনুসারে সামঞ্জস্য করা উচিত: যে লেবেলগুলিকে আপনি উচ্চ অগ্রাধিকার দিয়ে প্রসারিত / সংকোচিত করতে চান তার জন্য 'সামগ্রী আলিঙ্গন এবং সংক্ষেপণ প্রতিরোধ অগ্রাধিকার' সামঞ্জস্য করুন।


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

@ জেরেমি অ্যান্ড্রুজ শিওর আপনাকে সাহায্য করবে। আপনার চেষ্টা করা উত্স কোড এবং সমস্যা সম্পর্কে বিস্তারিত সহ আপনার প্রশ্ন উত্থাপন করুন।
ক্রুনাল

এটি tableView: heightForRowডেটাসোর্স বাস্তবায়ন না করে আমার পক্ষে কাজ করছে ।
হেমং

@ হেমাং - আইওএস 11+ যেহেতু এটি কাজ করে না tableView: heightForRow। (আইওএস 10- এর tableView: heightForRowজন্য প্রয়োজনীয়)
ক্রুনাল

1
@ হেমাং - সমাধান সঠিক কোয়েরির সংজ্ঞা উপর নির্ভর করে। আপনার প্রশ্নের জন্য আমি এখানে সাধারণ সাধারণ সমাধান করেছি। অবস্থার ভিতরে রাখুন tableView: heightForRow..if (indexPath.row == 0) { return 100} else { return UITableView.automaticDimension }
ক্রুনাল

16

@ বব-স্প্রিনের মতো আমি একটি গুরুত্বপূর্ণ পর্যায়ে গেচচা করেছিলাম যে আমি এটি একটি উত্তর হিসাবে পোস্ট করছি।

আমি @ স্মাইলিবার্গের উত্তরটির সাথে কিছুক্ষণ লড়াই করেছি। Gotcha হয় যে আমি গাড়ীতে আঘাত যদি আপনি অতিরিক্ত উপাদান (সঙ্গে আইবি আপনার প্রোটোটাইপ সেল সংজ্ঞায়িত করেছি UILabels, UIButtonsআইবি, ইত্যাদি) যখন আপনার সাথে [সেল instantiate [YourTableViewCellClass alloc] init]এটা যে কোষের মধ্যে সব অন্যান্য উপাদানের instantiate না যদি না আপনি করেছি এটা করার জন্য লিখিত কোড। (এর সাথে আমারও একই অভিজ্ঞতা হয়েছিল initWithStyle।)

স্টোরিবোর্ডটি ইনস্টল করার জন্য অতিরিক্ত সমস্ত উপাদান আপনার কক্ষটি গ্রহণ করে [tableView dequeueReusableCellWithIdentifier:@"DoseNeeded"](এটি [tableView dequeueReusableCellWithIdentifier:forIndexPath:]মজাদার সমস্যাগুলির কারণ হবেনা)) আপনি যখন এই কাজটি করেন আইবিতে আপনি নির্ধারিত সমস্ত উপাদান তাত্ক্ষণিকভাবে চালু করা হবে।


15

গতিশীল টেবিল ভিউ সেল উচ্চতা এবং অটো লেআউট

স্টোরিবোর্ড অটো লেআউট দ্বারা সমস্যাটি সমাধানের একটি ভাল উপায়:

- (CGFloat)heightForImageCellAtIndexPath:(NSIndexPath *)indexPath {
  static RWImageCell *sizingCell = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sizingCell = [self.tableView dequeueReusableCellWithIdentifier:RWImageCellIdentifier];
  });

  [sizingCell setNeedsLayout];
  [sizingCell layoutIfNeeded];

  CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
  return size.height;
}

1
এটি ইতিমধ্যে এই প্রশ্নের গৃহীত উত্তরে বিস্তৃত হয়েছে।
স্মাইলিবার্গ

2
হ্যাঁ, আমি জানি ... তবে আমি পিওরলাইআউট এবং প্রেরণ_অনসেস 'ট্রিক' ব্যবহার করে আমাকে অনেকটাই সহায়তা করতে চাইনি, কেবল স্টোরিবোর্ড ব্যবহার করে এটি ব্যবহার করতে।
মোহনসম


13

অন্য একটি "সমাধান": এই সমস্ত হতাশাকে এড়িয়ে যান এবং ইউআইটিএলভিউয়ের সাথে সাদৃশ্যপূর্ণ বলে মনে হয় এমন ফলাফল পাওয়ার জন্য একটি ইউআইএসক্রোলভিউ ব্যবহার করুন।

আমার জন্য এটি বেদনাদায়ক "সমাধান" ছিল, যা আক্ষরিকভাবে 20+ খুব হতাশার সময় দেওয়ার পরে স্মাইলিবার্গের পরামর্শ মতো অনেক কিছু তৈরি করার চেষ্টা করেছিল এবং অ্যাপ স্টোর প্রকাশের তিন মাস ধরে তিনটি সংস্করণে ব্যর্থ হয়েছিল।

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

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

এটি কীভাবে করবেন সে সম্পর্কে এখানে কিছু টিপস:

  1. স্টোরিবোর্ড বা একটি নিব ফাইল ব্যবহার করে একটি ভিউকন্ট্রোলার এবং সম্পর্কিত রুট ভিউ তৈরি করুন।

  2. আপনার মূল দৃশ্যের উপরে একটি ইউআইএসক্রোলভিউয়ের উপরে টানুন।

  3. শীর্ষ-স্তরের দৃশ্যে শীর্ষ, নীচে, বাম এবং ডান সীমাবদ্ধতা যুক্ত করুন যাতে ইউআইএসক্রোলভিউ পুরো রুট ভিউ পূরণ করে।

  4. ইউআইএসক্রোলভিউয়ের ভিতরে একটি ইউআইভিউ যুক্ত করুন এবং এটিকে "ধারক" বলুন। ইউআইএসক্রোলভিউতে (এর প্যারেন্ট) শীর্ষ, নীচে, বাম এবং ডান সীমাবদ্ধতা যুক্ত করুন। মূল ট্রিক: ইউআইএসক্রোলভিউ এবং ইউআইভিউউকে লিঙ্ক করতে একটি "সমান প্রস্থ" সীমাবদ্ধতা যুক্ত করুন।

    দ্রষ্টব্য: আপনি একটি ত্রুটি পাবেন "স্ক্রোল ভিউটিতে দ্বিপাক্ষিক স্ক্রোলযোগ্য সামগ্রীর উচ্চতা রয়েছে" এবং আপনার ধারক ইউআইভিউউউটি 0 পিক্সেলের উচ্চতা হওয়া উচিত। অ্যাপটি চলাকালীন ত্রুটির কোনও বিষয় মনে হচ্ছে না।

  5. আপনার প্রতিটি "সেল" এর জন্য নিব ফাইল এবং নিয়ন্ত্রক তৈরি করুন। ইউআইভিউউ ইউআইটিএবল ভিউসেল নয় ব্যবহার করুন।

  6. আপনার রুট ভিউকন্ট্রোলারে, আপনি প্রয়োজনীয়ভাবে সমস্ত "সারিগুলি" ধারক ইউআইভিউতে যুক্ত করুন এবং প্রোগ্রামগতভাবে তাদের বাম এবং ডান প্রান্তগুলি ধারক দৃশ্যের সাথে সংযুক্ত করে, তাদের শীর্ষ প্রান্তটি হয় কনটেইনার ভিউ শীর্ষে (প্রথম আইটেমের জন্য) বা পূর্ববর্তী অংশে যুক্ত করুন কক্ষ। তারপরে কনটেইনার নীচে চূড়ান্ত কক্ষটি লিঙ্ক করুন।

আমাদের জন্য, প্রতিটি "সারি" একটি নিব ফাইলের মধ্যে রয়েছে। কোডটি দেখতে এরকম কিছু দেখাচ্ছে:

class YourRootViewController {

    @IBOutlet var container: UIView! //container mentioned in step 4

    override func viewDidLoad() {

        super.viewDidLoad()

        var lastView: UIView?
        for data in yourDataSource {

            var cell = YourCellController(nibName: "YourCellNibName", bundle: nil)
            UITools.addViewToTop(container, child: cell.view, sibling: lastView)
            lastView = cell.view
            //Insert code here to populate your cell
        }

        if(lastView != nil) {
            container.addConstraint(NSLayoutConstraint(
                item: lastView!,
                attribute: NSLayoutAttribute.Bottom,
                relatedBy: NSLayoutRelation.Equal,
                toItem: container,
                attribute: NSLayoutAttribute.Bottom,
                multiplier: 1,
                constant: 0))
        }

        ///Add a refresh control, if you want - it seems to work fine in our app:
        var refreshControl = UIRefreshControl()
        container.addSubview(refreshControl!)
    }
}

এবং এখানে ইউআইটিউলস.এডিডিভিউটো টোটোপের কোড রয়েছে:

class UITools {
    ///Add child to container, full width of the container and directly under sibling (or container if sibling nil):
    class func addViewToTop(container: UIView, child: UIView, sibling: UIView? = nil)
    {
        child.setTranslatesAutoresizingMaskIntoConstraints(false)
        container.addSubview(child)

        //Set left and right constraints so fills full horz width:

        container.addConstraint(NSLayoutConstraint(
            item: child,
            attribute: NSLayoutAttribute.Leading,
            relatedBy: NSLayoutRelation.Equal,
            toItem: container,
            attribute: NSLayoutAttribute.Left,
            multiplier: 1,
            constant: 0))

        container.addConstraint(NSLayoutConstraint(
            item: child,
            attribute: NSLayoutAttribute.Trailing,
            relatedBy: NSLayoutRelation.Equal,
            toItem: container,
            attribute: NSLayoutAttribute.Right,
            multiplier: 1,
            constant: 0))

        //Set vertical position from last item (or for first, from the superview):
        container.addConstraint(NSLayoutConstraint(
            item: child,
            attribute: NSLayoutAttribute.Top,
            relatedBy: NSLayoutRelation.Equal,
            toItem: sibling == nil ? container : sibling,
            attribute: sibling == nil ? NSLayoutAttribute.Top : NSLayoutAttribute.Bottom,
            multiplier: 1,
            constant: 0))
    }
}

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

আপনি যদি আপনার কক্ষগুলির মধ্যে বিভাজক চান, কেবল আপনার কাস্টম "সেল" এর নীচে একটি 1 পিক্সেল উচ্চ ইউআইভিউ যুক্ত করুন যা একটি ডিভাইডারের মতো দেখায়।

রিফ্রেশ নিয়ন্ত্রণের কাজ করার জন্য "বাউন্স" এবং "উলম্বভাবে বাউন্স" চালু করার বিষয়ে নিশ্চিত হন এবং তাই এটি আরও একটি টেবিলভিউয়ের মতো বলে মনে হয়।

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

এখানে আশা করা হচ্ছে যে অন্য কোনও প্রোগ্রামার আমার পোস্টটি পড়ার আগে তাদের নিজস্ব অ্যাপ্লিকেশনে টেবিল ভিউ দিয়ে এটি বের করার চেষ্টা করে 20+ ঘন্টা নষ্ট করে। :)


11

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

তারপরে আমি যুক্ত করলাম

[cell layoutSubviews];

মৃত্যুদন্ড কার্যকর করার আগে

[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];

এর পরে লেবেলের প্রস্থ প্রত্যাশার মতো এবং গতিশীল উচ্চতা ডান গণনা করা হয়েছিল।


9

ধরা যাক আপনার একটি সাবউভিউ সহ একটি ঘর আছে এবং আপনি চান যে ঘরের উচ্চতা সাবউভিউ + প্যাডিংকে অন্তর্ভুক্ত করার জন্য যথেষ্ট উচ্চতর হোক।

1) সেলবন্টেন্টভিউ বিয়োগ প্যাডিংয়ের সমান সাবভিউয়ের নীচের সীমাবদ্ধতা সেট করুন। সেল বা সেল.কমেন্টভিউ নিজেই বাধা সেট করবেন না।

2) সেট পারেন tableView এর rowHeightসম্পত্তি বা tableView:heightForRowAtIndexPath:করতে UITableViewAutomaticDimension

3) টেবিলভিউর estimatedRowHeightসম্পত্তি বা tableView:estimatedHeightForRowAtIndexPath:উচ্চতার সেরা অনুমানের জন্য সেট করুন।

এটাই.


7

আপনি যদি প্রোগ্রামক্রমে লেআউট করেন তবে সুইফটে অ্যাঙ্কারগুলি ব্যবহার করে আইওএস 10 এর জন্য কী বিবেচনা করা উচিত তা এখানে।

তিনটি নিয়ম / পদক্ষেপ রয়েছে

নম্বর 1: ভিউডিডলয়েডে টেবিলভিউয়ের এই দুটি বৈশিষ্ট্য সেট করুন, প্রথমটি টেবিলভিউকে বলছে যা তাদের কোষগুলিতে গতিশীল আকারের আশা করতে পারে, দ্বিতীয়টি কেবল অ্যাপ্লিকেশনটিকে স্ক্রোলবার সূচকটির আকার গণনা করতে দেয়, তাই এটির জন্য সহায়তা করে কর্মক্ষমতা.

    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 100

নম্বর 2: এটি গুরুত্বপূর্ণ যে আপনার ঘরের কনটভিউতে সাবউভিউগুলি ভিউয়ের সাথে যোগ করা উচিত নয়, এবং উপরের এবং নীচে সাব-ভিউগুলি অ্যাঙ্কর করার জন্য এর লেআউটমার্জগাইডও ব্যবহার করুন এটি কীভাবে এটি করা যায় তার একটি কার্যকারী উদাহরণ example

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    setUpViews()
}

private func setUpViews() {

    contentView.addSubview(movieImageView)
    contentView.addSubview(descriptionLabel)
    let marginGuide = contentView.layoutMarginsGuide

    NSLayoutConstraint.activate([
        movieImageView.heightAnchor.constraint(equalToConstant: 80),
        movieImageView.widthAnchor.constraint(equalToConstant: 80),
        movieImageView.leftAnchor.constraint(equalTo: marginGuide.leftAnchor),
        movieImageView.topAnchor.constraint(equalTo: marginGuide.topAnchor, constant: 20),

        descriptionLabel.leftAnchor.constraint(equalTo: movieImageView.rightAnchor, constant: 15),
        descriptionLabel.rightAnchor.constraint(equalTo: marginGuide.rightAnchor),
        descriptionLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor, constant: -15),
        descriptionLabel.topAnchor.constraint(equalTo: movieImageView.topAnchor)

        ])
}

এমন একটি পদ্ধতি তৈরি করুন যা সংক্ষিপ্তসারগুলি যুক্ত করবে এবং বিন্যাসটি সম্পাদন করবে, তাকে ডিআর পদ্ধতিতে কল করবে।

নম্বর 3: পদ্ধতিতে কল করবেন না:

  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    }

আপনি যদি এটি করেন তবে আপনি নিজের প্রয়োগটিকে ওভাররাইড করবেন।

টেবিলভিউগুলিতে গতিশীল কক্ষগুলির জন্য এই 3 টি নিয়ম অনুসরণ করুন।

এখানে একটি কার্যকরী বাস্তবায়ন https://github.com/jamesrochabrun/ মিনিমালভিউকন্ট্রোলার


সুইফটে 5 ইউআইটিএবলভিউআউটমেটিক মাত্রাটির নাম পরিবর্তন করে ইউআইটিবেল ভিউ.আউটমেটিক ডাইমেনশন
জেমস রোচাব্রুন

4

যদি আপনার একটি দীর্ঘ স্ট্রিং থাকে। যেমন এক যা নেই একটি লাইন বিরতি আছে। তাহলে আপনি কিছু সমস্যা হতে পারে।

"অভিযুক্ত" ফিক্সটি গৃহীত উত্তর এবং আরও কয়েকটি উত্তর দ্বারা উল্লিখিত হয়। আপনাকে কেবল যুক্ত করতে হবে

cell.myCellLabel.preferredMaxLayoutWidth = tableView.bounds.width

আমি সুরার উত্তরটি সবচেয়ে সম্পূর্ণ এবং সংক্ষিপ্তভাবে পাই , তাই বিভ্রান্তিকর নয়।

যদিও এই পরিবর্তনগুলির প্রয়োজন কেন তা ব্যাখ্যা না করে। আসুন এটি করা যাক।

একটি প্রকল্পে নিম্নলিখিত কোডটি ড্রপ করুন।

import UIKit

class ViewController: UIViewController {

    lazy var label : UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.backgroundColor = .red
        lbl.textColor = .black
        return lbl
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // step0: (0.0, 0.0)
        print("empty Text intrinsicContentSize: \(label.intrinsicContentSize)")
        // ----------
        // step1: (29.0, 20.5)
        label.text = "hiiiii"
        print("hiiiii intrinsicContentSize: \(label.intrinsicContentSize)")
        // ----------
        // step2: (328.0, 20.5)
        label.text = "translatesAutoresizingMaskIntoConstraints"
        print("1 translate intrinsicContentSize: \(label.intrinsicContentSize)")
        // ----------
        // step3: (992.0, 20.5)
        label.text = "translatesAutoresizingMaskIntoConstraints translatesAutoresizingMaskIntoConstraints translatesAutoresizingMaskIntoConstraints"
        print("3 translate intrinsicContentSize: \(label.intrinsicContentSize)")
        // ----------
        // step4: (328.0, 20.5)
        label.text = "translatesAutoresizingMaskIntoConstraints\ntranslatesAutoresizingMaskIntoConstraints\ntranslatesAutoresizingMaskIntoConstraints"
        print("3 translate w/ line breaks (but the line breaks get ignored, because numberOfLines is defaulted to `1` and it will force it all to fit into one line! intrinsicContentSize: \(label.intrinsicContentSize)")
        // ----------
        // step5: (328.0, 61.0)
        label.numberOfLines = 0
        print("3 translate w/ line breaks and '0' numberOfLines intrinsicContentSize: \(label.intrinsicContentSize)")
        // ----------
        // step6: (98.5, 243.5)
        label.preferredMaxLayoutWidth = 100
        print("3 translate w/ line breaks | '0' numberOfLines | preferredMaxLayoutWidth: 100 intrinsicContentSize: \(label.intrinsicContentSize)")

        setupLayout()
    }
    func setupLayout(){
        view.addSubview(label)
        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }
}

মনে রাখবেন যে আমি কোনও আকারের বাধা যুক্ত করি নি । আমি কেবলমাত্র সেন্টারএক্স, কেন্দ্রের সীমাবদ্ধতা যুক্ত করেছি। তবে এখনও লেবেলটি সঠিকভাবে আকার দেওয়া হবে কেন?

কারণ contentSize

এটির আরও ভাল প্রক্রিয়া করার জন্য, প্রথমে পদক্ষেপ 0 রাখুন, তারপরে 1-6 পদক্ষেপের বিষয়ে মন্তব্য করুন। থাকুক setupLayout()। আচরণটি পর্যবেক্ষণ করুন।

তারপরে অসাধারণ পদক্ষেপ 1 এবং পর্যবেক্ষণ করুন।

তারপরে অসাধারণ পদক্ষেপ 2 এবং পর্যবেক্ষণ করুন।

যতক্ষণ না আপনি সমস্ত 6 টি পদক্ষেপকে অসম্পূর্ণ করেছেন এবং তাদের আচরণগুলি পর্যবেক্ষণ করেছেন এটি না করুন।

এই সব থেকে উপসংহার কি হতে পারে? কি কারণ পরিবর্তন করতে পারেন contenSize?

  1. পাঠ্যের দৈর্ঘ্য: আপনার যদি দীর্ঘতর পাঠ্য থাকে তবে আপনার আন্তঃসংশ্লিষ্ট আকারের প্রস্থ বৃদ্ধি পাবে
  2. লাইন বিরতি: আপনি যদি যোগ করেন \nতবে অন্তর্নিবিজ্ঞাসমূহের প্রস্থ সমস্ত লাইনের সর্বাধিক প্রস্থ হবে। যদি একটি লাইনের 25 টি অক্ষর থাকে, অন্যটিতে 2 টি অক্ষর থাকে এবং অন্যটিতে 21 টি বর্ণ থাকে তবে আপনার প্রস্থটি 25 টি অক্ষরের ভিত্তিতে গণনা করা হবে
  3. অনুমতি লাইনের সংখ্যা: আপনি সেট করতে হবে numberOfLinesকরতে 0অন্যথায় আপনি একাধিক লাইন থাকবে না। আপনার numberOfLinesআপনার আন্তঃসংশ্লিষ্ট আকারের উচ্চতা সামঞ্জস্য করবে
  4. সামঞ্জস্য করা: আপনার পাঠ্যের উপর ভিত্তি করে কল্পনা করুন যে আপনার অভ্যন্তরীণ কন্টেন্টসাইজের প্রস্থ ছিল 200এবং উচ্চতা ছিল 100তবে আপনি প্রস্থটি লেবেলের ধারকটিতে সীমাবদ্ধ করতে চেয়েছিলেন আপনি কী করতে চলেছেন? সমাধানটি পছন্দসই প্রস্থে সেট করা। আপনি এটি সেটিং preferredMaxLayoutWidthকরে 130তা করে আপনার নতুন অন্তর্নিবিজ্ঞানটির আকার প্রায় প্রশস্ত হবে 130। উচ্চতা স্পষ্টতই বেশি হবে 100কারণ আপনার আরও লাইন প্রয়োজন। এটি বলা হচ্ছে যদি আপনার সীমাবদ্ধতাগুলি সঠিকভাবে সেট করা থাকে তবে আপনার এটি ব্যবহার করার দরকার নেই! তার আরও তথ্যের জন্য এই উত্তর এবং এর মন্তব্যগুলি দেখুন। আপনার কেবলমাত্র তখনই ব্যবহার করতে হবে preferredMaxLayoutWidthযখন আপনার প্রস্থ / উচ্চতা সীমাবদ্ধ করার সীমাবদ্ধতা না থাকলে কারওর মধ্যে বলা যেতে পারে যে "পাঠ্যটি মোড়বেন না যদি না এটি সীমা ছাড়িয়ে যায়preferredMaxLayoutWidth"। আপনি নেতৃস্থানীয় / trailing এবং সেট কিন্তু 100% নিশ্চিতভাবে numberOfLinesকরতে 0তারপর তুমি ভাল! লং সংক্ষিপ্ত বিবরণ তাদেরকে এখানে উত্তর যার ফলে এটি ব্যবহার করার প্রস্তাব দিই ভুল! আপনি এটা প্রয়োজন হবে না। প্রয়োজন ছিল এটি ইঙ্গিত দেয় যে আপনার সীমাবদ্ধতা সঠিকভাবে সেট করা নেই বা আপনার কেবল বাধা নেই

  5. হরফ আকার: এছাড়াও মনে রাখবেন যে আপনি যদি আপনার ফন্টসাইজ বাড়িয়ে দেন তবে ইন্টারসনিকসন্টেন্টসাইজের উচ্চতা বৃদ্ধি পাবে। আমি আমার কোডে এটি প্রদর্শন করিনি। আপনি নিজে থেকে এটি চেষ্টা করতে পারেন।

সুতরাং আপনার টেবিলভিউকেলে উদাহরণটিতে ফিরে যান:

আপনাকে যা করতে হবে তা হ'ল:

  • সেট numberOfLinesথেকে0
  • মার্জিন / প্রান্তগুলিতে লেবেলটি সঠিকভাবে সীমাবদ্ধ করুন
  • সেট করার দরকার নেই preferredMaxLayoutWidth

1

আমার ক্ষেত্রে আমাকে একটি চিত্র সহ একটি কাস্টম সেল তৈরি করতে হবে যা সার্ভার থেকে আসছে এবং কোনও প্রস্থ এবং উচ্চতা হতে পারে। এবং গতিশীল আকারের (দুটি প্রস্থ এবং উচ্চতা) সহ দুটি ইউআইবিবেল

আমি আমার উত্তরটিতে অটোলেআউট এবং প্রোগ্রামগতভাবে এটি অর্জন করেছি:

মূলত উপরের @ সাইলিবার্গের উত্তরটি সাহায্য করেছে তবে সিস্টেমলাউটসাইজ ফিটিংসাইজ কখনও আমার পক্ষে কাজ করেনি, আমার পদ্ধতির ক্ষেত্রে:

1. স্বয়ংক্রিয় সারি উচ্চতা গণনা সম্পত্তি ব্যবহার না। 2. আনুমানিক উচ্চতার কোনও ব্যবহার নেই 3. অপ্রয়োজনীয় আপডেটকন্ট্রেন্টগুলির প্রয়োজন নেই। ৪. স্বয়ংক্রিয় পছন্দসই সর্বোচ্চ লেআউটের প্রস্থের কোনও ব্যবহার নেই। ৫. সিস্টেমলাউটসাইজ ফাইটিংসাইজের কোনও ব্যবহার (আমার পক্ষে ব্যবহার করা উচিত নয় তবে আমার পক্ষে কাজ করা উচিত, আমি অভ্যন্তরীণভাবে এটি কী করছে তা আমি জানি না), পরিবর্তে আমার পদ্ধতি - (ভাসা) ভিউহাইট কাজ করছে এবং আমি জানি যে এটি অভ্যন্তরীণভাবে কী করছে।

আমি যখন ঘরটি প্রদর্শন করার বিভিন্ন উপায় ব্যবহার করি তখন কি কোনও ইউআইটিএবলভিউ সেলটিতে আলাদা উচ্চতা পাওয়া সম্ভব?


1

আমার ক্ষেত্রে, প্যাডিংটি বিভাগ হিডার এবং বিভাগফুটরের উচ্চতাগুলির কারণে ছিল, যেখানে স্টোরিবোর্ড আমাকে এটিকে ন্যূনতম 1 এ পরিবর্তন করার অনুমতি দেয় So

tableView.sectionHeaderHeight = 0
tableView.sectionFooterHeight = 0

1

আমি শুধু এর 2 মান সঙ্গে কিছু বোবা চেষ্টা এবং ত্রুটি করেনি rowHeightএবং estimatedRowHeightএবং মাত্র এটি কিছু ডিবাগ অন্তর্দৃষ্টি প্রদান পারে চিন্তা:

আপনি যদি উভয় সেট করেন বা কেবল সেট করেন তবে estimatedRowHeightআপনি পছন্দসই আচরণ পাবেন:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 1.00001 // MUST be greater than 1

এটি প্রস্তাবিত যে সঠিক অনুমানটি পেতে আপনার যথাসাধ্য চেষ্টা করুন, তবে শেষ ফলাফলটি আলাদা নয়। এটি কেবল আপনার কর্মক্ষমতা প্রভাবিত করবে।

এখানে চিত্র বর্ণনা লিখুন


আপনি যদি কেবলমাত্র সারিটি সেট করেন তবে কেবলমাত্র করুন:

tableView.rowHeight = UITableViewAutomaticDimension

আপনার শেষ ফলাফলটি পছন্দ মতো হবে না:

এখানে চিত্র বর্ণনা লিখুন


আপনি যদি estimatedRowHeight1 বা তার চেয়ে কম সেট করে থাকেন তবে আপনি নির্বিশেষে ক্র্যাশ হয়ে যাবেন rowHeight

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 1 

আমি নিম্নলিখিত ত্রুটি বার্তাটি দিয়ে ক্র্যাশ করেছি:

Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'table view row height
must not be negative - provided height for index path (<NSIndexPath:
0xc000000000000016> {length = 2, path = 0 - 0}) is -1.000000'
    ...some other lines...

libc++abi.dylib: terminating with uncaught exception of type
NSException

1

@ স্মাইলিবার্গের গৃহীত উত্তর সম্পর্কে, আমি খুঁজে পেয়েছি

[cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]

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

-(CGFloat)systemLayoutHeightForWidth:(CGFloat)w{
    [self setNeedsLayout];
    [self layoutIfNeeded];
    CGSize size = [self systemLayoutSizeFittingSize:CGSizeMake(w, 1) withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityFittingSizeLevel];
    CGFloat h = size.height;
    return h;
}

যেখানে ডাবলু: টেবিলভিউয়ের প্রস্থ


0

আপনার ভিউকন্ট্রোলারে কেবল এই দুটি ফাংশন যুক্ত করুন এটি আপনার সমস্যার সমাধান করবে। এখানে তালিকাটি একটি স্ট্রিং অ্যারে যা আপনার প্রতিটি সারিটির স্ট্রিং ধারণ করে।

 func tableView(_ tableView: UITableView, 
   estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        tableView.rowHeight = self.calculateHeight(inString: list[indexPath.row])

    return (tableView.rowHeight) 
}

func calculateHeight(inString:String) -> CGFloat
{
    let messageString = input.text
    let attributes : [NSAttributedStringKey : Any] = [NSAttributedStringKey(rawValue: NSAttributedStringKey.font.rawValue) : UIFont.systemFont(ofSize: 15.0)]

    let attributedString : NSAttributedString = NSAttributedString(string: messageString!, attributes: attributes)

    let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

    let requredSize:CGRect = rect
    return requredSize.height
}

-1
swift 4

    @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var tableView: UITableView!
    private var context = 1
 override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.addObserver(self, forKeyPath: "contentSize", options: [.new,.prior], context: &context)
    }
  // Added observer to adjust tableview height based on the content

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if context == &self.context{
            if let size = change?[NSKeyValueChangeKey.newKey] as? CGSize{
                print("-----")
                print(size.height)
                tableViewHeightConstraint.constant = size.height + 50
            }
        }
    }

//Remove observer
 deinit {

        NotificationCenter.default.removeObserver(self)

    }

-1

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

পুনশ্চ. সেল অবজেক্ট উত্পন্ন করার জন্য কোডটি অন্য টেবিল ভিউ সেল ডেলিগেট পদ্ধতি কল করার জন্য অন্য পদ্ধতিতে সংজ্ঞায়িত করা যেতে পারে।


-3

UITableView.automaticDimension ইন্টারফেস বিল্ডারের মাধ্যমে সেট করা যেতে পারে:

এক্সকোড> স্টোরিবোর্ড> আকার পরিদর্শক

সারণী দর্শন ঘর> সারি উচ্চতা> স্বয়ংক্রিয়

আকার পরিদর্শক


-4

সুইফটে এখনও অন্য আইওএস 7 + আইওএস 8 সমাধান

var cell2height:CGFloat=44

override func viewDidLoad() {
    super.viewDidLoad()
    theTable.rowHeight = UITableViewAutomaticDimension
    theTable.estimatedRowHeight = 44.0;
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell =  tableView.dequeueReusableCellWithIdentifier("myTableViewCell", forIndexPath: indexPath) as! myTableViewCell
    cell2height=cell.contentView.height
    return cell
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if #available(iOS 8.0, *) {
        return UITableViewAutomaticDimension
    } else {
        return cell2height
    }
}

দ্রষ্টব্য: সিস্টেমলআউটসাইজ ফিটিংসাইজ আমার ক্ষেত্রে কাজ করে না
djdance

কক্ষের উচ্চতা সঠিক নয় cellForRowAtIndexPath, ঘরটি এখনও এই মুহুর্তে নির্ধারণ করা হয়নি।
আন্দ্রে চেরেনকো

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