2013-12-02 5 views
1

Вот настройки: У меня есть UIControls в ячейках таблицы, которые позволяют раздвижными справа налево для функции удаления (как Clear)Как сделать таблицу скроллинг работы: UIControl в UITableView в UIControl

Клетки таблицы внутри UITableView.

TableView живет в другом UIControl, который позволяет прокручивать слева направо или налево, чтобы изменить дни. Когда это происходит, новый TableView создается справа или слева от основного, а новый вытягивается слева или справа до тех пор, пока не будет достигнуто пороговое значение, и анимация не будет принята, а затем заменит старый на новый.

В некоторых условиях все эти взаимодействия действительно работают правильно. Проблема заключается в том, что после нескольких взаимодействий (слайды в таблице кажутся проблематичными) становится сложно/невозможно прокручивать таблицу.

Вот код TableViewSlider (UIControl верхнего уровня, который содержит TableViews). Благодарим за любую идею!

@implementation OSETableViewSlider 


- (void) initialize { 
    self.backgroundColor = [UIColor backgroundFlatColor]; 
    self.mainTableView = [self createUITableView]; 
    self.mainTableView.frame = CGRectMake(0,0, self.frame.size.width, self.frame.size.height); 
    self.mainTableView.hidden = NO; 
    [self addSubview:self.mainTableView]; 
    self.transitionInProgress = NO; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self initialize]; 
    } 
    return self; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super initWithCoder:aDecoder]; 
    if(self) { 
     [self initialize]; 
    } 
    return self; 
} 

- (UITableView *)createUITableView { 
    UITableView *newTable = [[UITableView alloc] init]; 
    newTable.hidden = YES; 
    newTable.separatorStyle = UITableViewCellSeparatorStyleNone; 
    newTable.scrollEnabled = YES; 
    newTable.bounces = YES; 
    newTable.dataSource = self; 
    newTable.delegate = self; 
    newTable.backgroundColor = [UIColor backgroundFlatColor]; 

    return newTable; 
} 

- (void)setFrame:(CGRect)frame { 
    super.frame = frame; 
    self.mainTableView.frame = CGRectMake(0,0, frame.size.width, frame.size.height); 
} 

- (void)transitionToDate:(NSDate *)date fromRight:(BOOL)rightToLeft { 
    [self.viewController beginTransitionToDate:date]; 

    self.transitionTableView = [self createUITableView]; 
    self.transitionTableView.frame = CGRectMake(rightToLeft ? self.frame.size.width : (-1 * self.frame.size.width), 0, 
               self.frame.size.width, self.frame.size.height); 
    self.transitionTableView.hidden = NO; 
    [self addSubview:self.transitionTableView]; 

    self.transitionInProgress = YES; 

    [UIView animateWithDuration:0.2f animations:^{ 
     self.transitionTableView.frame = CGRectMake(0,0, self.frame.size.width, self.frame.size.height); 

     self.mainTableView.frame = CGRectMake(rightToLeft ? (-1 * self.frame.size.width) : self.frame.size.width, 0, 
               self.frame.size.width, self.frame.size.height); 
    } completion:^(BOOL completed){ 
     [self.viewController endTransitionDidChange:YES]; 
     [self.mainTableView removeFromSuperview]; 
     self.mainTableView = self.transitionTableView; 

     self.transitionInProgress = NO; 

    }]; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [self.viewController activityCountForTransition:(tableView!=self.mainTableView)]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return [self.viewController cellNumber:indexPath.item forTransition:(tableView!=self.mainTableView)]; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return [self.viewController cellNumber:indexPath.item forTransition:(tableView!=self.mainTableView)].frame.size.height; 
} 

- (void)layoutSubviews { 
    if(!self.transitionInProgress) { 
     [self.mainTableView setFrame:CGRectMake(0,0, self.frame.size.width, self.frame.size.height)]; 
    } 
} 

