ডায়নামিক কক্ষের উচ্চতা সহ ইউআইটিএবলভিউর পুনঃলোডডাটা () পুনর্বিবেচনা স্ক্রোলিংয়ের কারণ


142

আমি মনে করি এটি সাধারণ সমস্যা হতে পারে এবং ভাবছিলাম যে এর কোনও সাধারণ সমাধান আছে কিনা।

মূলত, আমার ইউআইটিএবলভিউতে প্রতিটি কক্ষের জন্য গতিময় কক্ষের উচ্চতা রয়েছে। আমি যদি ইউআইটিএবলভিউ এবং আমি শীর্ষে না থাকি tableView.reloadData(), স্ক্রোলিং আপ ঝটপট হয়ে যায়।

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

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


কয়েকটি জিনিস ... (1) হ্যাঁ আপনি অবশ্যই নির্দিষ্ট কিছু সারি ব্যবহার করে পুনরায় লোড করতে পারেন reloadRowsAtIndexPaths। তবে (২) "ঝাঁপিয়ে পড়া" বলতে কী বোঝায় এবং (3) আপনি একটি আনুমানিক সারির উচ্চতা নির্ধারণ করেছেন? (কেবলমাত্র কোনও আরও ভাল সমাধান রয়েছে যা আপনাকে টেবিলটি গতিশীলভাবে আপডেট করার অনুমতি দেয় কিনা তা সন্ধান করার চেষ্টা করছেন))
লিন্ডসে স্কট

@ লিন্ডসেস্কট, হ্যাঁ, আমি আনুমানিক সারির উচ্চতা নির্ধারণ করেছি। ঝাপটায় আমি বোঝাতে চাইছি যেহেতু আমি উপরে স্ক্রোল করছি, সারিগুলি উপরের দিকে সরে যাচ্ছে। আমি বিশ্বাস করি এটি কারণ আমি আনুমানিক সারির উচ্চতা 128 রেখেছি এবং তারপরে আমি স্ক্রোল করার সাথে সাথে ইউআইটিবেল ভিউতে আমার উপরের সমস্ত পোস্ট ছোট, তাই এটি উচ্চতা সঙ্কুচিত করে, যার ফলে আমার টেবিলটি লাফিয়ে উঠবে। আমি আমার টেবিলভিউতে সারি xথেকে শেষ সারি পর্যন্ত পুনরায় লোডআরএটিস ইনডেক্সপথগুলি করার কথা ভাবছি ... তবে যেহেতু আমি নতুন সারিগুলি serোকাচ্ছি, এটি কাজ করবে না, আমি পুনরায় লোড করার আগে আমার টেবিলভিউয়ের শেষটি কী হবে তা আমি জানি না তথ্যটি.
ডেভিড

2
@ লিন্ডসেস্কট এখনও আমি সমস্যার সমাধান করতে পারছি না, এর কোনও ভাল সমাধান আছে কি?
রেড

1
আপনি কি কখনও এই সমস্যার সমাধান খুঁজে পেয়েছেন? আপনার ভিডিওতে যেমন দেখা গেছে ঠিক তেমনই সমস্যাটিও আমি अनुभव করছি।
user3344977

1
নীচের কোনও উত্তরই আমার পক্ষে কার্যকর হয়নি।
শ্রুজান সিংহা

উত্তর:


220

জাম্পিং প্রতিরোধ করতে আপনার ঘরের উচ্চতা সংরক্ষণ করা উচিত যখন তারা লোড হয় এবং সঠিক মান দেয় tableView:estimatedHeightForRowAtIndexPath:

সুইফট:

var cellHeights = [IndexPath: CGFloat]()

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeights[indexPath] = cell.frame.size.height
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return cellHeights[indexPath] ?? UITableView.automaticDimension
}

উদ্দেশ্য গ:

// declare cellHeightsDictionary
NSMutableDictionary *cellHeightsDictionary = @{}.mutableCopy;

// declare table dynamic row height and create correct constraints in cells
tableView.rowHeight = UITableViewAutomaticDimension;

