ගතික සෛල පිරිසැලසුම් සහ විචල්‍ය පේළි උස සඳහා UITableView හි ස්වයංක්‍රීය පිරිසැලසුම භාවිතා කිරීම


1503

UITableViewCellසුමට අනුචලන කාර්ය සාධනයක් පවත්වා ගෙන යන අතරම, එක් එක් කොටුවේ අන්තර්ගතය සහ උපසිරැසි මඟින් පේළි උස (තමා / ස්වයංක්‍රීයව) තීරණය කිරීමට ඉඩ දීම සඳහා ඔබ මේස දර්ශනය තුළ ස්වයංක්‍රීය පිරිසැලසුම භාවිතා කරන්නේ කෙසේද ?


මෙන්න ස්විෆ්ට් 2.3 හි නියැදි කේතය github.com/dpakthakur/DynamicCellHeight
දීපක්

බහු UILabel එකක් තිබීම සම්බන්ධයෙන් බොහෝ පිළිතුරු තේරුම් ගැනීමට, කෙසේද contentSizeසහ preferredMaxLayoutWidthවැඩ කරන්නේ කෙසේද යන්න පිළිබඳ පූර්ණ අවබෝධයක් අවශ්‍ය වේ. මෙහි බලන්න . ඔබේ සීමාවන් නිවැරදිව සකසා ගන්නේ නම් ඔබට අවශ්‍ය නොවිය යුතු preferredMaxLayoutWidthඅතර ඇත්ත වශයෙන්ම අනපේක්ෂිත ප්‍රති .ල ඇති කළ හැකිය.
මී පැණි

ඔබගේ UILabel සඳහා 2020 සඳහා තීරණාත්මක ඉඟිය. එය බාධාවකින් වමට සම්බන්ධ කර ඇති බව පවසන්න. “ශුන්‍යයට වඩා වැඩි හෝ සමාන” අවහිරයකින් ඔබ එය දකුණට ඇමිණිය යුතුය .
ෆැට්ටි

Answers:


2396

ටීඑල්; ඩීආර්: කියවීමට කැමති නැද්ද? GitHub හි නියැදි ව්‍යාපෘති වෙත කෙලින්ම යන්න:

සංකල්පීය විස්තරය

ඔබ සංවර්ධනය කරන්නේ කුමන iOS අනුවාදයන් නොසලකා පහත පළමු පියවර 2 අදාළ වේ.

1. සීමාවන් සකසා එකතු කරන්න

ඔබේ UITableViewCellඋප පංතියේ, කොටුවේ අන්තර්ගතයන් දර්ශනයේ දාරවලට (වඩාත් වැදගත් ලෙස ඉහළ සහ පහළ දාරවලට ) සෛලවල උප දර්ශනවල දාර සවි කර ඇති පරිදි සීමාවන් එකතු කරන්න . සටහන: කොටුවටම උපසිරැසි නොතබන්න; සෛලයට පමණයි contentView! එක් එක් උපසිරැසි සඳහා සිරස් මානයන්හි අන්තර්ගත සම්පීඩන ප්‍රතිරෝධය සහ අන්තර්ගත වැළඳ ගැනීමේ බාධක ඔබ එකතු කළ ඉහළ ප්‍රමුඛතා බාධක මගින් අභිබවා නොයන බවට වග බලා ගැනීමෙන් මෙම උපසිරැසි වල සහජ අන්තර්ගත ප්‍රමාණය වගුවේ දර්ශන කොටුවේ අන්තර්ගත දර්ශනයේ උස වැඩි කිරීමට ඉඩ දෙන්න. ( හහ්? මෙහි ක්ලික් කරන්න. )

මතක තබා ගන්න, සෛලයේ උප දර්ශන සිරස් අතට සෛල අන්තර්ගතයට සම්බන්ධ කර ඇති අතර එමඟින් ඔවුන්ට “පීඩනය” යෙදිය හැකි අතර ඒවාට ගැලපෙන පරිදි අන්තර්ගත දර්ශනය පුළුල් කළ හැකිය. උපසිරැසි කිහිපයක් සහිත නිදර්ශන කොටුවක් භාවිතා කරමින් , ඔබේ අවහිරතා සමහරක් (සියල්ලම නොවේ!) මොන වගේ විය යුතුද යන්න පිළිබඳ දෘශ්‍ය නිදර්ශනයක් මෙන්න:

වගු දර්ශන කොටුවක ඇති බාධක පිළිබඳ උදාහරණ නිදර්ශනය.

ඉහත උදාහරණ කොටුවේ බහු-රේඛා ශරීර ලේබලය වෙත වැඩි පෙළක් එක් කරන විට, පෙළට සරිලන සේ එය සිරස් අතට වැඩීමට අවශ්‍ය වනු ඇති අතර එමඟින් සෛලය උසින් වැඩීමට බල කරයි. (ඇත්ත වශයෙන්ම, මෙය නිවැරදිව වැඩ කිරීම සඳහා ඔබ අවහිරතා නිවැරදිව ලබා ගත යුතුය!)

ස්වයංක්‍රීය පිරිසැලසුම සමඟ වැඩ කරන ගතික සෛල උස ලබා ගැනීමේ දුෂ්කරම හා වැදගත්ම කොටස වන්නේ ඔබේ සීමාවන් නිවැරදිව ලබා ගැනීමයි. ඔබ මෙහි වැරැද්දක් කළහොත්, අනෙක් සියල්ල වැඩ කිරීමෙන් වළක්වා ගත හැකිය - එබැවින් ඔබේ කාලය ගන්න! කේතයේ ඔබේ සීමාවන් සැකසීමට මම නිර්දේශ කරමි, කොතැනට එකතු කරන්නේ කුමන බාධකදැයි ඔබ හරියටම දන්නා නිසා සහ දේවල් වැරදුණු විට නිදොස් කිරීම පහසුය. කේතයේ සීමාවන් එකතු කිරීම පිරිසැලසුම් නැංගුරම් භාවිතා කරමින් අතුරුමුහුණත් සාදන්නාට වඩා පහසු සහ සැලකිය යුතු තරම් බලවත් විය හැකිය, නැතහොත් GitHub හි ඇති අපූරු විවෘත කේත API වලින් එකකි.

  • ඔබ කේතයේ සීමාවන් එකතු කරන්නේ නම්, ඔබ මෙය කළ යුත්තේ updateConstraintsඔබේ UITableViewCell උප පංතියේ ක්‍රමයෙනි. updateConstraintsඑක් වරකට වඩා වැඩි වාර ගණනක් කැඳවිය හැකි බව සලකන්න , එම අවහිරතා එක් වරකට වඩා එක් කිරීමෙන් වළක්වා ගැනීම සඳහා, ඔබේ අවහිරතා එකතු කිරීමේ කේතය updateConstraintsබූලියන් දේපලක් සඳහා චෙක්පතක් තුළ එතීමට වග බලා ගන්න didSetupConstraints(ඔබ ඔබේ සීමාව ක්‍රියාත්මක කිරීමෙන් පසු ඔව් ලෙස සකසා ඇත කේතය එක් වරක් එකතු කිරීම). අනෙක් අතට, ඔබට පවතින සීමාවන් යාවත්කාලීන කරන කේතයක් තිබේ නම් ( constantදේපල යම් යම් සීමාවන් මත සකස් කිරීම වැනි ), මෙය updateConstraintsචෙක්පතෙහි පිටත නමුත් පිටත තබන්න didSetupConstraintsඑවිට ක්‍රමවේදය කැඳවන සෑම අවස්ථාවකම එය ක්‍රියාත්මක විය හැකිය.

2. අද්විතීය වගු දර්ශන සෛල නැවත භාවිතා කිරීමේ හඳුනාගැනීම් තීරණය කරන්න

සෛලයේ ඇති සෑම අද්විතීය අවහිරතා සමූහයක් සඳහාම, අද්විතීය සෛල නැවත භාවිතා කිරීමේ හඳුනාගැනීමක් භාවිතා කරන්න. වෙනත් වචන වලින් කිවහොත්, ඔබේ සෛල වලට අද්විතීය පිරිසැලසුමක් තිබේ නම්, සෑම අද්විතීය පිරිසැලසුමකටම නැවත භාවිතා කිරීමේ හඳුනාගැනීමක් ලැබිය යුතුය. (ඔබ නව නැවත භාවිතා කිරීමේ හඳුනාගැනීමක් භාවිතා කළ යුතු බවට හොඳ ඉඟියක් වන්නේ ඔබේ සෛල ප්‍රභේදයට වෙනස් උපසිරැසි සංඛ්‍යාවක් ඇති විට හෝ උප දර්ශන වෙනස් ආකාරයකින් සකසා ඇති විටය.)

උදාහරණයක් ලෙස, ඔබ එක් එක් කොටුව තුළ විද්‍යුත් තැපැල් පණිවිඩයක් ප්‍රදර්ශනය කරන්නේ නම්, ඔබට අද්විතීය පිරිසැලසුම් 4 ක් තිබිය හැකිය: විෂයයක් සහිත පණිවිඩ, විෂයයක් සහ ශරීරයක් සහිත පණිවිඩ, විෂයයක් සහ ඡායාරූප ඇමුණුමක් සහ විෂයයක් සහිත පණිවිඩ, ශරීරය සහ ඡායාරූප ඇමුණුම. සෑම පිරිසැලසුමකටම එය සාක්ෂාත් කර ගැනීම සඳහා සම්පූර්ණයෙන්ම වෙනස් අවහිරතා ඇත, එබැවින් සෛලය ආරම්භ කර මෙම සෛල වර්ග වලින් එකක් සඳහා සීමාවන් එකතු කළ පසු, සෛලයට එම සෛල වර්ගයට විශේෂිත වූ නැවත භාවිතා කිරීමේ හඳුනාගැනීමක් ලබා ගත යුතුය. මෙයින් අදහස් කරන්නේ ඔබ නැවත භාවිතා කිරීම සඳහා සෛලයක් ඉවත් කරන විට, අවහිරතා දැනටමත් එකතු කර ඇති අතර එම සෛල වර්ගයට යාමට සූදානම් බවයි.

