যখন ইউআইটিএবলভিউ ডেটা জিজ্ঞাসা শেষ করে?


108

যখন কোনও UITableViewতার ডেটা উত্স থেকে ডেটা জিজ্ঞাসা শেষ করে তখন এটির কোনও উপায় খুঁজে পাওয়া যায় ?

কোনটিই viewDidLoad/ viewWillAppear/ viewDidAppearসংশ্লিষ্ট দৃশ্য নিয়ামক (পদ্ধতি UITableViewController) তারা সব আগুন খুব তাড়াতাড়ি এখানে ব্যবহার করা হয়। এগুলির মধ্যে কোনওটিই (সম্পূর্ণরূপে বোধগম্য) গ্যারান্টি দেয় না যে ডেটা উত্সের অনুসন্ধানগুলি আপাতত শেষ হয়েছে (উদাহরণস্বরূপ, ভিউ স্ক্রোল না হওয়া পর্যন্ত)।

এক কার্যসংক্রান্ত আমি খুঁজে পেয়েছি কল হয় reloadDataমধ্যে viewDidAppear, যেহেতু, যখন reloadDataআয়, টেবিল ভিউ হয় যতটা তথ্য উৎস অনুসন্ধান যেমন সময়ের জন্য প্রয়োজন শেষ করেছি নিশ্চিত।

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

আমি একেবারেই এটি করার কারণটি হ'ল আমি এর স্ক্রোল অবস্থানটি সংরক্ষণ করতে চাই UITableView- তবে ঠিক নিকটতম সারিতে নয়, কেবল পিক্সেল স্তরে।

যখন স্ক্রল অবস্থান (ব্যবহার পুনরূদ্ধার scrollRectToVisible:animated:), আমি টেবিল ভিউ প্রয়োজন ইতিমধ্যে এটা যথেষ্ট তথ্য আছে, বা অন্য করতে scrollRectToVisible:animated:পদ্ধতি কল কিছুই (যা আপনি যদি কোন তার নিজের উপর কল এরকম করে viewDidLoad, viewWillAppearবা viewDidAppear)।


দেখে মনে হচ্ছে আপনি এই স্ট্যাকওভারফ্লো . com/a/11672379/2082172 এর মতো কিছু খুঁজছেন ।
তৈমুর কুচারভ

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

উত্তর:


61

উত্তরটি লেখার পর থেকে ইউআইটিএবলভিউ বাস্তবায়নে কিছু পরিবর্তন করার কারণে এই উত্তরটি আর কাজ করছে বলে মনে হচ্ছে না। এই মন্তব্যটি দেখুন: ইউআইটিএবলভিউ ডেটা জিজ্ঞাসা শেষ করার পরে বিজ্ঞপ্তি পান?

আমি কয়েকদিন জন্য এই সমস্যার সঙ্গে বাজানো এবং মনে করে যে, subclassing করে থাকেন UITableViewএর reloadDataসবচেয়ে ভালো উপায় হল:

- (void)reloadData {

    NSLog(@"BEGIN reloadData");

    [super reloadData];

    NSLog(@"END reloadData");

}

reloadDataটেবিলটির ডেটা শেষ হওয়ার আগে শেষ হয় না। সুতরাং, যখন দ্বিতীয়টি NSLogবরখাস্ত করা হয়, টেবিলের ভিউ আসলে ডেটা জিজ্ঞাসা শেষ করে।

UITableViewআগে এবং পরে প্রতিনিধিদের কাছে পদ্ধতিগুলি প্রেরণ করার জন্য আমি সাবক্ল্যাস করেছি reloadData। ইহা যাদুর মত কাজ করে।


2
বলতে হবে, এটি সেরা সমাধান বলে মনে হচ্ছে। এটি কেবল কার্যকর করা হয়েছে এবং আপনি যেমন বলেছিলেন এটি একটি কবজির মতো কাজ করে। ধন্যবাদ!
তত্ত্ব 21