// save height
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cellHeightsDictionary setObject:@(cell.frame.size.height) forKey:indexPath];
}

// give exact height value
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];
    if (height) return height.doubleValue;
    return UITableViewAutomaticDimension;
}

1
ধন্যবাদ, আপনি সত্যিই আমার দিনটি সংরক্ষণ করেছেন :) আপত্তিতেও কাজ করে
আর্টেম জেড।

3
আরম্ভ করতে ভুলবেন না cellHeightsDictionary:cellHeightsDictionary = [NSMutableDictionary dictionary];
গেরহর্বো

1
estimatedHeightForRowAtIndexPath:একটি ডাবল মান প্রদান করে *** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]ত্রুটি হতে পারে । return floorf(height.floatValue);পরিবর্তে , এটি ঠিক করার জন্য ।
লিউশুইকোব

হাই @lgor, আমি একই সমস্যা পেয়েছি এবং আপনার সমাধানটি বাস্তবায়নের চেষ্টা করছি। আমি যে ইস্যুটি পাচ্ছি তা অনুমান করা হয় হাইফোরআরএটআইএনডেক্সপথ উইলডিসপ্লে সেল এর আগে ডাকা হয়, সুতরাং সেলটির উচ্চতা গণনা করা হয় না যখন অনুমান করা হয় হাইফোরআরআউটআইডেক্সপথ বলা হয়। কোন সাহায্য?
মাধুরী

1
@ মাধুরী কার্যকর উচ্চতাগুলি "উচ্চতা forRowAtIndexPath" তে গণনা করা উচিত, যা উইলডিসপ্লেলে এর ঠিক আগে স্ক্রিনের প্রতিটি কক্ষের জন্য ডাকা হয়, এটি অনুমানরোহাইট (টেবিল পুনরায় লোডে) পরবর্তী ব্যবহারের জন্য অভিধানে উচ্চতা নির্ধারণ করবে।
Donnit

108

স্বীকৃত উত্তরের 3 সংস্করণ।

var cellHeights: [IndexPath : CGFloat] = [:]


func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeights[indexPath] = cell.frame.size.height
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return cellHeights[indexPath] ?? 70.0 
}

ধন্যবাদ এটি দুর্দান্ত কাজ করেছে! আসলে আমি আমার বাস্তবায়নটি সরাতে সক্ষম হয়েছি func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {, এটি আমার প্রয়োজনীয় সমস্ত উচ্চতার গণনা পরিচালনা করে।
নাটালিয়া

অবিচ্ছিন্ন ঝাঁপ দিয়ে বেশ কয়েক ঘন্টা লড়াই করার পরে আমি বুঝতে পারলাম যে আমি UITableViewDelegateআমার ক্লাসে যুক্ত হওয়া ভুলে গেছি । সেই প্রোটোকলের সাথে সামঞ্জস্য করা প্রয়োজনীয় cess কারণ এটিতে উপরের দেখানো willDisplayফাংশন রয়েছে। আমি আশা করি আমি কাউকে একই সংগ্রাম বাঁচাতে পারি।
এমজেকিউজেড 1347

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

সুইফট 4.2 এ পুরোপুরি কাজ করে
অ্যাডাম এস

একটি জীবন রক্ষাকারী ডেটাসোর্সে আরও আইটেম যুক্ত করার চেষ্টা করার সময় তাই সহায়ক। পর্দার কেন্দ্রে সদ্য যুক্ত হওয়া ঘরগুলির জাম্পিং প্রতিরোধ করে।
ফিলিপ বর্বন

38

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

func viewDidLoad() {
     super.viewDidLoad()
     tableView.estimatedRowHeight = 100//close to your cell height
}

আপনার যদি বিভিন্ন বিভাগে বিভিন্ন ধরণের কোষ থাকে তবে আমার মনে হয় আরও ভাল জায়গা

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
     //return different sizes for different cells if you need to
     return 100
}

2
আপনাকে ধন্যবাদ, আমার টেবিল ভিউটি এতটাই ঝাপটা ছিল কেন exactly
লুই ডি ডেকার