සහජ අන්තර්ගත ප්‍රමාණයෙහි වෙනස්කම් හේතුවෙන් එකම අවහිරතා (වර්ගය) ඇති සෛලවලට තවමත් වෙනස් උස තිබිය හැකි බව සලකන්න! විවිධ ප්‍රමාණයේ අන්තර්ගතයන් හේතුවෙන් මූලික වශයෙන් වෙනස් පිරිසැලසුම් (විවිධ සීමාවන්) විවිධ ගණනය කළ දර්ශන රාමු සමඟ (සමාන සීමාවන්ගෙන් විසඳනු ලැබේ) පටලවා නොගන්න.

  • එකම නැවත භාවිතා කරන සංචිතයට සම්පූර්ණයෙන්ම වෙනස් අවහිරතා සහිත සෛල එකතු නොකරන්න (එනම් එකම නැවත භාවිතා කිරීමේ හඳුනාගැනීමක් භාවිතා කරන්න) ඉන්පසු පැරණි අවහිරතා ඉවත් කර එක් එක් වර්‍ගයෙන් පසු මුල සිටම නව බාධක ඇති කිරීමට උත්සාහ කරන්න. අභ්‍යන්තර ස්වයංක්‍රීය පිරිසැලසුම් එන්ජිම සැලසුම් කර ඇත්තේ විශාල පරිමාණයේ වෙනස්කම් වලට මුහුණ දීම සඳහා නොවන අතර විශාල කාර්ය සාධන ගැටළු ඔබට පෙනෙනු ඇත.

IOS 8 සඳහා - ස්වයං ප්‍රමාණයේ සෛල

3. පේළි උස ඇස්තමේන්තු කිරීම සක්‍රීය කරන්න

ස්වයං-ප්‍රමාණ වගු දර්ශන සෛල සක්‍රීය කිරීම සඳහා, ඔබ මේස දර්ශනයේ පේළි උස දේපල UITableViewAutomaticDimension ලෙස සැකසිය යුතුය. ඇස්තමේන්තුගත රෝහයිට් දේපල සඳහා ඔබ වටිනාකමක් ලබා දිය යුතුය. මෙම ගුණාංග දෙකම සැකසූ විගස, පද්ධතිය ස්වයංක්‍රීය පිරිසැලසුම භාවිතා කර පේළියේ නියම උස ගණනය කරයි

ඇපල්: ස්වයං-ප්‍රමාණ වගු දර්ශන සෛල සමඟ වැඩ කිරීම

IOS 8 සමඟ, ඇපල් විසින් iOS 8 ට පෙර ඔබ විසින් ක්‍රියාවට නැංවිය යුතු බොහෝ කාර්යයන් අභ්‍යන්තරීකරණය කර ඇත. ස්වයං ප්‍රමාණයේ සෛල යාන්ත්‍රණය වැඩ කිරීමට ඉඩ දීම සඳහා, ඔබ පළමුව rowHeightමේස දර්ශනයේ ඇති දේපල නියතයට සැකසිය යුතුය. UITableViewAutomaticDimension. ඉන්පසුව, ඔබට වගු දර්ශනයේ estimatedRowHeightදේපල අස්ථිර අගයකට සැකසීම මඟින් පේළි උස තක්සේරු කිරීම සක්‍රීය කළ යුතුය, උදාහරණයක් ලෙස:

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

මෙය කරන්නේ තිරයේ නොමැති සෛලවල පේළි උස සඳහා තාවකාලික ඇස්තමේන්තුවක් / ස්ථානගත කිරීමක් මේස දර්ශනයට ලබා දීමයි. එවිට, මෙම සෛල තිරය මත අනුචලනය වීමට ආසන්න වන විට, සත්‍ය පේළි උස ගණනය කෙරේ. එක් එක් පේළිය සඳහා සත්‍ය උස තීරණය කිරීම සඳහා, වගු දර්ශනය ස්වයංක්‍රීයව එක් එක් සෛලයට contentViewඅන්තර්ගතයේ දර්ශනයේ දන්නා ස්ථාවර පළල මත පදනම්ව එහි උස කොපමණ දැයි විමසයි (එය වගු දර්ශනයේ පළල මත පදනම් වේ, අංශ දර්ශකය වැනි අමතර දේවල් us ණ කරයි හෝ උපාංග දර්ශනය) සහ ඔබ කොටුවේ අන්තර්ගත දර්ශනයට සහ උප දර්ශන වලට එකතු කර ඇති ස්වයංක්‍රීය පිරිසැලසුම් බාධක. මෙම සත්‍ය සෛල උස තීරණය කළ පසු, පේළිය සඳහා පැරණි ඇස්තමේන්තුගත උස නව තථ්‍ය උස සමඟ යාවත්කාලීන වේ (සහ වගු දර්ශනයේ අන්තර්ගතයේ ඕනෑම වෙනස් කිරීමක් ඔබට අවශ්‍ය පරිදි සකසා ඇත).

පොදුවේ ගත් කල, ඔබ සපයන ඇස්තමේන්තුව ඉතා නිවැරදි විය යුතු නැත - එය භාවිතා කරනුයේ වගු දර්ශනයේ ඇති අනුචලන දර්ශකය නිවැරදිව ප්‍රමාණ කිරීම සඳහා පමණක් වන අතර වගු දර්ශනය ඔබ මෙන් වැරදි ඇස්තමේන්තු සඳහා අනුචලන දර්ශකය සකස් කිරීමේ හොඳ කාර්යයක් කරයි. තිරය ​​මත සෛල අනුචලනය කරන්න. ඔබ estimatedRowHeightමේස දර්ශනයේ ඇති දේපල ( viewDidLoadසාමාන්‍ය හෝ පේළි උස) නියත අගයකට සැකසිය යුතුය . ඔබේ පේළි උසෙහි අතිශය විචල්‍යතාවයක් තිබේ නම් (උදා: විශාලත්වයේ අනුපිළිවෙලකින් වෙනස් වේ) සහ ඔබ අනුචලනය කරන විට අනුචලන දර්ශකය “පැනීම” ඔබ දුටුවහොත් tableView:estimatedHeightForRowAtIndexPath:පමණක් එක් එක් පේළිය සඳහා වඩාත් නිවැරදි ඇස්තමේන්තුවක් ලබා දීමට අවශ්‍ය අවම ගණනය කිරීම සිදු කිරීමට ඔබ කරදර විය යුතුය .

IOS 7 සහාය සඳහා (ස්වයංක්‍රීය සෛල ප්‍රමාණය ඔබම ක්‍රියාත්මක කිරීම)

3. පිරිසැලසුම් පාස් එකක් කර සෛල උස ලබා ගන්න

පළමුවෙන්ම, උස ගණනය කිරීම් සඳහා දැඩි ලෙස භාවිතා කරන එක් එක් නැවත භාවිතා කරන හඳුනාගැනීමේ එක් අවස්ථාවක් වන වගු දර්ශන කොටුවක ඕෆ්ස්ක්‍රීන් නිදසුනක් ක්ෂණිකව ස්ථාපනය කරන්න. (ඕෆ්ස්ක්‍රීන් යන්නෙන් අදහස් වන්නේ සෛල යොමුව දර්ශන පාලකයේ දේපල / අයිවරයක ගබඩා කර ඇති අතර එය tableView:cellForRowAtIndexPath:තිරය ​​මත තිරය පෙන්වීම සඳහා කිසි විටෙකත් ආපසු නොඑනු ඇත .) ඊළඟට, කොටුව නිශ්චිත අන්තර්ගතයෙන් වින්‍යාසගත කළ යුතුය (උදා: පෙළ, රූප, ආදිය) එය වගු දර්ශනයේ පෙන්වන්නේ නම් එය රඳවා තබන බව.

එවිට, කිරීමට සෛල බල වහාම එහි subviews පිරිසැලසුම, පසුව භාවිතා systemLayoutSizeFittingSize:මත ක්රමය UITableViewCellගේ contentViewසෛලය අවශ්ය උස යනු කුමක්ද කියා සොයා බැලීමට. UILayoutFittingCompressedSizeසෛලයේ සියලුම අන්තර්ගතයන්ට සරිලන සේ අවශ්‍ය කුඩාම ප්‍රමාණය ලබා ගැනීමට භාවිතා කරන්න . උස පසුව tableView:heightForRowAtIndexPath:නියෝජිත ක්‍රමයෙන් ආපසු ලබා ගත හැකිය .

4. ඇස්තමේන්තුගත පේළි උස භාවිතා කරන්න