2
@ এরিকমোর্যান্ড আপনি বলেছেন যে "টেবিলটির ডেটা পুনরায় লোড শেষ হওয়ার আগেই পুনরায় লোড ডেটা শেষ হবে না।" আপনি এর দ্বারা কী বোঝাতে চেয়েছেন তা কি আপনি পরিষ্কার করতে পারেন? আমি reloadDataতাৎক্ষণিকভাবে প্রত্যাবর্তনটি পেয়েছি এবং ঘরগুলি বাস্তবে পুনরায় লোড করার আগে (অর্থাত্‍ পদ্ধতিগুলি বলার আগে) আমি "এন্ড রিলোডলোড" দেখি see UITableViewDataSourceআমার পরীক্ষা আপনি যা বলছেন তার বিপরীত চিত্র প্রদর্শন করে। আপনি যা বলতে চাইছেন তা অবশ্যই আমার ভুল বুঝাব।
রব

3
এরিকের উত্তর কি পুনরায় লোডডাটা বাস্তবায়ন না করা (ওভাররাইডিং না পড়ুন), পুনরায় লোডডেটা কল করা (যা মূলত [সুপার রিলোডডাটা হবে), এবং তারপরে ফোন করার পরে, আপনি যে
জিনিসটি

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

3
কলিং পর প্রধান কিউ উপর একটি ব্লক সমাপ্ত হতে কোড পোস্টিং [super reloadData]আমার জন্য কাজ করে: dispatch_async(dispatch_get_main_queue(), ^{NSLog(@"reload complete");});। এটি মূলত ব্যাঙগুলিকে ঝাঁকুনি দেয় যা সারণীতে এই দর্শন দ্বারা পোস্ট করা হয় reloadData
টিমোথি মুজ

53

আমার অ্যাপ্লিকেশনটিতে আমার একই পরিস্থিতি ছিল এবং আমি ভেবেছিলাম যে আমার উত্তরগুলি আপনার কাছে পোস্ট করব কারণ এখানে উল্লিখিত অন্যান্য উত্তরগুলি iOS7 এবং তার পরে আমার জন্য কাজ করে না

অবশেষে এটিই আমার পক্ষে কাজ করেছে।

[yourTableview reloadData];

dispatch_async(dispatch_get_main_queue(),^{
        NSIndexPath *path = [NSIndexPath indexPathForRow:yourRow inSection:yourSection];
        //Basically maintain your logic to get the indexpath
        [yourTableview scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
 });

সুইফট আপডেট:

yourTableview.reloadData()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
    let path : NSIndexPath = NSIndexPath(forRow: myRowValue, inSection: mySectionValue)
    //Basically maintain your logic to get the indexpath
    yourTableview.scrollToRowAtIndexPath(path, atScrollPosition: UITableViewScrollPosition.Top, animated: true)

})

সুতরাং এটি কিভাবে কাজ করে।

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

IOS7 এবং iOS8 এ পরীক্ষিত এবং এটি দুর্দান্ত কাজ করে;)

আইওএস 9 এর জন্য আপডেট: এটি আইওএস 9ও ঠিক কাজ করে। আমি পিসি হিসাবে গিথুবে একটি নমুনা প্রকল্প তৈরি করেছি। https://github.com/ipraba/TableReloadingNotifier

আমি এখানে আমার পরীক্ষার স্ক্রিনশট সংযুক্ত করছি।

পরীক্ষিত পরিবেশ: Xcode7 থেকে আইওএস 9 আইফোন 6 সিমুলেটর

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


8
ভাল উত্তর আমি খুঁজে পেয়েছি!
নিকোলে শুভেনকোভ

আমি জিতেছি আমি iOS9 এ একটি পরীক্ষা করেছি এবং এটি ঠিক কাজ করে works আপনি কি দয়া করে github.com/ipraba/TableReloadingNotifier
ipraba

এটি আমার এমুলেটরটিতে দুর্দান্ত কাজ করে তবে প্রকৃত ডিভাইসে কাজ করে বলে মনে হয় না। অন্য কেউ এই সমস্যা আছে?
sosale151

1
এই সমাধানটি শেষ পর্যন্ত আমার পক্ষে কাজ করে! এটা iOS 9 এর উপর কাজ করে জরিমানা
স্ট্রং

1
আমি রিয়েল ডিভাইস, একটি আইফোন 6 এস পরীক্ষা করেছি। এটি খুব ভাল কাজ করে।
শক্তিশালী

25

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

@ এরিক মোর্যান্ডের উত্তরটি প্রসারিত করতে, একটি সমাপ্তি ব্লক রেখে দিন Who ব্লকটি কে পছন্দ করে না?