1
একটি পুরানো উত্তর, তবে এটি 2018 সালের মতো এখনও সত্য other ধন্যবাদ। বিটিডাব্লু, বিকল্পভাবে esimatedRowHeight আকার পরিদর্শক> টেবিল ভিউ> প্রাক্কলন মধ্যে ইন্টারফেস বিল্ডারের মাধ্যমে সেট করা যেতে পারে।
ভাইটালি

আরও সঠিক অনুমানের উচ্চতা আমাকে সহায়তা করেছিল provided আমারও একটি বহু-বিভাগীয় গোষ্ঠীযুক্ত টেবিল ভিউ শৈলী ছিল এবং এটি বাস্তবায়ন করতে হয়েছিলtableView(_:estimatedHeightForHeaderInSection:)
nteissler

25

@ আইগরের উত্তরটি এরSwift-4কোডএই ক্ষেত্রে ভাল কাজ করছে।

// declaration & initialization  
var cellHeightsDictionary: [IndexPath: CGFloat] = [:]  

নিম্নলিখিত পদ্ধতিতে UITableViewDelegate

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
  // print("Cell height: \(cell.frame.size.height)")
  self.cellHeightsDictionary[indexPath] = cell.frame.size.height
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
  if let height =  self.cellHeightsDictionary[indexPath] {
    return height
  }
  return UITableView.automaticDimension
}

6
এই সমাধানটি ব্যবহার করে কীভাবে সারি সন্নিবেশ / মুছে ফেলা হবে? টেবিলভিউ লাফ দেয়, অভিধানের ডেটা আসল না বলে।
অ্যালেক্সি চেকানভ 19

1
দুর্দান্ত কাজ! বিশেষ করে শেষ কক্ষে যখন পুনরায় লোড করুন।
নিং

19

আমি উপরের সমস্ত কাজের চেষ্টা করেছি, কিন্তু কিছুই কার্যকর হয়নি।

ঘন্টা ব্যয় করার পরে এবং সম্ভাব্য সমস্ত হতাশাগুলি পেরিয়ে যাওয়ার পরে এটি ঠিক করার একটি উপায় বের করলেন। এই সমাধানটি জীবন রক্ষাকারী! মোহন মত কাজ!

সুইফট 4

let lastContentOffset = tableView.contentOffset
tableView.beginUpdates()
tableView.endUpdates()
tableView.layer.removeAllAnimations()
tableView.setContentOffset(lastContentOffset, animated: false)

কোডটিকে আরও পরিষ্কার দেখানোর জন্য এবং যতবার আমি পুনরায় লোড করতে চাইছি এই সমস্ত লাইন লেখা এড়াতে আমি এটি একটি এক্সটেনশন হিসাবে যুক্ত করেছি।

extension UITableView {

    func reloadWithoutAnimation() {
        let lastScrollOffset = contentOffset
        beginUpdates()
        endUpdates()
        layer.removeAllAnimations()
        setContentOffset(lastScrollOffset, animated: false)
    }
}

শেষ পর্যন্ত ..

tableView.reloadWithoutAnimation()

অথবা আপনি প্রকৃতপক্ষে আপনার UITableViewCell awakeFromNib()পদ্ধতিতে এই লাইনটি যুক্ত করতে পারেন

layer.shouldRasterize = true
layer.rasterizationScale = UIScreen.main.scale

এবং স্বাভাবিক করুন reloadData()


1
এটি কীভাবে কোনও পুনরায় লোড করে? আপনি কল এটা reloadWithoutAnimationকিন্তু কোথায় reloadঅংশ?
ম্যাট

@ ম্যাট আপনি tableView.reloadData()প্রথমে কল করতে পারেন এবং তারপরেও tableView.reloadWithoutAnimation()এটি কার্যকর হয়।
শ্রুজান সিমহা

গ্রেট! উপরের কোনওটিই আমার পক্ষে কাজ করেনি। এমনকি সমস্ত উচ্চতা এবং আনুমানিক উচ্চতাও সম্পূর্ণ এক। মজাদার.
টিওয়াই কুকুক