ඔබගේ වගු දර්ශනයේ පේළි දුසිමකට වඩා තිබේ නම්, ස්වයංක්‍රීය පිරිසැලසුම් අවහිරතා විසඳීම මඟින් වගු දර්ශනය ප්‍රථමයෙන් පැටවීමේදී ප්‍රධාන නූලට වේගයෙන් ඇද වැටිය හැකි බව ඔබට පෙනී tableView:heightForRowAtIndexPath:යනු ඇත. අනුචලන දර්ශකයේ ප්‍රමාණය ගණනය කිරීම සඳහා).

IOS 7 වන විට, ඔබට estimatedRowHeightමේස දර්ශනයේ ඇති දේපල භාවිතා කළ හැකිය (සහ අනිවාර්යයෙන්ම) . මෙය කරන්නේ තිරයේ නොමැති සෛලවල පේළි උස සඳහා තාවකාලික ඇස්තමේන්තුවක් / ස්ථානගත කිරීමක් මේස දර්ශනයට ලබා දීමයි. එවිට, මෙම සෛල තිරය මත අනුචලනය වීමට ආසන්න වන විට, සත්‍ය පේළි උස ගණනය කරනු ලැබේ (ඇමතීමෙන් tableView:heightForRowAtIndexPath:), සහ ඇස්තමේන්තුගත උස සත්‍යය සමඟ යාවත්කාලීන වේ.

පොදුවේ ගත් කල, ඔබ සපයන ඇස්තමේන්තුව ඉතා නිවැරදි විය යුතු නැත - එය භාවිතා කරනුයේ වගු දර්ශනයේ ඇති අනුචලන දර්ශකය නිවැරදිව ප්‍රමාණ කිරීම සඳහා පමණක් වන අතර වගු දර්ශනය ඔබ මෙන් වැරදි ඇස්තමේන්තු සඳහා අනුචලන දර්ශකය සකස් කිරීමේ හොඳ කාර්යයක් කරයි. තිරය ​​මත සෛල අනුචලනය කරන්න. ඔබ estimatedRowHeightමේස දර්ශනයේ ඇති දේපල ( viewDidLoadසාමාන්‍ය හෝ පේළි උස) නියත අගයකට සැකසිය යුතුය . ඔබේ පේළි උසෙහි අතිශය විචල්‍යතාවයක් තිබේ නම් (උදා: විශාලත්වයේ අනුපිළිවෙලකින් වෙනස් වේ) සහ ඔබ අනුචලනය කරන විට අනුචලන දර්ශකය “පැනීම” ඔබ දුටුවහොත් tableView:estimatedHeightForRowAtIndexPath:පමණක් එක් එක් පේළිය සඳහා වඩාත් නිවැරදි ඇස්තමේන්තුවක් ලබා දීමට අවශ්‍ය අවම ගණනය කිරීම සිදු කිරීමට ඔබ කරදර විය යුතුය .

5. (අවශ්‍ය නම්) පේළි උස හැඹිලිය එක් කරන්න

ඔබ ඉහත සියල්ල කර ඇති අතර, බාධක විසඳීමේදී කාර්ය සාධනය පිළිගත නොහැකි ලෙස මන්දගාමී බව තවමත් සොයාගෙන තිබේ නම් tableView:heightForRowAtIndexPath:, අවාසනාවකට ඔබට සෛල උස සඳහා යම් හැඹිලියක් ක්‍රියාත්මක කිරීමට අවශ්‍ය වනු ඇත. (මෙය ඇපල් ඉංජිනේරුවන් විසින් යෝජනා කරන ලද ප්‍රවේශයයි.) සාමාන්‍ය අදහස නම් ස්වයංක්‍රීයව එන්ජිමට පළමු වරට බාධක විසඳීමට ඉඩ දීම, ඉන්පසු එම කොටුව සඳහා ගණනය කළ උස හැඹිලිගත කිරීම සහ එම සෛලයේ උස සඳහා අනාගත සියලු ඉල්ලීම් සඳහා හැඹිලි අගය භාවිතා කිරීමයි. ඇත්ත වශයෙන්ම උපක්‍රමය නම්, සෛලයක උස වෙනස් වීමට හේතු විය හැකි යමක් සිදු වූ විට ඔබ සෛලයක් සඳහා හැඹිලි උස ඉවත් කිරීමට වග බලා ගැනීමයි - මූලික වශයෙන්, මෙය සිදුවන්නේ එම සෛලයේ අන්තර්ගතය වෙනස් වන විට හෝ වෙනත් වැදගත් සිදුවීම් සිදු වූ විට (පරිශීලක සැකසීම වැනි) ගතික වර්ගයේ පෙළ ප්‍රමාණයේ ස්ලයිඩරය).

iOS 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;
    }
}

නියැදි ව්‍යාපෘති

මෙම ව්‍යාපෘති UILabels හි ගතික අන්තර්ගතයන් අඩංගු වගු දර්ශන සෛල නිසා විචල්‍ය පේළි උසකින් යුත් වගු දර්ශන සඳහා පූර්ණ ක්‍රියාකාරී උදාහරණ වේ.

Xamarin (C # /. NET)

ඔබ Xamarin භාවිතා කරන්නේ නම්, entKentBoogaart විසින් එකතු කරන ලද මෙම නියැදි ව්‍යාපෘතිය බලන්න .


1
මෙය හොඳින් ක්‍රියාත්මක වන අතර, අවශ්‍ය ප්‍රමාණයන් තරමක් ඇස්තමේන්තු කර ඇති බව මට පෙනේ (විවිධ වටකුරු ගැටලු නිසා විය හැක) සහ මගේ සියලුම පෙළ ලේබල් තුළට ගැලපෙන පරිදි අවසාන උසට ලකුණු කිහිපයක් එකතු කළ යුතුය
ඩීබීඩී

5
@ ඇලෙක්ස් 311 ඉතා රසවත්, මෙම උදාහරණය ලබා දීම ගැන ස්තූතියි. මම මගේ අවසානය ගැන කුඩා පරීක්ෂණයක් කර මෙහි අදහස් කිහිපයක් ලියා තැබුවෙමි
ස්මයිලිබෝග්

3
සෑම සෛල නැවත භාවිතා කිරීමේ හඳුනාගැනීමේ වර්ගයක් සඳහාම සෛල රඳවා ගැනීමට මම තරයේ නිර්දේශ කරමි. ඔබ උස සඳහා තට්ටු කරන සෑම අවස්ථාවකම ඔබ නැවත එකතු නොකරන පෝලිමේ සිට කොටුවක් රැගෙන යයි. හැඹිලි මඟින් ඔබේ වගු සෛල සඳහා ආරම්භක ලෙස හඳුන්වන වාර ගණන සැලකිය යුතු ලෙස අඩු කළ හැකිය. කිසියම් හේතුවක් නිසා, මම හැඹිලිගත නොකරන විට, භාවිතා කරන මතකයේ ප්‍රමාණය මා අනුචලනය වන පරිදි වර්ධනය වෙමින් පවතී.
ඇලෙක්ස් 311

1
කතන්දර පුවරු, ඇත්ත වශයෙන්ම. මූලාකෘති සෛල සඳහා එය ක්‍රියා කරයි යැයි මම නොසිතමි (අවම වශයෙන් සමස්ත VC නැවත ස්ථාපනය නොකර). තුළට කාන්දු වීම heightForRowAtIndexPath, සෛලය තබා ගැනීම සහ ඊළඟ වතාවේ එය නැවත ලබා දීමෙන් කාන්දුව සම්පූර්ණයෙන්ම වළක්වා ගත හැකිය cellForRowAtIndexPath.
nschum

2
යනු iOS8ක්රියාත්මක කිරීම තවමත් සඳහා නිර්දේශ iOS9හා iOS10, හෝ මෙම පිළිතුර ප්රකාශයට පත් කරන ලදී පටන් එහි නව ප්රවේශයන් ද?
koen

176

ඉහත iOS 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
}

නමුත් iOS 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
මම හිතන්නේ අපි OS8 නඩුවේ heightForRowAtIndexPath ශ්‍රිතය ක්‍රියාත්මක කිරීමට අවශ්‍ය නැහැ
jpulikkottil

Edddwinpaz වෙනත් පිළිතුරක සටහන් කර ඇති පරිදි, පේළි උසෙහි අගුලු දැමීමට භාවිතා කරන බාධකවලට ආන්තිකය ඇතුළත් නොවීම වැදගත්ය.
රිචඩ්

1
+1 සඳහා "බහු පේළි ලේබල් නම්, අංක ඕෆ්ලයින් 0 ලෙස සැකසීමට අමතක නොකරන්න" මෙය මගේ සෛල ප්‍රමාණයෙන් ගතික නොවීමට හේතු විය.
ඉයන්-ෆොගල්මන්

මට පාලක විහිළුවක් ලෙස අමතන්න, නමුත් iOS 11 දිනවල පවා මම තවමත් UITableViewAutomaticDimension භාවිතා කිරීමට කැමති නැත. අතීතයේ ඒ සමඟ නරක අත්දැකීම් තිබුනා. එනිසා මම සාමාන්‍යයෙන් මෙහි ලැයිස්තුගත කර ඇති iOS7 විසඳුම් භාවිතා කරමි. විලියම්ගේ සටහන ලේබලය අමතක නොකරන්න. PreferredMaxLayoutWidth මෙහි මා බේරා ගත්තේය.
බ්‍රයන් සචෙටා

අපි අනුචලනය කරන විට, ලේබලය පේළි කිහිපයකින් දිස්වීමට පටන් ගන්නා අතර පේළියේ උස ද වැඩි නොවේ
කරන්වීර් සිං

94