@interface DUTableView : UITableView

   - (void) reloadDataWithCompletion:( void (^) (void) )completionBlock;

@end

এবং...

#import "DUTableView.h"

@implementation DUTableView

- (void) reloadDataWithCompletion:( void (^) (void) )completionBlock {
    [super reloadData];
    if(completionBlock) {
        completionBlock();
    }
}

@end

ব্যবহার:

[self.tableView reloadDataWithCompletion:^{
                                            //do your stuff here
                                        }];

2
আমি যথেষ্ট পরিমাণে ব্লক পেতে পারি না। আপনার খুব ভাল ব্লক পেলে কার একজন প্রতিনিধি প্রয়োজন!
বন্দেজাপাইসায়

আমি এটি পছন্দ করি তবে যখন সিস্টেমটি পুনরায়লোডডাটা () ডাকে, যেমন টেবিলটি প্রথম প্রদর্শিত হয় তখন কী হয়?
প্রতিসম

12
এটি সমাধান নয় কমপ্লিটেশন ব্লকটি সেলফোরআউটইন্ডেক্সপথের আগে সম্পাদন শুরু করে
zvjerka24

1
এটি কাজ করবে না; রিলোডডেটা কোনও ব্লক করার পদ্ধতি নয়। এই কোড বলা হয় অবিলম্বে reloadData কলিং পর, এমনকি যদি কোষ এখনো পুনরায় লোড করা হয় না। এছাড়াও, এই কোডটি দেখুন এবং আপনি দেখতে পাবেন যে আপনি পুনরায়লোডডাটার পরে কেবল আপনার কোডটি রেখেছিলেন
কলিনতা

1
এটি আমার পক্ষে সামান্য পরিবর্তন নিয়ে কাজ করে। পরিবর্তে সমাপ্তির ব্লক সরাসরি কলিং, এটি একটি ব্লক প্রধান কিউ পোস্ট কল: dispatch_async(dispatch_get_main_queue(), ^{completionBlock();});। এটি মূলত টেবিল ভিউ দ্বারা পোস্ট করা ব্লকগুলিকে ব্যাপ করে reloadData
তীমথিয় মুজ

11

পুনরায়লোডডাটা দৃশ্যমান কক্ষগুলির জন্য কেবল ডেটা চাইছে। বলে, আপনার টেবিলের অংশটি বোঝা হয়ে গেলে নির্দিষ্ট করতে হবে, দয়া করে tableView: willDisplayCell:পদ্ধতিটি হুক করুন ।

- (void) reloadDisplayData
{
    isLoading =  YES;
    NSLog(@"Reload display with last index %d", lastIndex);
    [_tableView reloadData];
    if(lastIndex <= 0){
    isLoading = YES;
    //Notify completed
}

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row >= lastIndex){
    isLoading = NO;
    //Notify completed
}

1
আমি নিশ্চিত না এই কাজ কিনা। সর্বশেষ সূচীকরণটি টেবিলের ডেটার সমাপ্তি (যেমন 100 রেকর্ড) তবে টেবিলটি কেবল পর্দায় যা দৃশ্যমান তা প্রদর্শন করবে (যেমন 8 রেকর্ড)।
ট্র্যাভিস এম।

10

এটাই আমার সমাধান। 100% কাজ করে এবং অনেক প্রকল্পে ব্যবহৃত হয়। এটি একটি সাধারণ ইউআইটিএবলভিউ সাবক্লাস।

@protocol MyTableViewDelegate<NSObject, UITableViewDelegate>
@optional
- (void)tableViewWillReloadData:(UITableView *)tableView;
- (void)tableViewDidReloadData:(UITableView *)tableView;
@end

@interface MyTableView : UITableView {
    struct {
        unsigned int delegateWillReloadData:1;
        unsigned int delegateDidReloadData:1;
        unsigned int reloading:1;
    } _flags;
}
@end

@implementation MyTableView
- (id<MyTableViewDelegate>)delegate {
    return (id<MyTableViewDelegate>)[super delegate];
}

- (void)setDelegate:(id<MyTableViewDelegate>)delegate {
    [super setDelegate:delegate];
    _flags.delegateWillReloadData = [delegate respondsToSelector:@selector(tableViewWillReloadData:)];
    _flags.delegateDidReloadData = [delegate    respondsToSelector:@selector(tableViewDidReloadData:)];
}