1
আমার জন্য কাজ করবেন না। এটি টেবিল ভিউ.অ্যান্ডআপেটস () এ ক্র্যাশ হয়েছে। কেউ আমাকে সাহায্য করতে পারেন!
কাকাশি

12

আমি কীভাবে এটি ঠিক করতে আরও উপায় ব্যবহার করি:

নিয়ামক দেখার জন্য:

var cellHeights: [IndexPath : CGFloat] = [:]


func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeights[indexPath] = cell.frame.size.height
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return cellHeights[indexPath] ?? 70.0 
}

ইউআইটিএবলভিউয়ের এক্সটেনশন হিসাবে

extension UITableView {
  func reloadSectionWithouAnimation(section: Int) {
      UIView.performWithoutAnimation {
          let offset = self.contentOffset
          self.reloadSections(IndexSet(integer: section), with: .none)
          self.contentOffset = offset
      }
  }
}

ফলাফল হলো

tableView.reloadSectionWithouAnimation(section: indexPath.section)

1
আমার জন্য চাবিকাঠিটি তার ইউআইটিএবলভিউ এক্সটেনশনটি এখানে বাস্তবায়ন করেছিল। খুব চালাক. ধন্যবাদ রাস্টিস্লাভ
বেনি

নিখুঁতভাবে কাজ করে তবে এটিতে কেবল একটি ত্রুটি রয়েছে, শিরোনাম, পাদলেখ বা সারি সন্নিবেশ করার সময় আপনি অ্যানিমেশনটি হারাবেন।
সৌফিয়ান হোসাম

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

11

আমি আজ এটিতে ছুটে এসে পর্যবেক্ষণ করেছি:

  1. এটি শুধুমাত্র আইওএস 8, সত্যই।
  2. ওভাররাইড করা cellForRowAtIndexPathকোনও উপকারে আসে না।

ফিক্সটি আসলে বেশ সহজ ছিল:

ওভাররাইড estimatedHeightForRowAtIndexPathএবং নিশ্চিত করুন যে এটি সঠিক মানগুলি দেয় returns

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

দ্রষ্টব্য: আমি আসলে আমার ঘরের আকার জানি। দুটি মাত্র সম্ভাব্য মান রয়েছে। আপনার কোষ সত্যিই পরিবর্তনশীল আকারের হয়, তাহলে আপনি ক্যাশে করতে চাইবেন cell.bounds.size.heightথেকেtableView:willDisplayCell:forRowAtIndexPath:


2
এটা ওয়েন ফিক্সড একটি উচ্চ মান estimatedHeightForRowAtIndexPath পদ্ধতি অগ্রাহ্য, উদাহরণস্বরূপ 300f জন্য
ফ্ল্যাপি

1
@ ফ্ল্যাপি এটি আকর্ষণীয় যে কীভাবে আপনার সরবরাহিত সমাধান কাজ করে এবং অন্যান্য প্রস্তাবিত কৌশলগুলির চেয়ে কম হয়। একটি উত্তর হিসাবে এটি পোস্ট বিবেচনা করবেন না।
রোহান সানাপ

9

আপনি প্রকৃতপক্ষে ব্যবহার করে কেবলমাত্র নির্দিষ্ট কিছু সারি পুনরায় লোড করতে পারেন reloadRowsAtIndexPaths:

tableView.reloadRowsAtIndexPaths(indexPathArray, withRowAnimation: UITableViewRowAnimation.None)

তবে, সাধারণভাবে, আপনি টেবিল ঘরের উচ্চতার পরিবর্তনগুলিও এনিমেট করতে পারেন:

tableView.beginUpdates()
tableView.endUpdates()

আমি প্রারম্ভের আপডেটগুলি / শেষগুলি আপডেট করার পদ্ধতিটি চেষ্টা করেছি, তবে এটি কেবল আমার টেবিলের দৃশ্যমান সারিগুলিকেই প্রভাবিত করে। আমি যখন স্ক্রোল করব তখন আমার এখনও সমস্যাটি রয়েছে।
ডেভিড