විචල්ය උස UITableViewCell සඳහා වේගවත් උදාහරණය

ස්විෆ්ට් 3 සඳහා යාවත්කාලීන කරන ලදි

විලියම් හූගේ ස්විෆ්ට් පිළිතුර හොඳයි, නමුත් පළමු වරට යමක් කිරීමට ඉගෙන ගන්නා විට සරල නමුත් සවිස්තරාත්මක පියවර කිහිපයක් ගැනීමට එය මට උපකාරී වේ. පහත දැක්වෙන උදාහරණය වන්නේ UITableViewවිචල්‍ය සෛල උසකින් යුත් එකක් සෑදීමට ඉගෙන ගන්නා අතරතුර මගේ පරීක්ෂණ ව්‍යාපෘතියයි . මම එය පදනම් කළේ ස්විෆ්ට් සඳහා මෙම මූලික UITableView උදාහරණය මත ය .

නිමි ව්‍යාපෘතිය මේ ආකාරයට විය යුතුය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

නව ව්‍යාපෘතියක් සාදන්න

එය තනි දර්ශන යෙදුමක් පමණක් විය හැකිය.

කේතය එක් කරන්න

ඔබේ ව්‍යාපෘතියට නව ස්විෆ්ට් ගොනුවක් එක් කරන්න. එයට MyCustomCell ලෙස නම් කරන්න. කතන්දර පුවරුවේ ඔබේ කොටුවට ඔබ එකතු කරන අදහස් සඳහා මෙම පන්තිය අලෙවිසැල් පවත්වනු ඇත. මෙම මූලික උදාහරණයේ දී අපට ඇත්තේ එක් සෛලයක එක් ලේබලයක් පමණි.

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

අපි පසුව මෙම අලෙවිසැල සම්බන්ධ කරමු.

ViewController.swift විවෘත කර ඔබට පහත අන්තර්ගතය ඇති බවට වග බලා ගන්න:

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

කතන්දර පුවරුව සකසන්න

ඔබගේ දර්ශන පාලකයට මේස දර්ශනයක් එක් කර ස්වයංක්‍රීය සැකැස්ම භාවිතා කර එය හතර පැත්තට ඇලවීම. ඉන්පසු මේස දර්ශනයට මේස දර්ශන කොටුවක් ඇදගෙන යන්න. මූලාකෘති කොටුවට ලේබලයක් අදින්න. වගු දර්ශන කොටුවේ අන්තර්ගත දර්ශනයේ දාර හතරට ලේබලය ඇලවීමට ස්වයංක්‍රීය පිරිසැලසුම භාවිතා කරන්න.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

වැදගත් සටහනක්:

  • මා ඉහත සඳහන් කළ කේතයේ වැදගත් පේළි දෙක සමඟ ස්වයංක්‍රීය පිරිසැලසුම ක්‍රියා කරයි. ඔබ ස්වයංක්‍රීය පිරිසැලසුම භාවිතා නොකරන්නේ නම් එය ක්‍රියාත්මක නොවේ.

වෙනත් IB සැකසුම්

අභිරුචි පන්තියේ නම සහ හැඳුනුම්පත

වගු දර්ශන කොටුව තෝරන්න සහ අභිරුචි පන්තිය ලෙස සකසන්න MyCustomCell(අප එකතු කළ ස්විෆ්ට් ගොනුවේ පන්තියේ නම). හැඳුනුම්පතද සකසන්න cell( cellReuseIdentifierඉහත කේතයේ අප භාවිතා කළ නූලම.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ලේබලය සඳහා ශුන්‍ය රේඛා

0ඔබේ ලේබලයේ ඇති පේළි ගණන සකසන්න . මෙයින් අදහස් කරන්නේ බහු රේඛාවක් වන අතර ලේබලය එහි අන්තර්ගතය මත පදනම්ව ප්‍රමාණය වෙනස් කිරීමට ඉඩ දෙයි.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

හක් අප් අලෙවිසැල්

  • කතන්දර පුවරුවේ ඇති වගු දර්ශනයේ සිට tableViewවිචල්‍යය වෙත ඇදගෙන යාම පාලනය කරන්නViewController කේතයේ කරන්න.
  • ඔබේ මූලාකෘති කොටුවේ ඇති ලේබලය පන්තියේ myCellLabelවිචල්‍යයට සමාන කරන්න MyCustomCell.

අවසන්

ඔබට දැන් ඔබේ ව්‍යාපෘතිය ක්‍රියාත්මක කිරීමට හැකි වන අතර විචල්‍ය උසකින් යුත් සෛල ලබා ගත හැකිය.

සටහන්

  • මෙම උදාහරණය ක්‍රියාත්මක වන්නේ iOS 8 සහ ඊට පසුව පමණි. ඔබට තවමත් iOS 7 සඳහා සහය දැක්වීමට අවශ්‍ය නම් මෙය ඔබ වෙනුවෙන් ක්‍රියා නොකරනු ඇත.
  • ඔබගේ අනාගත ව්යාපෘති වල ඇති ඔබේම අභිරුචි සෛල තනි ලේබලයකට වඩා වැඩි ගණනක් ඇත. ස්වයංක්‍රීය පිරිසැලසුම මඟින් භාවිතා කිරීමට නිවැරදි උස තීරණය කළ හැකි වන පරිදි ඔබ සියල්ල නිවැරදිව ඇණ ගසා ඇති බවට වග බලා ගන්න. ඔබට සිරස් සම්පීඩන ප්‍රතිරෝධය සහ වැළඳගැනීම් භාවිතා කිරීමට සිදු විය හැකිය. ගැන වැඩි විස්තර සඳහා මෙම ලිපිය බලන්න .
  • ඔබ ප්‍රමුඛ හා පසුපස (වමේ සහ දකුණේ) දාරවල් සවි නොකරන්නේ නම්, ඔබට ලේබලය සැකසීමට අවශ්‍ය වනු ඇත preferredMaxLayoutWidth. නිදසුනක් ලෙස, ඔබ ප්‍රමුඛ හා පසුපස දාරවල් ඇලවීමට වඩා ඉහත ව්‍යාපෘතියේ ලේබලය වෙත තිරස් බාධකයක් එකතු කර ඇත්නම්, එවිට ඔබට මෙම රේඛාව tableView:cellForRowAtIndexPathක්‍රමයට එකතු කළ යුතුය :

     cell.myCellLabel.preferredMaxLayoutWidth = tableView.bounds.width

මෙයද බලන්න


preferredMaxLayoutWidthසෛලයට එරෙහිව ක්‍රියා කිරීම වඩා හොඳ contentSizeනොවේද? ඒ ආකාරයෙන් ඔබට උපාංග දර්ශනයක් තිබේ නම් හෝ එය සංස්කරණය සඳහා අතුගා දැමුවේ නම් එය තවමත් සැලකිල්ලට ගත යුතුද?
මී පැණි

Oney හනී, ඔබ හරි විය හැකිය. මම දැන් අවුරුද්දක් පමණ iOS මත රැඳී නොසිටි අතර දැන් ඔබට හොඳින් පිළිතුරු දීමට තරම් මලකඩ ඇත.
සුරග්

65

මම @ ස්මයිලිබර්ග්ගේ iOS7 විසඳුම කාණ්ඩයකට ඔතා

@ ස්මිලිබෝග් විසින් මෙම දක්ෂ විසඳුම කාණ්ඩයකට ඇතුළත් කිරීමට මම තීරණය කළෙමි UICollectionViewCell+AutoLayoutDynamicHeightCalculation.

@ Wildmonkey ගේ පිළිතුරෙහි දක්වා ඇති ගැටළු ද මෙම කාණ්ඩය නිවැරදි කරයි (නියපොත්තකින් කොටුවක් පටවා 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
ඔබට හුදෙක් a භාවිතා කිරීමට හැකි විය යුතුය: [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
ස්වයංක්‍රීය කේතය නිවැරදිව සැකසීම, මෙම කේතය viewDidLoad සමඟ එකතු කිරීම උපක්‍රමය කළේය.
බෲස්

1
නමුත් estimatedRowHeightපේළියකින් පේළිය වෙනස් වන්නේ නම් කුමක් කළ යුතුද? මම ඇස්තමේන්තු කළ යුතුද? මා භාවිතා කරන උසෙහි අවම හෝ උපරිම භාවිතා කරන්න tableView?
ජෙනොස්

1
@ ජෙනොස් මෙය පේළි හයිට්හි ලක්ෂ්‍යයයි. මෙය අපේක්ෂිත පරිදි හැසිරවීමට ඔබ ආන්තිකයන් නොමැතිව සීමාවන් භාවිතා කළ යුතු අතර TableViewCell වස්තු වෙත පෙළගැස්විය යුතුය. ඔබ UITextView භාවිතා කරන බව මම සිතමි, එබැවින් ඔබ autoscroll = false ඉවත් කළ යුතුය. එසේ නොවුවහොත් එය උස පවත්වා ගෙන යනු ඇති අතර සාපේක්ෂ උස බලාපොරොත්තු වන පරිදි ක්‍රියා නොකරනු ඇත.
එඩ්වින් පාස්

1
එය වඩාත්ම ශක්තිමත් විසඳුමයි. කණගාටු නොවන්න estimatedRowHeight, එය බොහෝ විට අනුචලන තීරුවේ ප්‍රමාණයට බලපායි, කිසි විටෙක සැබෑ සෛලවල උස නොවේ. ඔබ තෝරා ගන්නා උසෙහි නිර්භීත වන්න: එය ඇතුළත් කිරීමට / මකාදැමීමේ සජීවිකරණයට බලපායි.
ස්විෆ්ට් ආර්කිටෙක්ට්

මෙන්න ස්විෆ්ට් 2.3 හි නියැදි කේතය github.com/dpakthakur/DynamicCellHeight
දීපක්

47

@ ස්මිලිබෝග් විසින් යෝජනා කරන ලද විසඳුම පාහේ පරිපූර්ණයි. ඔබට අභිරුචි කොටුවක් තිබේ නම් සහ ඔබට UILabelගතික උසකින් එකක් හෝ වැඩි ගණනක් අවශ්‍ය නම්, ස්වයංක්‍රීයව සක්‍රීය කර ඇති පද්ධති ලේයූට්සයිස් ෆිටිංසයිස් ක්‍රමය මඟින් CGSizeZeroඔබ ඔබේ සෛල අවහිරතා සියල්ලම සෛලයෙන් එහි අන්තර්ගතයට ගෙන නොයන්නේ නම් (@ ටොම්ස්විෆ්ට් විසින් යෝජනා කරන පරිදි) සියලුම උපසිරැසි ස්වයංක්‍රීයව ගැලපීම සමඟ ගැලපේද? ).

එසේ කිරීමට ඔබ ඔබේ අභිරුචි UITableViewCell ක්‍රියාත්මක කිරීමේදී පහත කේතය ඇතුළත් කළ යුතුය (dAdrian ට ස්තූතියි).

- (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];
    }
}