- (BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { 
    NSLog(@"begin track"); 

    self.locationInView = [touch locationInView:self.superview]; 
    self.fingerTracking = YES; 
    self.fingerMoved = NO; 
    self.transitionTableView = nil; 

    return YES; 
} 

- (CGFloat) calcOffsetForTouch:(UITouch *)touch { 
    CGFloat fingerOffset = [touch locationInView:self.superview].x - self.locationInView.x; 
    return fingerOffset + self.startingOffset; 
} 

- (BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { 
    self.fingerMoved = YES; 
    CGFloat offset = [self calcOffsetForTouch:touch]; 

    //NSLog(@"offset is: %f flarb: %f", offset, fabs(offset)); 

    if(offset < 0 && (!self.transitioningLeft || [OSEUtils isNull:self.transitionTableView])) { 
     [self.viewController beginTransitionToDate:[OSEUtils daysOffset:1 fromDate:self.viewController.selectedDate withTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]]]; 
     [self.transitionTableView removeFromSuperview]; 
     self.transitionTableView = [self createUITableView]; 
     self.transitioningLeft = YES; 
     NSLog(@"going left"); 
     [self addSubview:self.transitionTableView]; 
     [self.transitionTableView reloadData]; 
    } 
    if(offset > 0 && (self.transitioningLeft || [OSEUtils isNull:self.transitionTableView])) { 
     [self.viewController beginTransitionToDate:[OSEUtils daysOffset:-1 fromDate:self.viewController.selectedDate withTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]]]; 
     [self.transitionTableView removeFromSuperview]; 
     self.transitionTableView = [self createUITableView]; 
     self.transitioningLeft = NO; 
     NSLog(@"going right"); 
     [self addSubview:self.transitionTableView]; 
     [self.transitionTableView reloadData]; 
    } 

    CGFloat mult = self.transitioningLeft ? 1 : -1; 

    if(fabs(offset) > (self.frame.size.width/3.0f)) { 
     if(self.transitioningLeft) { 
      offset = -1 * self.frame.size.width; 
     } else { 
      offset = self.frame.size.width; 
     } 

     [UIView animateWithDuration:0.2f animations:^{ 
      self.mainTableView.frame = CGRectMake(offset, 0, self.frame.size.width, self.frame.size.height); 
      self.transitionTableView.frame = CGRectMake(offset + (mult * self.frame.size.width), 0, 
                 self.frame.size.width, self.frame.size.height); 
     } completion:^(BOOL finished) { 
      [self.mainTableView removeFromSuperview]; 

      if(self.transitioningLeft) { 
       [self.viewController.daySelector jumpToNext]; 
      } else { 
       [self.viewController.daySelector jumpToPrevious]; 
      } 

      self.mainTableView = self.transitionTableView; 
      self.transitionTableView = nil; 

      [self.viewController endTransitionDidChange:YES]; 
     }]; 

     return NO; 
    } 

    self.mainTableView.frame = CGRectMake(offset, 0, self.frame.size.width, self.frame.size.height); 
    self.transitionTableView.frame = CGRectMake(offset + (mult * self.frame.size.width), 0, self.frame.size.width, self.frame.size.height); 
    self.transitionTableView.hidden = NO; 

    return YES; 
} 



- (void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { 
    NSLog(@"end tableslide track"); 
    [UIView animateWithDuration:0.2f animations:^{ 
     self.mainTableView.frame = CGRectMake(0,0,self.frame.size.width, self.frame.size.height); 
     self.transitionTableView.frame = CGRectMake(((self.transitioningLeft ? 1 : -1) * self.frame.size.width), 0, self.frame.size.width, self.frame.size.height); 
    } completion:^(BOOL completion){ 
     [self.transitionTableView removeFromSuperview]; 
     self.transitionTableView = nil; 
     [self.viewController endTransitionDidChange:NO]; 
    }]; 



    self.fingerTracking = NO; 
} 


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
    UIView *tableHitTest = [self.mainTableView hitTest:point withEvent:event]; 
    if([tableHitTest isKindOfClass:[OSECellPanelControl class]]) { 
     return tableHitTest; 
    } else { 
     return self; 
    } 
} 

@end 
+0

Я вижу, что вы удаляете представления таблиц из супервизора, но я просто не уверен, что вы их очищаете. При взгляде на ваш код могут быть некоторые способы выполнения, которые позволяют некоторым табличным представлениям стекаться (не очищаться). Причина, по которой что-то замедляется через некоторое время, часто складывается из представлений, поэтому попробуйте прохождение кода, я думаю, вы обнаружите утечку ... – AntonijoDev

+0

Хм - можно определенно увидеть, что представления стеков являются плохими. Я провел некоторое рудиментарное тестирование (проблема триггера, а затем точка останова и po self.subviews), а не просмотр дополнительных табличных представлений. Еще одна подсказка - когда условие проявляется, мои события перетаскивания для ячеек в конечном итоге идут в неправильную ячейку - обычно около 2 от той, которую я перетягиваю .... ??? – Fiid

+0