@ ডেভিড সম্ভবত কারণ আপনি আনুমানিক সারি উচ্চতা ব্যবহার করছেন।
লিন্ডসে স্কট 21

আমার কি আমার আনুমানিক রৌহাইটগুলি থেকে মুক্তি পাওয়া উচিত, এবং পরিবর্তে এটি স্টার্টআপডেটস এবং এন্ডপুটেটস দিয়ে প্রতিস্থাপন করা উচিত?
ডেভিড

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

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

3

এখানে কিছুটা সংক্ষিপ্ত সংস্করণ:

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return self.cellHeightsDictionary[indexPath] ?? UITableViewAutomaticDimension
}

3

উচ্চমানের সাথে আনুমানিক হাইফটআরআউটআইডেক্সপথ পদ্ধতিটি ওভাররাইড করা, উদাহরণস্বরূপ 300f

এই সমস্যা ঠিক করা উচিত :)


2

আমি বিশ্বাস করি যে একটি বাগ রয়েছে যা আইওএস 11 এ চালু হয়েছিল।

আপনি যখন reloadটেবিলভিউটি করেন তখন contentOffSetঅপ্রত্যাশিতভাবে পরিবর্তন হয়। আসলে contentOffsetপুনরায় লোডের পরে পরিবর্তন করা উচিত নয়। এটি ভুল সংকলনের কারণে ঘটে থাকেUITableViewAutomaticDimension

আপনাকে নিজের সংরক্ষণ করতে হবে contentOffSetএবং আপনার পুনরায় লোড শেষ হওয়ার পরে এটি আপনার সংরক্ষিত মানটিতে আবার সেট করতে হবে।

func reloadTableOnMain(with offset: CGPoint = CGPoint.zero){

    DispatchQueue.main.async { [weak self] () in

        self?.tableView.reloadData()
        self?.tableView.layoutIfNeeded()
        self?.tableView.contentOffset = offset
    }
}

আপনি এটি কিভাবে ব্যবহার করবেন?

someFunctionThatMakesChangesToYourDatasource()
let offset = tableview.contentOffset
reloadTableOnMain(with: offset)

এই উত্তরটি থেকে উদ্ভূত হয় এখানে


2

এই একজন আমার জন্য সুইফট 4 এ কাজ করেছিলেন:

extension UITableView {

    func reloadWithoutAnimation() {
        let lastScrollOffset = contentOffset
        reloadData()
        layoutIfNeeded()
        setContentOffset(lastScrollOffset, animated: false)
    }
}

1

এই সমাধানগুলির কোনওোটাই আমার পক্ষে কাজ করেনি। আমি সুইফট 4 এবং এক্সকোড 10.1 দিয়ে যা করেছি তা এখানে ...

ViewDidLoad () এ, সারণী গতিশীল সারি উচ্চতা ঘোষণা করুন এবং কোষগুলিতে সঠিক সীমাবদ্ধতা তৈরি করুন ...

tableView.rowHeight = UITableView.automaticDimension

ভিডিডিএলড () এও, আপনার সমস্ত টেবিলভিউ সেল নিবগুলি এই জাতীয় সারণী দর্শনতে নিবন্ধ করুন:

tableView.register(UINib(nibName: "YourTableViewCell", bundle: nil), forCellReuseIdentifier: "YourTableViewCell")
tableView.register(UINib(nibName: "YourSecondTableViewCell", bundle: nil), forCellReuseIdentifier: "YourSecondTableViewCell")
tableView.register(UINib(nibName: "YourThirdTableViewCell", bundle: nil), forCellReuseIdentifier: "YourThirdTableViewCell")