මේ සමඟ @smileyborg පිළිතුර මිශ්‍ර කිරීම ක්‍රියාත්මක විය යුතුය.


systemLayoutSizeFittingSizeකොටුව මත නොව අන්තර්ගත දර්ශනයෙන් ඇමතිය යුතුය
onmyway133

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);

(මෙම විශේෂිත කොටුව නැවත භාවිතා කිරීම සඳහා මම හැඹිලිගත කරමි, නමුත් එය අදාල නොවේ).


20

මිනිසුන්ට තවමත් මේ සම්බන්ධයෙන් ගැටලුවක් තිබේ නම්. UITableViews සමඟ ස්වයංක්‍රීයකරණය භාවිතා කිරීම ගැන මම ඉක්මන් බ්ලොග් සටහනක් ලිවුවෙමි. මෙය ගතික සෛල උස සඳහා ස්වයංක්‍රීයකරණය මෙන්ම විවෘත මූලාශ්‍රයක් වන අතර මෙය වඩාත් වියුක්ත හා ක්‍රියාත්මක කිරීමට පහසු කරවයි. 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;
}

යාවත්කාලීන කිරීම: ඔබ iOS 8 හි හඳුන්වා දී ඇති ගතික ප්‍රතිප්‍රමාණනය භාවිතා කළ යුතුය.


මෙම iOS7 මත මට වැඩ, එය කැඳවීමට මිත්තණියගෙන් tableView:cellForRowAtIndexPath:දී tableView:heightForRowAtIndexPath:දැන්?
කුහුඹුවන්

හරි, මෙය ක්‍රියා නොකරයි, නමුත් මම ඇමතුමක් ලබා systemLayoutSizeFittingSize:දී tableView:cellForRowAtIndexPath:ප්‍රති result ලය හැඹිලිගත කර පසුව tableView:heightForRowAtIndexPath:අවහිරතා නිවැරදිව සකසා ඇති තාක් කල් එය හොඳින් ක්‍රියාත්මක වේ.
කුහුඹුවන්

මෙය ක්‍රියාත්මක වන්නේ ඔබ dequeueReusableCellWithIdentifier භාවිතා කරන්නේ නම් පමණි: dequeueReusableCellWithIdentifier වෙනුවට: forIndexPath:
Antoine

1
මම හිතන්නේ නැහැ tableV අමතන්න: cellForRowAtIndexPath: කෙලින්ම හොඳ ක්‍රමයක්.
ඉටාචි

19

(පතුලේ කියවන Xcode 8.x / Xcode 9.x සඳහා)

Xcode 7.x හි පහත සඳහන් ගැටලුව ගැන පරෙස්සම් වන්න, එය ව්‍යාකූලත්වයට හේතුවක් විය හැකිය:

අතුරු මුහුණත් සාදන්නා ස්වයංක්‍රීය ප්‍රමාණයේ සෛල සැකසුම නිසි ලෙස හසුරුවන්නේ නැත. ඔබේ සීමාවන් නියත වශයෙන්ම වලංගු වුවද, IB තවමත් පැමිණිලි කර ව්‍යාකූල යෝජනා සහ දෝෂ ලබා දෙනු ඇත. හේතුව, ඔබේ සීමාවන් නියම කරන පරිදි පේළියේ උස වෙනස් කිරීමට IB අකමැති වීමයි (එමඟින් සෛලය ඔබේ අන්තර්ගතයට ගැලපේ). ඒ වෙනුවට, එය පේළියේ උස ස්ථාවරව තබා ගන්නා අතර ඔබ නොසලකා හැරිය යුතු ඔබේ සීමාවන් වෙනස් කිරීමට යෝජනා කරයි .

නිදසුනක් ලෙස, ඔබ සෑම දෙයක්ම හොඳින් සකසා ඇතැයි සිතන්න, අනතුරු ඇඟවීම්, දෝෂ නැත, සියලු ක්‍රියා.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

දැන් ඔබ අකුරු ප්‍රමාණය වෙනස් කරන්නේ නම් (මෙම උදාහරණයේ දී මම විස්තර ලේබල් අකුරු ප්‍රමාණය 17.0 සිට 18.0 දක්වා වෙනස් කරමි).

රූප විස්තරය මෙහි ඇතුළත් කරන්න

අකුරු ප්‍රමාණය වැඩි වූ නිසා, ලේබලය දැන් පේළි 3 ක් අල්ලා ගැනීමට අවශ්‍යය (ඊට පෙර එය පේළි 2 ක් අල්ලාගෙන සිටියේය).

අතුරුමුහුණත් සාදන්නා අපේක්ෂා කළ පරිදි ක්‍රියා කළේ නම්, එය නව ලේබලයේ උසට සරිලන සේ කොටුවේ උස ප්‍රමාණය වෙනස් කරයි. කෙසේ වෙතත් ඇත්ත වශයෙන්ම සිදුවන්නේ අයිබී රතු ස්වයංක්‍රීය සැකසුම් දෝෂ නිරූපකය පෙන්වන අතර වැළඳගැනීම් / සම්පීඩන ප්‍රමුඛතා වෙනස් කිරීමට යෝජනා කිරීමයි.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඔබ මෙම අනතුරු ඇඟවීම් නොසලකා හැරිය යුතුය. ඒ වෙනුවට ඔබට කළ හැක්කේ පේළියේ උස අතින් වෙනස් කිරීමයි (කොටුව> ප්‍රමාණ පරීක්ෂක> පේළි උස තෝරන්න).

රූප විස්තරය මෙහි ඇතුළත් කරන්න

රතු ඊතල දෝෂ අතුරුදහන් වන තුරු මම එක වරකට එක ක්ලික් කිරීමක් (ඉහළ / පහළ පියවර භාවිතා කරමින්) වෙනස් කරමින් සිටියෙමි! (ඔබට සැබවින්ම කහ අනතුරු ඇඟවීම් ලැබෙනු ඇත, එම අවස්ථාවේදී ඉදිරියට ගොස් 'යාවත්කාලීන රාමු' කරන්න, ඒ සියල්ල ක්‍රියාත්මක විය යුතුය).

* අතුරු මුහුණත් සාදන්නා තුළ ඔබට මෙම රතු දෝෂ හෝ කහ අනතුරු ඇඟවීම් සැබවින්ම විසඳිය යුතු නැති බව සලකන්න - ක්‍රියාත්මක වන විට, සියල්ල නිවැරදිව ක්‍රියාත්මක වනු ඇත (IB දෝෂ / අනතුරු ඇඟවීම් පෙන්වුවද). කොන්සෝල ලොගයේ ධාවන වේලාවේදී ඔබට ස්වයංක්‍රීය සැකසුම් දෝෂ කිසිවක් නොලැබෙන බවට වග බලා ගන්න.

ඇත්ත වශයෙන්ම IB හි පේළි උස සෑම විටම යාවත්කාලීන කිරීමට උත්සාහ කිරීම අතිශය කරදරකාරී වන අතර සමහර විට එය කළ නොහැකි මට්ටමට ආසන්න වේ (භාගික අගයන් නිසා).

කරදරකාරී IB අනතුරු ඇඟවීම් / දෝෂයන් වලක්වා ගැනීම සඳහා, ඔබට අදාළ අදහස් තෝරා ගත හැකි Size Inspectorඅතර දේපල Ambiguityතෝරා ගැනීම සඳහාVerify Position Only

රූප විස්තරය මෙහි ඇතුළත් කරන්න


Xcode 8.x / Xcode 9.x (සමහර විට) Xcode 7.x ට වඩා වෙනස් ලෙස දේවල් කරන බව පෙනේ, නමුත් තවමත් වැරදියට. නිදසුනක් ලෙස compression resistance priority/ hugging priorityඅවශ්‍යතාවයට සකසා ඇති විටදී පවා (1000), අතුරුමුහුණත මඟින් කොටුවට සරිලන සේ ලේබලයක් දිගු කිරීම හෝ ඇලවීම කළ හැකිය (ලේබලය වටා ගැළපෙන පරිදි සෛල උස ප්‍රමාණය වෙනස් කිරීම වෙනුවට). එවැනි අවස්ථාවකදී එය ස්වයංක්‍රීය සැකසුම් අනතුරු ඇඟවීම් හෝ දෝෂ පවා නොපෙන්වයි. නැතහොත් සමහර විට එය ඉහත විස්තර කර ඇති Xcode 7.x කළ දේම කරයි.


