【发布时间】:2013-12-02 18:39:14
【问题描述】:
设置如下:我在表格单元格中有 UIControls,允许从右向左滑动以实现删除功能(如清除)
表格单元格位于 UITableView 中。
TableView 位于另一个 UIControl 中,它允许从左向右或从右向左滑动以更改日期。发生这种情况时,会在主视图的右侧或左侧创建一个新的 TableView,然后从左侧或右侧拉入新的 TableView,直到达到阈值并且动画接管,然后用新的替换旧的。
在某些情况下,所有这些交互实际上都能正常工作。问题是经过几次交互(表格幻灯片似乎有问题)后,滚动表格变得困难/不可能。
这里是 TableViewSlider(包含 TableView 的顶级 UIControl)的代码。任何想法将不胜感激!
@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
【问题讨论】:
-
我可以看到您正在从 superview 中删除表视图,但我不确定您是否将它们全部清除。查看您的代码,可能有一些执行方式允许某些表视图堆叠(未清理)。一段时间后某些事情变得缓慢的原因通常是视图堆叠,所以尝试代码演练我猜你会发现泄漏......
-
嗯 - 肯定会看到堆叠视图不好。我做了一些基本的测试(触发问题,然后是断点和 po self.subviews),但没有看到额外的表格视图。另一个线索 - 当情况出现时,我的单元格拖动事件最终会进入错误的单元格 - 通常比我正在拖动的单元格高出大约 2 个......???
-
你可以发布一些截图吗,很难想象你在这里做什么......
标签: ios objective-c uitableview uicontrol