Это может вас заинтересовать, [Как сделать приложение для списка дел, подобранное жестом, как Clear) (http://www.raywenderlich.com/21842) –

ответ

1

Почему вы создаете новый UITableView, когда пользователь пробирается влево или вправо? Было бы гораздо эффективнее использовать встроенные методы deleteRowsAtIndexPath: и insertRowsAtIndexPath:, чтобы анимировать ряды, вдвигающиеся и выходящие без необходимости скользить и выворачивать все UITableView.

Вы можете посмотреть at this for a reference на анимацию изменений содержимого таблицы, когда вы проведите пальцем по датам.

Я не знаю о вашей текущей настройке, но когда я попробовал эту же вещь с swipeable UITableViewCell, и это супервизор, способный пронестись, у меня были проблемы с получением взаимодействия, которое я хотел. Если это вносит свой вклад в вашу проблему, вы можете посмотреть, где находится пользователь. Если пользователь переместится в пределах определенного смещения от левого и правого края UITableViewCell, тогда он проведет проверку ячейки, что-либо вне этого смещения (в центре ячейки) будет иметь сам UITableView. Затем вы можете активировать удаление и вставку новых строк.

Кроме того, путем повторного запуска нового UITableView каждый раз, вы также заставляете свой UITableViewCell переустанавливаться каждый раз. Используя методы удаления и вставки, вы можете продолжать использовать существующие ячейки через метод dequeueReusableCellWithIdentifier. При каждом повторном экземпляре UITableView ваши ячейки устанавливаются на нуль и отбрасываются, требуя, чтобы новое представление таблицы создало полные новые экземпляры ваших ячеек. Это крайне неэффективно.

+0

Спасибо за ответ .... Я определенно создаю слишком много объектов; однако производительность еще не была проблемой. Ссылка, которую вы отправили, интересна ... Я собираюсь менять каждую ячейку при каждом ударе, хотя бы эта техника все еще работает? Также; могу ли я сделать частичное перетаскивание? – Fiid

+0

вы можете сделать что-то похожее на то, что упомянуто @Rufel, чтобы оживить частичное перетаскивание (используя вариант C). Если вы идете по этому маршруту, я бы привел пример 2 UITableView и просто повторно использовал их. Просмотр таблицы. Слайды вне места и слайд-шоу в виде таблицы. Это обеспечивает функцию частичного перетаскивания. Затем каждый раз, когда вы двигаетесь, вы перемещаете противоположный TableView в нужную сторону и оживляете. Это позволяет продолжить повторное использование уже настроенного UITableViewCells и экономит время, создавая тонну табличных представлений. –

1

Вы получаете глубокое слежение и отслеживаете попадание. Вместо этого используйте API более высокого уровня - распознаватели жестов. С помощью жестов вы можете установить приоритет (этот должен провалиться до того, как это начнется).

Итак, вы хотите, чтобы на экране контейнера появилось несколько настраиваемых жестов (которые больше не должны быть элементом управления). Они терпят неудачу, если начальная точка касания не находится на краю представления (в пределах некоторой границы). Это вызывает общее изменение вида таблицы.

И в ячейках таблицы есть жесты пальцев, каждый из которых требует, чтобы пользовательские команды терпели неудачу. Они запускают логику удаления вашей ячейки.

1

Ваша идея разделяет несколько сходств с тем, как построен экран разблокировки iOS7 и календарь. На экране разблокировки вы можете прокручивать уведомления, перемещать список уведомлений вверх и вниз и прокручивать, чтобы разблокировать. В приложении календаря вы можете прокручивать, чтобы изменить текущий день, или проведите по экрану заголовок, чтобы изменить неделю.Таким образом, я рекомендую посмотреть видеозапись сеанса WWDC 2013 # 217 «Изучение прокрутки на iOS 7», которые объясняют и демонстрируют, как они это сделали, и как реплицировать функциональность.

В принципе, то, что вы могли бы сделать (и что они сделали для экрана разблокировки и календарного экрана): либо (A) гнездо UIScrollViews в UITableView ИЛИ (B) использовать салфетки/панорамирование жест делегата каждая ячейка и (C) гнездо, что UITableView вместе с каждым другим UITableViews, представляющим дни в UIScrollView с включенным пейджинговым управлением.

(A) позволит вам открыть кнопку удаления в ячейках. Вы можете поместить кнопку удаления под UIScrollView, которая находится в ячейке таким образом, чтобы раздвинуть содержимое.

(B) позволит вам отслеживать жест в ячейках, отменить его при необходимости и воспроизвести с помощью содержимого содержимого ячейки, чтобы отобразить кнопку удаления.

(C) позволит красть от одного UITableView к другому довольно легко, и с подкачкой позволит вам получить бесплатный «встанут на место или отскочить назад» анимации PLUS вы можете легко использовать два UITableViews вместо выделения один в день.

Лично я бы с (B) и (C).

0

Оказывается, возникла проблема с моим методом hitTest. Замена [self.mainTableView hitTest ...] с помощью [super hitTest ...] решила мою проблему. Я думаю, что я испортил некоторые координаты, которые заставляли этот метод возвращать нуль, когда он должен был вернуть представление. Я не на 100% уверен, что с ним что-то не так, но теперь он работает лучше.

Смежные вопросы