- (void)reloadData {
    [super reloadData];
    if (_flags.reloading == NO) {
        _flags.reloading = YES;
        if (_flags.delegateWillReloadData) {
            [(id<MyTableViewDelegate>)self.delegate tableViewWillReloadData:self];
        }
        [self performSelector:@selector(finishReload) withObject:nil afterDelay:0.0f];
    }
}

- (void)finishReload {
    _flags.reloading = NO;
    if (_flags.delegateDidReloadData) {
        [(id<MyTableViewDelegate>)self.delegate tableViewDidReloadData:self];
    }
}

@end

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

এমনকি আপনি সাবক্লাস UITableViewকরতে না চাইলে আপনি কেবল কল করতে পারেন [performSelector:@selector(finishReload) withObject:nil afterDelay:0.0f]এবং টেবিলটি পুনরায় লোডিং শেষ হওয়ার পরে আপনার নির্বাচককে ডাকা হবে। তবে আপনার অবশ্যই নিশ্চিত হওয়া উচিত যে নির্বাচককে একবার কল করার জন্য একবার কল করা হয়েছিল reloadData:

[self.tableView reloadData];
[self performSelector:@selector(finishReload) withObject:nil afterDelay:0.0f];

উপভোগ করুন। :)


1
সঞ্চালনকারী কল ব্যবহার করা উজ্জ্বল। সরল এবং কর্মক্ষম, থেক্স
জুলিয়া

এটি একেবারে দুর্দান্ত। আমি কয়েক দিন ধরে এই নিয়ে বিচরণ করছি। ধন্যবাদ!
ডেভিড ক্যারিকো

@ মার্কক্রাইজানৌসকি, আপনি কি আইওএস 9 তে পরীক্ষা করেছেন?
ভিক্টর

@ মার্কক্রাইজানৌসকি, প্রম্পট প্রতিক্রিয়ার জন্য ধন্যবাদ! আইওএস 7 এবং 8 এ দুর্দান্ত কাজ করে
ভিক্টর

performSelectorমূল থ্রেডে সমাধানগুলি বা সম্পাদনকারী আইওএস 9 এdispatch_asynch কাজ করে না ।
ম্যানুয়েল

8

এটি কিছুটা পৃথক প্রশ্নের উত্তর: কখন UITableViewফোন করা শেষ হয়েছিল তা আমার জানা দরকার cellForRowAtIndexPath()। আমি layoutSubviews()উপক্লাস করেছি (ধন্যবাদ @ এরিক মোর্যান্ড) এবং একটি প্রতিনিধি কলব্যাক যোগ করেছি:

SDTableView.h:

@protocol SDTableViewDelegate <NSObject, UITableViewDelegate>
@required
- (void)willReloadData;
- (void)didReloadData;
- (void)willLayoutSubviews;
- (void)didLayoutSubviews;
@end

@interface SDTableView : UITableView

@property(nonatomic,assign) id <SDTableViewDelegate> delegate;

@end;

SDTableView.m:

#import "SDTableView.h"

@implementation SDTableView

@dynamic delegate;

- (void) reloadData {
    [self.delegate willReloadData];

    [super reloadData];

    [self.delegate didReloadData];
}

- (void) layoutSubviews {
    [self.delegate willLayoutSubviews];

    [super layoutSubviews];

    [self.delegate didLayoutSubviews];
}

@end

ব্যবহার:

MyTableViewController.h:

#import "SDTableView.h"
@interface MyTableViewController : UITableViewController <SDTableViewDelegate>
@property (nonatomic) BOOL reloadInProgress;

MyTableViewController.m:

#import "MyTableViewController.h"
@implementation MyTableViewController
@synthesize reloadInProgress;

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    if ( ! reloadInProgress) {
        NSLog(@"---- numberOfSectionsInTableView(): reloadInProgress=TRUE");
        reloadInProgress = TRUE;
    }

    return 1;
}

- (void)willReloadData {}
- (void)didReloadData {}
- (void)willLayoutSubviews {}

- (void)didLayoutSubviews {
    if (reloadInProgress) {
        NSLog(@"---- layoutSubviewsEnd(): reloadInProgress=FALSE");
        reloadInProgress = FALSE;
    }
}

