ios - Maintaining scroll position after reload in tableView -
i've got tableview. when user taps 1 of records, check it's property , basing on i'm filtering results , showing similar results - need refresh tableview.
the problem user can scroll up/down tableview. need scroll tableview cell @ same uitableviewscrollposition
before refresh.
obviously, i'm saving last tapped item
- (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { _lastselecteditem = [self itemforindexpath:indexpath]; }
then after reloading tableview:
nsindexpath *indexpath = [self indexpathforitem:_lastselecteditem]; if (_tableview.numberofsections > indexpath.section && [_tableview numberofrowsinsection:indexpath.section] > indexpath.row) { [_tableview scrolltorowatindexpath:indexpath atscrollposition:uitableviewscrollpositionmiddle animated:no]; _lastselecteditem = nil; }
it but... user not finish @ uitableviewscrollpositionmiddle
. have finish scrolling @ uitableviewscrollpositiontop
or uitableviewscrollpositionbottom
or somewhere between.
-- edit --
calculating via offset problematic, offset difference between start of view , top table scroll position.. while i'm not interested in value :/.
because structure quite complicated finished way (eg. expandable sections etc). please mind, i'm saving _lastselecteditem
, object @ datasource, indexpath change after refresh.
- (void)refresh { [self savelastscrollposition]; [self reloaddata]; // inside reload data + reload tableview [self scrolltolastscrollposition]; } - (nsinteger)heighttominyofcellatindexpath:(nsindexpath *)indexpath { nsinteger sections = indexpath.section; nsinteger totalrows = 0; (nsinteger section = 0; section < indexpath.section; section++) { totalrows += [self.tableview numberofrowsinsection:section]; } totalrows += indexpath.row; return ((sections + 1) * kheaderheight + totalrows * krowheight); } - (void)savelastscrollposition { if (_lastselecteditem) { // make sure have item selected nsindexpath *indexpath = [self itemforitem:_lastselecteditem]; nsinteger aboveitemheight = [self heighttominyofcellatindexpath:indexpath]; cgfloat contentoffsety = self.tableview.contentoffset.y; _previousoffset = aboveitemheight - contentoffsety; } } - (void)scrolltolastscrollpostion { if (_lastselecteditem) { // make sure have item selected nsindexpath *indexpath = [self itemforitem:_lastselecteditem]; if (self.tableview.numberofsections > indexpath.section && [self.tableview numberofrowsinsection:indexpath.section] > indexpath.row) { // make sure indexpath still exist after reload nsinteger aboveitemheight = [self heighttominyofcellatindexpath:indexpath]; // height of items above selected index cgpoint offset = cgpointmake(0.f, aboveitemheight - _previousoffset); // in case index should higher: eg earlier item @ index (4,8) @ (0,0) if (offset.y < 0) { offset.y = 0; } [self.tableview setcontentoffset:offset animated:no]; // jump, user shouldn't see _previousoffset = 0; // forget calculated values _lastselecteditem = nil; } } }
Comments
Post a Comment