හායි, සෛල සඳහා ගතික උස ලබා දිය හැකිද, ගතික සෛල අන්තර්ගතය සහිත සෛල සමඟ වගු දර්ශනයක් තිබීම.
ජිග්නේෂ් බී

18

පේළි උස සහ ඇස්තමේන්තුගත පේළි උස සඳහා ස්වයංක්‍රීය මානයන් සැකසීම සඳහා, පහත සඳහන් පියවරයන් සහතික කිරීම, සෛල / පේළි උස පිරිසැලසුම සඳහා ස්වයංක්‍රීය මානය effective ලදායී වේ.

  • වගු දත්ත දත්ත පැවරීම සහ ක්‍රියාත්මක කිරීම
  • සකාට UITableViewAutomaticDimensionrowHeight සහ estimatedRowHeight කිරීමට
  • නියෝජිත / දත්ත ප්‍රභව ක්‍රම ක්‍රියාත්මක කරන්න (එනම් 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
}

UITableviewCell හි ලේබල් උදාහරණය සඳහා

  • පේළි ගණන = 0 සකසන්න (& රේඛා කඩන මාදිලිය = කපා දැමූ වලිගය)
  • එහි අධීක්ෂණ / සෛල බහාලුමට අදාළව සියලු සීමාවන් (ඉහළ, පහළ, දකුණු වමේ) සකසන්න.
  • වෛකල්පිත : දත්ත නොමැති වුවද ලේබලයෙන් ආවරණය වන අවම සිරස් ප්‍රදේශයක් ඔබට අවශ්‍ය නම් ලේබලය සඳහා අවම උස සකසන්න.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

සටහන : ඔබ ගතික දිගකින් යුත් ලේබල් එකකට වඩා (UIElements) තිබේ නම්, එහි අන්තර්ගත ප්‍රමාණය අනුව එය සකස් කළ යුතුය: ඔබට වැඩි ප්‍රමුඛතාවයකින් පුළුල් කිරීමට / සම්පීඩනය කිරීමට අවශ්‍ය ලේබල සඳහා 'අන්තර්ගත වැළඳගැනීම් සහ සම්පීඩන ප්‍රතිරෝධක ප්‍රමුඛතාවය' සකසන්න.


1
ස්තූතියි ඔබට පැහැදිලි හා සරල විසඳුමක් සේ පෙනේ, නමුත් මට ගැටලුවක් තිබේ මම ලේබල් නොව පෙළ දර්ශන භාවිතා නොකිරීම නිසා දත්ත එකතු වන විට පේළි උස වැඩි කිරීමට මට අවශ්‍යය. එවිට මගේ ගැටලුව වන්නේ තොරතුරු උස ෆෝරෝව් වෙත යැවීමයි. මගේ වෙනස්වන පෙළ දර්ශනවල උස මැනිය හැකි නමුත් දැන් පේළි උස වෙනස් කළ යුතුය. කරුණාකර යම් උදව්වක් අගය කරනු ඇත
ජෙරමි

@ ජෙරමි ඇන්ඩෘස් ෂුවර් ඔබට උදව් කරනු ඇත. ඔබ උත්සාහ කළ ප්‍රභව කේතය සහ ගැටලුව පිළිබඳ විස්තර සහිතව ඔබේ ප්‍රශ්නය මතු කරන්න.
කෘනාල්

tableView: heightForRowදත්ත මූලාශ්‍රය ක්‍රියාත්මක නොකර එය මා වෙනුවෙන් වැඩ කරයි.
හේමාන්

Em හේමාන්ග් - iOS 11+ සිට එය නොමැතිව ක්‍රියා කරයි tableView: heightForRow. (iOS 10 tableView: heightForRowසඳහා අවශ්‍ය වේ)
කෘනාල්

1
Em හේමාන්ග් - විසඳුම නිශ්චිත විමසුම් අර්ථ දැක්වීම මත රඳා පවතී. මෙන්න මම ඔබේ විමසුම සඳහා පොදු පොදු විසඳුමක් ඇත. තත්වය ඇතුලත තබන්න tableView: heightForRow..if (indexPath.row == 0) { return 100} else { return UITableView.automaticDimension }
කෘනාල්

16

@ බොබ්-ස්ප්‍රින් මෙන් මම මෙය පිළිතුරක් ලෙස පළ කරන තරම් වැදගත් ගොචාවකට ගියෙමි.

මම ටික වේලාවක් @ ස්මයිලිබර්ග්ගේ පිළිතුර සමඟ පොරබදිමි . මම ඔබට අමතර මූලද්රව්ය (සමග IB ඔබේ මූලාකෘති සෛල අර්ථ තියෙනවා නම් වේ තුළට දිව ගියා බව gotcha UILabels, UIButtonsඔබ [සමග සෛල instantiate විට IB දී, ආදිය) [YourTableViewCellClass alloc] init]ඔබ එක හොදයි නම් එය instantiate අනෙකුත් සියලු කොටු තුල කොටස් නැහැ එය කිරීමට ලිඛිත කේතය. (මට ඒ හා සමාන අත්දැකීමක් තිබුණිinitWithStyle .)

කතන්දර පුවරුව ක්ෂණිකව ලබා ගැනීම සඳහා සියලු අමතර අංග සමඟ ඔබේ සෛලය ලබා ගනී [tableView dequeueReusableCellWithIdentifier:@"DoseNeeded"]( [tableView dequeueReusableCellWithIdentifier:forIndexPath:]මෙය සිත්ගන්නාසුලු ගැටළු ඇති නොකරයි.) ඔබ මෙය කරන විට ඔබ IB හි අර්ථ දක්වා ඇති සියලුම අංග ක්ෂණිකව ලබා දෙනු ඇත.


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
ඔව්, මම දනිමි ... නමුත් මට PureLayout භාවිතා කිරීමට අවශ්‍ය නොවූ අතර dispatch_once 'උපක්‍රමය' මට බොහෝ සෙයින් උපකාරී විය, එය කතන්දර පුවරුව භාවිතයෙන් පමණක් ක්‍රියාත්මක කිරීමට.
මොහ්නාස්ම්

13
tableView.estimatedRowHeight = 343.0
tableView.rowHeight = UITableViewAutomaticDimension

රූප විස්තරය මෙහි ඇතුළත් කරන්න


13

තවත් "විසඳුමක්": UITableView ට සමාන හා දැනෙන ප්‍රති result ලයක් ලබා ගැනීම සඳහා මේ සියලු කලකිරීම් මඟ හැර UIScrollView භාවිතා කරන්න.

එය මට වේදනාකාරී “විසඳුම” විය. වචනාර්ථයෙන් 20+ කට අධික කාලයක් ගත කිරීමෙන් පසු ස්මයිලිබෝග් යෝජනා කළ දේ වැනි දෙයක් ගොඩනඟා ගැනීමට උත්සාහ කිරීම සහ මාස ගණනාවක් තිස්සේ අසාර්ථක වීම සහ ඇප් ස්ටෝර් නිකුතුවල අනුවාද තුනක්.

මගේ අදහස නම් ඔබට සැබවින්ම iOS 7 සහය අවශ්‍ය නම් (අපට එය අත්‍යවශ්‍යයි) එවිට තාක්‍ෂණය ඉතා අස්ථාවර වන අතර ඔබ උත්සාහ කිරීමෙන් ඔබේ කොණ්ඩය අදින්නේය. සාමාන්‍යයෙන් ඔබ සමහර උසස් පේළි සංස්කරණ විශේෂාංග භාවිතා නොකරන්නේ නම් සහ / හෝ 1000+ “පේළි” සඳහා සහය දැක්විය යුතු නම් මිස, එම UITableView සම්පූර්ණ අතිරික්තය (අපගේ යෙදුමේ, එය යථාර්ථවාදීව පේළි 20 කට වඩා වැඩි නොවේ).

එකතු කරන ලද ප්‍රසාද දීමනාව නම්, UITableView සමඟ එන සියලුම නියෝජිත කපටිකමට හා පසුපසට හා පිටුපසින් කේතය ඉතා සරල වීමයි. ViewOnLoad හි ඇති එක් කේත ලූපයක් පමණක් එය අලංකාර පෙනුමක් ඇති අතර කළමනාකරණය කිරීමට පහසුය.