দ্রষ্টব্য: এটি যেহেতু UITableViewএটির একটি সাবক্লাস যার মধ্যে ইতিমধ্যে একটি প্রতিনিধি সম্পত্তি MyTableViewControllerরয়েছে সেখানে নির্দেশ করে অন্য একটি যুক্ত করার দরকার নেই। "@Dynamic প্রতিনিধি" সংকলককে এই সম্পত্তিটি ব্যবহার করতে বলে। (এখানে একটি লিঙ্ক এই বর্ণনা দেওয়া হল: http://farhadnoorzay.com/2012/01/20/objective-c-how-to-add-delegate-methods-in-a-subclass/ )

UITableViewসম্পত্তি MyTableViewControllerআবশ্যক নতুন ব্যবহার করতে পরিবর্তন করা SDTableViewবর্গ। এটি ইন্টারফেস নির্মাতা পরিচয় পরিদর্শকতে করা হয়। নির্বাচন UITableViewভেতরে UITableViewControllerএবং তার "কাস্টম ক্লাস" তে সেট SDTableView


আপনি কোথায় আপনার MyTableViewController কে SDTableView এর প্রতিনিধি হিসাবে সেট করবেন? এসডিটিবেল ভিউতে "ডেলিগেট" নামের একটি সম্পত্তি সেট করা কীভাবে সম্ভব, যখন এর সুপারক্লাসে ইতিমধ্যে সেই নামের (ইউআইটিবেলভিউ.ডিলেগেট) সম্পত্তি রয়েছে? সম্পত্তি "ইউআইটিবেলভিউ" ধরণের এবং অবজেক্ট (এসডিটিবলভিউর একটি উদাহরণ) "এসডিটিবেল ভিউ" প্রকারের হয় তখন আপনি কীভাবে আপনার কাস্টম এসডিটিবলভিউটি মাই টেবিলভিউ কনট্রোলআর্টেবল ভিউ সম্পত্তিটিতে সংযুক্ত করবেন? আমি একই সমস্যার সাথে লড়াই করছি, তাই আমি আশাবাদী যে এই সমস্যার সমাধান রয়েছে :) :)
আর্ল গ্রে

সিমেট্রিকের কোডে (এসডিটিবেল ভিউ), পুনরায় লোডইনপ্রোগ্রেডকে ডায়ালআউটডাটাডে লেআউটআউটভিউগুলির পরিবর্তে FALSE এ সেট করা উচিত নয়? কারণ পুনঃলোডডেটাকে লেআউটআউটভিউগুলির পরে কল করা হয় এবং পুনরায় ডেটা শেষ হওয়ার আগে লোডটি করা বিবেচনা করা উচিত নয়।
tzuchien.chiu

এটি আইওএস 8 এর জন্য কাজ করে না, আইপ্রাবাবুর উত্তর অন্তর্ভুক্ত করতে হয়েছিল ।
স্টানার

6

আমি পরিবর্তনের জন্য বিজ্ঞপ্তি পেতে অনুরূপ কিছু পাওয়া যায় contentSizeএর TableView। আমি মনে করি যে এখানে কাজ করা উচিত কারণ কনটেন্টসাইজও লোডিং ডেটার সাথে পরিবর্তিত হয়।

এটা চেষ্টা কর:

ইন viewDidLoadলেখ,

[self.tableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld | NSKeyValueObservingOptionPrior context:NULL];

এবং এই পদ্ধতিটি আপনার ভিউকন্ট্রোলারে যুক্ত করুন:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"contentSize"]) {
        DLog(@"change = %@", change.description)

        NSValue *new = [change valueForKey:@"new"];
        NSValue *old = [change valueForKey:@"old"];

        if (new && old) {
            if (![old isEqualToValue:new]) {
                // do your stuff
            }
        }


    }
}

পরিবর্তনের জন্য আপনার চেকটিতে সামান্য পরিবর্তন দরকার হতে পারে। এটি যদিও আমার জন্য কাজ করেছে।

চিয়ার্স! :)


1
খুব চালাক. আমার জন্য পুরোপুরি কাজ করে। ভাগ করে নেওয়ার জন্য ধন্যবাদ!
DZenBot