টেবিলভিউ উচ্চতার জন্যরোআআউটে, সূচকপথ.রোতে প্রতিটি কক্ষের উচ্চতার সমান উচ্চতা ফেরান ...

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

    if indexPath.row == 0 {
        let cell = Bundle.main.loadNibNamed("YourTableViewCell", owner: self, options: nil)?.first as! YourTableViewCell
        return cell.layer.frame.height
    } else if indexPath.row == 1 {
        let cell = Bundle.main.loadNibNamed("YourSecondTableViewCell", owner: self, options: nil)?.first as! YourSecondTableViewCell
        return cell.layer.frame.height
    } else {
        let cell = Bundle.main.loadNibNamed("YourThirdTableViewCell", owner: self, options: nil)?.first as! YourThirdTableViewCell
        return cell.layer.frame.height
    } 

}

এখন টেবিলের প্রতিটি কক্ষের জন্য আনুমানিক সারির উচ্চতা দিনভিউরোরআউএটি অনুমান করুন। যথাযথ আপনি পারেন হিসাবে ...

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {

    if indexPath.row == 0 {
        return 400 // or whatever YourTableViewCell's height is
    } else if indexPath.row == 1 {
        return 231 // or whatever YourSecondTableViewCell's height is
    } else {
        return 216 // or whatever YourThirdTableViewCell's height is
    } 

}

এটি কাজ করা উচিত ...

টেবিলভিউ.রেলোডডাটা () কে কল করার সময় আমার কন্টেন্ট অফসেট সংরক্ষণ এবং সেট করার দরকার নেই)


1

আমার 2 টি আলাদা আলাদা উচ্চতা রয়েছে।

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let cellHeight = CGFloat(checkIsCleanResultSection(index: indexPath.row) ? 130 : 160)
        return Helper.makeDeviceSpecificCommonSize(cellHeight)
    }

আমি আনুমানিক হাইফোরআরআউট যুক্ত করার পরে , আর কোনও জাম্পিং হয়নি।

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    let cellHeight = CGFloat(checkIsCleanResultSection(index: indexPath.row) ? 130 : 160)
    return Helper.makeDeviceSpecificCommonSize(cellHeight)
}

0

cell.layoutSubviews()ঘরে ফিরে যাওয়ার আগে কল করার চেষ্টা করুন func cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell?। এটি আইওএস 8-তে বাগ হিসাবে পরিচিত।


0

আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন ViewDidLoad()

tableView.estimatedRowHeight = 0     // if have just tableViewCells <br/>

// use this if you have tableview Header/footer <br/>
tableView.estimatedSectionFooterHeight = 0 <br/>
tableView.estimatedSectionHeaderHeight = 0

0

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

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


0

আমারো একই ইস্যু ছিল. অ্যানিমেশন ছাড়াই আমার কাছে পৃষ্ঠাগুলি এবং পুনরায় লোডিং ডেটা ছিল তবে এটি জাম্পিং রোধ করতে স্ক্রোলটিকে সহায়তা করে না। আমার আইফোনগুলির বিভিন্ন আকার রয়েছে, স্ক্রোলটি আইফোন 8 এ ঝাঁঝালো ছিল না তবে এটি আইফোন 7 + এ ঝাপটায় ছিল +

আমি ভিউডিডলড ফাংশনে নিম্নলিখিত পরিবর্তনগুলি প্রয়োগ করেছি :

    self.myTableView.estimatedRowHeight = 0.0
    self.myTableView.estimatedSectionFooterHeight = 0
    self.myTableView.estimatedSectionHeaderHeight = 0

এবং আমার সমস্যা সমাধান হয়েছে। আমি এটা খুব সাহায্য করে আশা করি।


0

আমি যে সমস্যাটি পেয়েছি সেগুলির সমাধান করার একটি উপায়

CATransaction.begin()
UIView.setAnimationsEnabled(false)
CATransaction.setCompletionBlock {
   UIView.setAnimationsEnabled(true)
}
tableView.reloadSections([indexPath.section], with: .none)
CATransaction.commit()

-2

বাস্তবে আমি খুঁজে পেয়েছি আপনি যদি reloadRowsঝাঁপ দেওয়ার সমস্যার কারণ ব্যবহার করেন । তারপরে আপনার এটির reloadSectionsমতো ব্যবহার করার চেষ্টা করা উচিত :

UIView.performWithoutAnimation {
    tableView.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: .none)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.