එය කරන්නේ කෙසේද යන්න පිළිබඳ උපදෙස් කිහිපයක් මෙන්න:

  1. ස්ටෝරිබෝඩ් හෝ නිබ් ගොනුවක් භාවිතා කරමින්, ViewController සහ ඊට සම්බන්ධ මූල දර්ශනයක් සාදන්න.

  2. ඔබගේ මූල දර්ශනයට UIScrollView එකක් හරහා ඇදගෙන යන්න.

  3. ඉහළ මට්ටමේ දර්ශනයට ඉහළ, පහළ, වම සහ දකුණේ සීමාවන් එක් කරන්න, එවිට UIScrollView සමස්ත මූල දර්ශනය පුරවයි.

  4. UIScrollView තුළ UIView එකක් එකතු කර එය "බහාලුම්" ලෙස අමතන්න. UIScrollView (එහි මවුපිය) වෙත ඉහළ, පහළ, වම් සහ දකුණු සීමාවන් එක් කරන්න. KEY TRICK: UIScrollView සහ UIView සම්බන්ධ කිරීම සඳහා "සමාන පළල" සීමාවන් එකතු කරන්න.

    සටහන: ඔබට "අනුචලන දර්ශනයෙහි නොපැහැදිලි අනුචලනය කළ හැකි අන්තර්ගත උස ඇත" සහ ඔබේ බහාලුම් UIView පික්සෙල් 0 ක උසකින් යුක්ත විය යුතුය. යෙදුම ක්‍රියාත්මක වන විට කිසිදු දෝෂයක් වැදගත් නොවන බව පෙනේ.

  5. ඔබගේ එක් එක් "සෛල" සඳහා නිබ් ගොනු සහ පාලක සාදන්න. UITiew නොව UITableViewCell භාවිතා කරන්න.

  6. ඔබේ මූල ViewController හි, ඔබ මූලිකවම UIView කන්ටේනරයට සියලු "පේළි" එකතු කර ක්‍රමලේඛනය කර ඒවායේ වම් සහ දකුණු දාර බහාලුම් දර්ශනයට සම්බන්ධ කරයි, ඒවායේ ඉහළ දාර බහාලුම් දර්ශන ඉහළට (පළමු අයිතමය සඳහා) හෝ පෙර කොටුව. ඉන්පසු අවසාන කොටුව බහාලුම් පතුලට සම්බන්ධ කරන්න.

අප සඳහා, සෑම "පේළියක්ම" නිබ් ගොනුවක ඇත. එබැවින් කේතය මේ වගේ ය:

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!)
    }
}

UITools.addViewToTop සඳහා කේතය මෙන්න:

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))
    }
}

මෙම ප්‍රවේශය සමඟ මා මෙතෙක් සොයාගෙන ඇති එකම "ගොචා" නම්, ඔබ අනුචලනය කරන විට දර්ශනයේ ඉහළින්ම "පාවෙන" අංශ ශීර්ෂයන්හි UITableView සතුව හොඳ ලක්ෂණයකි. ඔබ වැඩිපුර ක්‍රමලේඛන එකතු කළහොත් මිස ඉහත විසඳුම එය නොකරනු ඇත. නමුත් අපගේ විශේෂ අවස්ථාව සඳහා මෙම අංගය 100% අත්‍යවශ්‍ය නොවන අතර එය නැති වූ විට කිසිවෙකු නොදැන සිටියේය.

ඔබේ සෛල අතර බෙදීම් අවශ්‍ය නම්, බෙදුම්කරුවෙකු මෙන් පෙනෙන ඔබේ අභිරුචි "කොටුවේ" පතුලේ පික්සල් 1 ක ඉහළ UIV දර්ශනයක් එක් කරන්න.

නැවුම්බව පාලනය කිරීම සඳහා "පැනීම" සහ "සිරස් අතට පනින්න" සක්‍රිය කිරීමට වග බලා ගන්න, එබැවින් එය මේස දර්ශනයක් මෙන් පෙනේ.

මෙම විසඳුම නොමැති පරිදි සම්පූර්ණ තිරය පුරවා නොමැති නම්, ඔබේ අන්තර්ගතය යටතේ හිස් පේළි සහ බෙදුම්කරුවන් කිහිපයක් TableView පෙන්වයි. නමුත් පෞද්ගලිකව, මම කැමතියි එම හිස් පේළි කෙසේ හෝ නොතිබුනේ නම් - විචල්ය සෛල උසකින් එය හිස් පේළි එහි තිබීම සඳහා සෑම විටම මට "දෝෂ සහිත" බවක් පෙනෙන්නට තිබුණි.

මෙන්න ඔවුන්ගේම යෙදුමේ වගු දර්ශනය සමඟ එය වටහා ගැනීමට පැය 20+ ක් නාස්ති කිරීමට පෙර වෙනත් ක්‍රමලේඛකයෙකු මගේ සටහන කියවනු ඇතැයි බලාපොරොත්තු වේ. :)


11

මට ගතික දර්ශන (කේත අනුව සැකසුම් දසුන් සහ අවහිරතා) භාවිතා කිරීමට සිදු වූ අතර මට කැමති මැක්ස්ලයිට්අවුඩ් පළල ලේබලයේ පළල 0 ලෙස සැකසීමට අවශ්‍ය වූ විට මට වැරදි සෛල උස තිබේ.

ඊට පස්සේ මම එකතු කළා

[cell layoutSubviews];

ක්‍රියාත්මක කිරීමට පෙර

[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];

ඊට පසු ලේබලයේ පළල අපේක්ෂා කළ පරිදි වූ අතර ගතික උස නිවැරදිව ගණනය කෙරිණි.


9

ඔබට උප දර්ශනයක් සහිත කොටුවක් ඇති බව කියමු, සහ ඔබට අවශ්‍ය වන්නේ කොටුවේ උස උප දර්ශනය + පෑඩින් ඇතුළත් කිරීමට තරම් ඉහළ මට්ටමක තිබීමයි.

1) උප දර්ශනයේ පහළ සීමාව cell.contentView ට සමාන ලෙස සකසන්න. කොටුවට හෝ cell.contentView හි සීමාවන් සකසන්න එපා.

2) tableView හි rowHeightදේපල හෝ tableView:heightForRowAtIndexPath:වෙත සකසන්නUITableViewAutomaticDimension .

3) tableView හි estimatedRowHeightදේපල හෝ සකසන්නtableView:estimatedHeightForRowAtIndexPath: උස පිළිබඳ හොඳම අනුමානයකට .

ඒක තමයි.


7

ඔබ ක්‍රමානුකූලව පිරිසැලසුමක් කරන්නේ නම්, ස්විෆ්ට් හි නැංගුරම් භාවිතා කරමින් iOS 10 සඳහා සලකා බැලිය යුතු දේ මෙන්න.

නීති / පියවර තුනක් තිබේ

අංක 1: වගු දර්ශනයේ මෙම ගුණාංග දෙක viewDidLoad හි සකසන්න, පළමුවැන්න ඔවුන්ගේ සෛලවල ගතික ප්‍රමාණ අපේක්ෂා කළ යුතු වගු දර්ශනයට ය, දෙවැන්න වන්නේ අනුචලන දර්ශකයේ ප්‍රමාණය ගණනය කිරීමට යෙදුමට ඉඩ දීමයි, එබැවින් එය උපකාරී වේ කාර්ය සාධනය.

    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 100

අංක 2: මෙය ඔබට වැදගත් වන්නේ කොටුවේ අන්තර්ගතයට දර්ශනයට එකතු කිරීම අවශ්‍ය නොවන අතර, එහි පිරිසැලසුම ඉහළ සහ පහළ නැංගුරම් ලෑමට එහි පිරිසැලසුම භාවිතා කිරීම, මෙය කරන්නේ කෙසේද යන්න පිළිබඳ ක්‍රියාකාරී උදාහරණයකි.

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)

        ])
}

උප දර්ශන එකතු කර පිරිසැලසුම සිදු කරන ක්‍රමයක් සාදන්න, එය init ක්‍රමයට අමතන්න.

අංක 3: ක්‍රමය අමතන්න එපා:

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

ඔබ එය කළහොත් ඔබ ක්‍රියාත්මක කිරීම අභිබවා යනු ඇත.

වගු දර්ශනවල ගතික සෛල සඳහා මෙම නීති 3 අනුගමනය කරන්න.

මෙන්න ක්‍රියාත්මක කිරීමකි https://github.com/jamesrochabrun/MinimalViewController


ස්විෆ්ට් 5 හි UITableViewAutomaticDimension ලෙස UITableView.automaticDimension ලෙස නම් කරන ලදි
ජේම්ස් රොචබ්‍රන්

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
    }
}

මම කිසිදු ප්‍රමාණයක් එකතු කර නැති බව සලකන්න සීමාවන් . මම එකතු කර ඇත්තේ centerX, centerY අවහිරතා පමණි. නමුත් තවමත් ලේබලය නිවැරදිව ප්‍රමාණ කරනු ඇත ඇයි?

නිසා contentSize .

මෙය වඩා හොඳින් ක්‍රියාවට නැංවීමට, පළමුව පියවර 0 තබා, පියවර 1-6 දක්වා අදහස් දක්වන්න. ඉඩsetupLayout()ඉන්න . හැසිරීම නිරීක්ෂණය කරන්න.

පියවර 1 නොතකා, නිරීක්ෂණය කරන්න.

ඉන්පසු පියවර 2 අසම්පූර්ණ කර නිරීක්ෂණය කරන්න.

ඔබ පියවර 6 ම නිරාකරණය කර ඔවුන්ගේ හැසිරීම් නිරීක්ෂණය කරන තුරු මෙය කරන්න.