2
মার্জিত! আমি কেবল যুক্ত করতে চাই তা হল আপনার নিজের এবং একজন পর্যবেক্ষক (সম্ভবত -ডালোক পদ্ধতিতে) অপসারণ করা দরকার। অথবা নিজেকে পর্যবেক্ষক হিসাবে যুক্ত করুন -viewWillAppearএবং নিজেকে -viewWillDisapearপদ্ধতিতে সরিয়ে দিন ।
লুজি

2

এটি একটি সম্ভাব্য সমাধান, যদিও এটি একটি হ্যাক:

[self.tableView reloadData];
[self performSelector:@selector(scrollTableView) withObject:nil afterDelay:0.3];

যেখানে আপনার -scrollTableViewপদ্ধতিটি দিয়ে টেবিলের দৃশ্য স্ক্রোল করে -scrollRectToVisible:animated:। এবং অবশ্যই, আপনি উপরের কোডে বিলম্বটি ০.০ থেকে আপনার জন্য কাজ করে যা মনে হচ্ছে কনফিগার করতে পারেন। হ্যাঁ, এটি হাস্যকরভাবে হ্যাকি, তবে এটি আমার আইফোন 5 এবং 4 এস এ আমার জন্য কাজ করে ...


2
এটি "হ্যাকি" বলে মনে হতে পারে তবে এটি সত্যিই স্ক্রোলিংয়ের জন্য একটি মানক পদ্ধতির: এটি পরবর্তী রান চক্র থেকে পিছিয়ে দিন। আমি দেরিটি 0 তে পরিবর্তন করব, যেহেতু এটি ঠিক একইভাবে কাজ করে এবং কম বিলম্ব হয়।
ফাতেমন

0 এ দেরি করে আমার জন্য কাজ করেন নি; ০.০ আমি যাচ্ছিলাম সবচেয়ে কম ছিল এবং এখনও ডেটা পেতে পারি।
জোশ ব্রাউন

@ ফ্যাটম্যান এটি আমার পক্ষে কাজ করেছে। আমি আমার বিলম্বের জন্য 0 ব্যবহার করতে সক্ষম হয়েছি। আপনাদের দুজনকেই ধন্যবাদ।
mcphersonjr

1

আমি বিশ্বাস করি তেমন কিছু আমার ছিল। উদাহরণস্বরূপ ভেরিয়েবল হিসাবে আমি একটি বিওওএল যুক্ত করেছি যা আমাকে বলছে অফসেটটি পুনরুদ্ধার করা হয়েছে কিনা এবং এটিতে চেক করুন -viewWillAppear:। যখন এটি পুনরুদ্ধার করা হয়নি, আমি সেই পদ্ধতিতে এটি পুনরুদ্ধার করি এবং আমি অফসেটটি পুনরুদ্ধার করেছি কি না তা বোঝাতে BOOL সেট করে।

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


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

তবে সম্ভবত আপনি বোঝাতে চেয়েছেন যে আপনি ভিউইল অ্যাপয়ারের মধ্যে পুনরায়লোডডাটা কল করে প্রথমে টেবিলের ঘরগুলি লোড করতে বাধ্য করছেন?
kennethmac2000

না, আমি পুনরায় লোড জোর করছি না। যখন আমার সমস্যা হয়েছিল, আমি অফসেটটি পুনরুদ্ধার করার চেষ্টা করেছি -viewDidLoad(যেখানে এটি অবশ্যই হওয়া উচিত) তবে আমি কেবল অফসেট অ্যানিমেটেড সেট করলেই এটি কাজ করে। -viewWillAppear:এটিতে অফসেটের সেটিংটি সরিয়ে নিয়ে কাজ করা হয়েছে তবে এটি একবার সেট করতে আমাকে একটি পতাকা বজায় রাখতে হয়েছিল। আমি মনে করি টেবিল ভিউ একবারে একটি ভিউতে যুক্ত হয়ে তার ডেটা পুনরায় লোড করে, তাই এটি ইতিমধ্যে -loadView। আপনি কি নিশ্চিত যে আপনার ভিউ লোডে আপনার ডেটা উপলব্ধ আছে? বা এটি একটি পৃথক থ্রেড বা কিছুতে লোড করা হচ্ছে?
জুস্ট

ঠিক আছে, সম্ভবত আপনি আমার বুঝতে এখানে সহায়তা করতে পারেন। কোনও ইউআইটিএলভিউ আপ নির্মিত হওয়ার পরে আমি কলগুলির ক্রমটি বুঝতে পারি understand 1) ভিউডিডলড প্রথমে গুলি করা হয়। এটি নির্দেশ করে যে ইউআইটিএবলভিউ মেমরিতে লোড হয়েছে। 2) ভিউউইল অ্যাপয়ার আগুনের পাশে রয়েছে। এটি ইঙ্গিত করে যে ইউআইটিএবলভিউ প্রদর্শিত হবে, তবে অগত্যা যে সমস্ত দৃশ্যমান ইউআইটিএবলভিউসেল বস্তু সম্পূর্ণরূপে তাত্ক্ষণিকভাবে / সমাপ্ত রেন্ডারিং হবে।
kennethmac2000

2
এবং উপরের সমস্তটি সত্য, তারপরে প্রশ্নটি হল: ইউআইটিএবল ভিউ যখন তার তথ্য উত্স থেকে কোনও স্ক্রোল অনুরোধের (যেমন, একটি স্ক্রোলরেটটেক্টভিভিজিবল: অ্যানিমেটেড: কল) গ্যারান্টি সরবরাহ করার জন্য পর্যাপ্ত তথ্য পেয়েছে তখন আমাদের কাছে কী অ-হ্যাকি বিকল্প রয়েছে তা আবিষ্কার করার জন্য? ) আসলে কাজ করবে (এবং কেবল কিছুই করবে না)?
kennethmac2000

1

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

এটি করার বিষয়ে বেশ কয়েকটি নিবন্ধ রয়েছে। এটি একটি।

আমি সেটকন্টেন্টঅফসেট ব্যবহার করার পরামর্শ দিচ্ছি: অ্যানিমেটেড: স্ক্রোলআরেক্টটওভিজিবলের পরিবর্তে: অ্যানিমেটেড: একটি স্ক্রোল দর্শনের পিক্সেল-নিখুঁত সেটিংসের জন্য।


1

আপনি নিম্নলিখিত যুক্তি চেষ্টা করতে পারেন:

-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    if ( [self chkIfLastCellIndexToCreate:tableView :indexPath]){
        NSLog(@"Created Last Cell. IndexPath = %@", indexPath);
        //[self.activityIndicator hide];
        //Do the task for TableView Loading Finished
    }
    prevIndexPath = indexPath;

    return cell;
}



-(BOOL) chkIfLastCellIndexToCreate:(UITableView*)tableView : (NSIndexPath *)indexPath{

    BOOL bRetVal = NO;
    NSArray *visibleIndices = [tableView indexPathsForVisibleRows];

    if (!visibleIndices || ![visibleIndices count])
        bRetVal = YES;

    NSIndexPath *firstVisibleIP = [visibleIndices objectAtIndex:0];
    NSIndexPath *lastVisibleIP = [visibleIndices objectAtIndex:[visibleIndices count]-1];

    if ((indexPath.row > prevIndexPath.row) && (indexPath.section >= prevIndexPath.section)){
        //Ascending - scrolling up
        if ([indexPath isEqual:lastVisibleIP]) {
            bRetVal = YES;
            //NSLog(@"Last Loading Cell :: %@", indexPath);
        }
    } else if ((indexPath.row < prevIndexPath.row) && (indexPath.section <= prevIndexPath.section)) {
        //Descending - scrolling down
        if ([indexPath isEqual:firstVisibleIP]) {
            bRetVal = YES;
            //NSLog(@"Last Loading Cell :: %@", indexPath);
        }
    }
    return bRetVal;
}

এবং আপনি পুনরায় লোড ডেটা কল করার আগে, উপিলিপেক্সপেটটি শূন্য করতে সেট করুন। ভালো লেগেছে:

prevIndexPath = nil;
[mainTableView reloadData];

আমি এনএসলোগ দিয়ে পরীক্ষা করেছি এবং এই যুক্তিটি ঠিক আছে বলে মনে হচ্ছে। আপনি প্রয়োজন হিসাবে কাস্টমাইজ / উন্নত করতে পারেন।


0

অবশেষে আমি আমার কোডটি এটি দিয়ে তৈরি করেছি -

[tableView scrollToRowAtIndexPath:scrollToIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];