මේ සියල්ලෙන් නිගමනය කළ හැක්කේ කුමක් ද? වෙනස් කළ හැකි සාධක contenSizeමොනවාද?

  1. පෙළ දිග: ඔබට දිගු පා text යක් තිබේ නම් ඔබේ අභ්‍යන්තර අන්තර්ගතයේ පළල වැඩි වේ
  2. රේඛා බිඳීම්: ඔබ එකතු කළහොත් \nඅභ්‍යන්තර අන්තර්ගතයේ පළල සියලු රේඛාවල උපරිම පළල වනු ඇත. එක් පේළියක අක්ෂර 25 ක්, තවත් අක්ෂර 2 ක් සහ තවත් අක්ෂර 21 ක් තිබේ නම් ඔබේ පළල ගණනය කරනු ලබන්නේ අක්ෂර 25 මත පදනම්වය
  3. ඉඩ මාර්ග අංකය: ඔබ කර ගත යුතු ය numberOfLinesකිරීමට 0වෙනත් ආකාරයකින් ඔබ රේඛා කිහිපයක් නැත. ඔබ numberOfLinesඔබේ සහජ අන්තර්ගතයෙහි උස වෙනස් කරනු ඇත
  4. ගැලපීම් සිදු කිරීම: ඔබේ පෙළ මත පදනම්ව, ඔබේ සහජ අන්තර්ගතයේ පළල 200සහ උස යැයි 100සිතන්න, නමුත් ඔබට අවශ්‍ය වූයේ පළල ලේබලයේ කන්ටේනරයට සීමා කිරීමට ඔබ කුමක් කරන්නද? විසඳුම එය අපේක්ෂිත පළලකට සැකසීමයි. වම ඔබ ඔබ විසින් preferredMaxLayoutWidthකිරීමට 130ඔබගේ නව intrinsicContentSize දළ වශයෙන් පළල ඇත 130. 100ඔබට වැඩි රේඛා අවශ්‍ය වන නිසා උස පැහැදිලිවම වැඩි ය . ඔබේ සීමාවන් නිවැරදිව සකසා ඇත්නම් ඔබට මෙය කිසිසේත් භාවිතා කිරීමට අවශ්‍ය නොවනු ඇත. බව වැඩි දකින සඳහා මෙම පිළිතුර සහ එහි අදහස් බලන්න. ඔබ භාවිතා කළ යුත්තේ ඔබ හොඳය! ". නමුත් 100% ක් නිශ්චිතව ඔබ ප්රධාන පෙළේ / අවර හා සකස් නම් කිරීමටpreferredMaxLayoutWidth කළ යුත්තේ පළල / උස සීමා කිරීමට ඔබට බාධාවක් නොමැති නම් “පා text ය ඉක්මවා ගියහොත් එය එතීමෙන් වළකින්න.preferredMaxLayoutWidthnumberOfLines0දීර් story කතන්දර කෙටියෙන් මෙහි භාවිතා කිරීමට නිර්දේශ කරන බොහෝ පිළිතුරු වැරදියි! ඔබට එය අවශ්‍ය නැත. එය අවශ්‍ය වන්නේ ඔබේ අවහිරතා නිවැරදිව සකසා නැති බවට හෝ ඔබට සීමාවන් නොමැති බවට ලකුණකි

  5. අකුරු ප්‍රමාණය: තවද ඔබ ඔබේ අකුරු ප්‍රමාණය වැඩි කළහොත් අභ්‍යන්තර අන්තර්ගතයේ උස වැඩි වන බව සලකන්න . මම එය මගේ කේතයේ පෙන්වූයේ නැත. ඔබට එය තනිවම උත්සාහ කළ හැකිය.

එබැවින් ඔබගේ tableViewCell උදාහරණය වෙත ආපසු යන්න:

ඔබ කළ යුත්තේ:

  • සකසන්න numberOfLines ගැනීමට0
  • ලේබලය නිවැරදිව ආන්තික / දාරවලට සීමා කරන්න
  • සැකසීමට අවශ්‍ය නැත preferredMaxLayoutWidth.

1

මගේ නඩුවේදී මට සේවාදායකයෙන් එන රූපයක් සහිත අභිරුචි කොටුවක් නිර්මාණය කළ යුතු අතර එය ඕනෑම පළලකින් හා උසකින් යුක්ත විය හැකිය. ගතික ප්‍රමාණයෙන් යුත් UILabels දෙකක් (පළල සහ උස යන දෙකම)

මම ස්වයංක්‍රීයව හා ක්‍රමලේඛනගතව මගේ පිළිතුරෙන් එය ලබාගෙන ඇත:

මූලික වශයෙන් ඉහළින් @smileyBorg පිළිතුර උදව් වූ නමුත් systemLayoutSizeFittingSize මා වෙනුවෙන් කිසි විටෙකත් ක්‍රියා කළේ නැත, මගේ ප්‍රවේශයේදී:

1. ස්වයංක්‍රීය පේළි උස ගණනය කිරීමේ දේපල භාවිතා නොකෙරේ. 2. ඇස්තමේන්තුගත උස භාවිතා නොකිරීම 3. අනවශ්‍ය යාවත්කාලීන කිරීම් අවශ්‍ය නොවේ. 4. ස්වයංක්‍රීය වරණීය උපරිම පිරිසැලසුම් පළල භාවිතා නොකිරීම. 5. SystemLayoutSizeFittingSize හි කිසිදු භාවිතයක් නොමැත (මා වෙනුවෙන් වැඩ කළ යුතු නමුත් වැඩ නොකළ යුතුය, එය අභ්‍යන්තරව කරන්නේ කුමක්දැයි මම නොදනිමි), නමුත් ඒ වෙනුවට මගේ ක්‍රමය - (පාවෙන) getViewHeight වැඩ කරන අතර එය අභ්‍යන්තරව කරන්නේ කුමක්දැයි මම දනිමි.

මම සෛලය ප්‍රදර්ශනය කිරීමට විවිධ ක්‍රම භාවිතා කරන විට UITableView කොටුවක විවිධ උස තිබිය හැකිද?


1

මගේ නඩුවේදී, පෑඩින් කිරීම සිදු වූයේ හීඩර් සහ කොටසේ ෆුටර් උස නිසා වන අතර, කතන්දර පුවරුව එය අවම 1 දක්වා වෙනස් කිරීමට මට ඉඩ ලබා දුන්නේය. එබැවින් viewDidLoad ක්‍රමයේදී:

tableView.sectionHeaderHeight = 0
tableView.sectionFooterHeight = 0

1

මම වටිනාකම් 2 සමග සමහර ගොළු උත්සාහක දිනුමක් හා දෝෂ කළා rowHeightහා estimatedRowHeightහා ඒක සමහර දෝෂහරණ අවබෝධයක් ලබා අදහස සමහරවිට:

ඔබ ඒවා දෙකම සැකසූ විට හෝ සැකසූ විට පමණක් estimatedRowHeightඔබට අපේක්ෂිත හැසිරීම ලැබෙනු ඇත:

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

නිවැරදි ඇස්තමේන්තුව ලබා ගැනීම සඳහා ඔබේ උපරිමය කරන ලෙස යෝජනා කර ඇත, නමුත් අවසාන ප්‍රති result ලය වෙනස් නොවේ. එය ඔබගේ ක්‍රියාකාරිත්වයට පමණක් බලපානු ඇත.

රූප විස්තරය මෙහි ඇතුළත් කරන්න


ඔබ පේළිය පමණක් සකසා ඇත්නම්, එනම් කරන්න:

tableView.rowHeight = UITableViewAutomaticDimension

ඔබේ අවසාන ප්‍රති result ලය අපේක්ෂිත පරිදි නොවනු ඇත:

රූප විස්තරය මෙහි ඇතුළත් කරන්න


ඔබ 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]

අවහිරතා නොපැහැදිලි අවස්ථාවන්හිදී විශ්වාස කළ නොහැකි වීම. පහත දැක්වෙන UIView හි සහායක කාණ්ඩය භාවිතා කරමින්, එක් දිශාවකට උස ගණනය කිරීමට පිරිසැලසුම් එන්ජිමට බල කිරීම වඩා හොඳය:

-(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;
}

කොහෙද w: යනු මේස දර්ශනයේ පළලයි


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) ගණනය කිරීමට අමතක නොකරන්න . එනම්, වගු සෛල උස නියෝජිත ක්‍රමයේදී, සෛල පළල නිවැරදි කිරීමට cell.frame භාවිතා කරන්න, ඉන්පසු සුදුසු අගය ලබා ගැනීම සඳහා කොටුවේ අර්ථ දක්වා ඇති ගණන් කිරීමේ උස ක්‍රමය අමතන්න. .

පීඑස්. සෛල වස්තුව උත්පාදනය කිරීමේ කේතය වෙනත් වගුවකින් විවිධ වගු දර්ශන සෛල නියෝජිතයින් ඇමතීමට අර්ථ දැක්විය හැකිය.


-3

UITableView.automaticDimension අතුරුමුහුණත හරහා සැකසිය හැකිය:

Xcode> කතන්දර පුවරුව> ප්‍රමාණ පරීක්ෂක

වගු දර්ශන කොටුව> පේළි උස> ස්වයංක්‍රීය

ප්‍රමාණ පරීක්ෂක


-4

ස්විෆ්ට් හි තවත් iOs7 + iOs8 විසඳුමක්

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
    }
}

සටහන: systemLayoutSizeFittingSize මගේ නඩුවේ ක්‍රියා
නොකරයි

සෛල උස නිවැරදි නොවේ cellForRowAtIndexPath, මේ මොහොතේ සෛලය තවම සකසා නැත.
ඇන්ඩ්‍රි චර්නෙන්කෝ

iOs7 හි එය ස්ථාවර අගයකි, එනම් එය ක්‍රියා කරයි. ඔබට අවශ්‍ය නම් පිටත කොටුව තුළ සැකසිය හැකිය
djdance
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.