কিছু জিনিস ছিল যা যত্ন নেওয়ার প্রয়োজন ছিল -

  1. " - (UITableViewCell *)MyTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath" এর মধ্যে কল করুন
  2. কেবলমাত্র নিশ্চিত করুন যে "স্ক্রোলটিওআউটইন্টেক্সপথ" বার্তাটি ইউআইটিবেবলের প্রাসঙ্গিক উদাহরণটিতে প্রেরণ করা হয়েছে, যা অবশ্যই এই ক্ষেত্রে মাই টেবিলভিউ।
  3. আমার ক্ষেত্রে ইউআইভিউ হল এমন ভিউ যা ইউআইটিএবলভিউয়ের উদাহরণ রয়েছে
  4. এছাড়াও, প্রতিটি সেল লোডের জন্য এটি কল করা হবে। অতএব, একবারে "স্ক্রোলটরোআউটইন্টেক্সপ্যাথ" কল করা এড়ানোর জন্য "সেলফোর্ডআউটইন্ডেক্সপথ" এর ভিতরে একটি যুক্তি স্থাপন করুন।

এবং কেবল নিশ্চিত করুন যে এই টুকরোটি একাধিকবার ডাকা হবে না। যদি এটি স্ক্রোলিং লক করে না।
smile.al.d.way

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

0

সমস্ত ডেটা লোড হওয়ার পরে আপনি নিজের টেবিলভিউটি আকার পরিবর্তন করতে পারেন বা এই পদ্ধতিতে সামগ্রীর আকার সেট করতে পারেন:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    tableView.frame =CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.frame.size.width, tableView.contentSize.height);
}

0

আমি কেবল নির্ধারিত টাইমার পুনরাবৃত্তি চালাই এবং টেবিলের হাইডারভিউ উচ্চতা (যখন টেবিলের মধ্যে সারিগুলির সামগ্রী রয়েছে) কেবল তখন টেবিলের বিষয়বস্তু আকার বড় হলে এটিকে অবৈধ করে তুলি। সি # তে কোড (একঘেয়েমি), তবে আমি আশা করি ধারণাটি পরিষ্কার হয়েছে:

    public override void ReloadTableData()
    {
        base.ReloadTableData();

        // don't do anything if there is no data
        if (ItemsSource != null && ItemsSource.Length > 0)
        {
            _timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.MinValue, 
                new NSAction(() => 
                {
                    // make sure that table has header view and content size is big enought
                    if (TableView.TableHeaderView != null &&
                        TableView.ContentSize.Height > 
                            TableView.TableHeaderView.Frame.Height)
                    {
                        TableView.SetContentOffset(
                            new PointF(0, TableView.TableHeaderView.Frame.Height), false);
                        _timer.Invalidate();
                        _timer = null;
                    }
                }));
        }
    }

0

UITableView layoutSubviewsটেবিল ভিউটি এতে সামগ্রী প্রদর্শন করার ঠিক আগে বলা হয় না ? আমি লক্ষ্য করেছি যে টেবিল ভিউ এর ডেটা লোড করা শেষ হলে এটি বলা হয়ে থাকে, সম্ভবত আপনাকে সেই দিকে তদন্ত করা উচিত।


0

আইওএস 6 এর পরে, UITableviewপ্রতিনিধি পদ্ধতিটি ডেকেছিল:

-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section

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


0

সেরা সমাধান আমি সুইফটে খুঁজে পেয়েছি

extension UITableView {
    func reloadData(completion: ()->()) {
        self.reloadData()
        dispatch_async(dispatch_get_main_queue()) {
            completion()
        }
    }
}

-1

কেন শুধু প্রসারিত হবে না?

@interface UITableView(reloadComplete)
- (void) reloadDataWithCompletion:( void (^) (void) )completionBlock;
@end

@implementation UITableView(reloadComplete)
- (void) reloadDataWithCompletion:( void (^) (void) )completionBlock {
    [self reloadData];
    if(completionBlock) {
        completionBlock();
    }
}
@end

শেষ পর্যন্ত স্ক্রোল করুন:

[self.table reloadDataWithCompletion:^{
    NSInteger numberOfRows = [self.table numberOfRowsInSection:0];
    if (numberOfRows > 0)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:numberOfRows-1 inSection:0];
        [self.table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
    }
}];

প্রচুর ডেটা দিয়ে পরীক্ষা করা হয়নি

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