IPhone UITableView - кнопка удаления
Я использую функцию "прокрутка для удаления" UITableView
.
Проблема заключается в том, что я использую настраиваемый UITableViewCell
, который создается на основе каждого элемента в
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Мне нужно изменить положение кнопки удаления (просто переместите его вокруг 10 пикселей влево), как бы я это сделал?
Вот мой существующий код для создания ячейки:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"cellForRowAtIndexPath");
#if USE_CUSTOM_DRAWING
const NSInteger TOP_LABEL_TAG = 1001;
const NSInteger BOTTOM_LABEL_TAG = 1002;
UILabel *topLabel;
UILabel *bottomLabel;
#endif
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//
// Create the cell.
//
cell =
[[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier]
autorelease];
#if USE_CUSTOM_DRAWING
const CGFloat LABEL_HEIGHT = 20;
UIImage *image = [UIImage imageNamed:@"trans_clock.png"];
//
// Create the label for the top row of text
//
topLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
image.size.width + 2.0 * cell.indentationWidth,
0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT),
aTableView.bounds.size.width -
image.size.width - 4.0 * cell.indentationWidth
,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:topLabel];
//
// Configure the properties for the text that are the same on every row
//
topLabel.tag = TOP_LABEL_TAG;
topLabel.backgroundColor = [UIColor clearColor];
topLabel.textColor = fontColor;
topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
//
// Create the label for the top row of text
//
bottomLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
image.size.width + 2.0 * cell.indentationWidth,
0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT) + LABEL_HEIGHT,
aTableView.bounds.size.width -
image.size.width - 4.0 * cell.indentationWidth
,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:bottomLabel];
//
// Configure the properties for the text that are the same on every row
//
bottomLabel.tag = BOTTOM_LABEL_TAG;
bottomLabel.backgroundColor = [UIColor clearColor];
bottomLabel.textColor = fontColor;
bottomLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
bottomLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];
//
// Create a background image view.
//
cell.backgroundView =
[[[UIImageView alloc] init] autorelease];
cell.selectedBackgroundView =
[[[UIImageView alloc] init] autorelease];
#endif
}
#if USE_CUSTOM_DRAWING
else
{
topLabel = (UILabel *)[cell viewWithTag:TOP_LABEL_TAG];
bottomLabel = (UILabel *)[cell viewWithTag:BOTTOM_LABEL_TAG];
}
topLabel.text = @"Example Text";
topLabel.textColor = fontColor;
bottomLabel.text = @"More Example Text";
bottomLabel.textColor = fontColor;
//
// Set the background and selected background images for the text.
// Since we will round the corners at the top and bottom of sections, we
// need to conditionally choose the images based on the row index and the
// number of rows in the section.
//
UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [aTableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 && row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:@"topAndBottomRow.png"];
selectionBackground = [UIImage imageNamed:@"topAndBottomRowSelected.png"];
}
else if (row == 0)
{
rowBackground = [UIImage imageNamed:@"topRow.png"];
selectionBackground = [UIImage imageNamed:@"topRowSelected.png"];
}
else if (row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:@"bottomRow.png"];
selectionBackground = [UIImage imageNamed:@"bottomRowSelected.png"];
}
else
{
rowBackground = [UIImage imageNamed:@"middleRow.png"];
selectionBackground = [UIImage imageNamed:@"middleRowSelected.png"];
}
((UIImageView *)cell.backgroundView).image = rowBackground;
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
cell.imageView.image = [UIImage imageNamed:@"Example_Image.png"];
#else
cell.text = @"Example";
#endif
return cell;
}
Ответы
Ответ 1
Код Iwat для меня не работает. Но это работает.
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
subview.hidden = YES;
subview.alpha = 0.0;
}
}
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state {
[super didTransitionToState:state];
if (state == UITableViewCellStateShowingDeleteConfirmationMask || state == UITableViewCellStateDefaultMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
CGRect f = deleteButtonView.frame;
f.origin.x -= 20;
deleteButtonView.frame = f;
subview.hidden = NO;
[UIView beginAnimations:@"anim" context:nil];
subview.alpha = 1.0;
[UIView commitAnimations];
}
}
}
}
Ответ 2
Для меня лучшим способом решить это было переопределение -(void)layoutSubviews
в MyCell:UITableViewCell
Здесь вы можете видеть не только пользовательскую позицию кнопки "Удалить", но и перемещать элементы "Изменить" и "Изменить порядок" для режима Изменить
- (void)layoutSubviews
{
[super layoutSubviews];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0f];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 200;
subview.frame = newFrame;
}
else if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellEditControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 100;
subview.frame = newFrame;
}
else if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellReorderControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 200;
subview.frame = newFrame;
}
}
[UIView commitAnimations];
}
Ответ 3
Я не смог изменить фактический вид кнопки удаления, но вы можете изменить текст. Возможно, вы можете использовать это, чтобы получить эффект, который вы ищете?
Проверьте следующий член протокола UITableViewDelegate
:
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
Кроме того, вы можете обнаружить, когда кнопка удаления отображается подклассом UITableViewCell
и переопределяет следующее:
- (void)willTransitionToState:(UITableViewCellStateMask)state
- (void)didTransitionToState:(UITableViewCellStateMask)state
Для любой из них маска состояния будет UITableViewCellStateShowingDeleteConfirmationMask
, когда отображается кнопка удаления.
Надеемся, что эти подсказки укажут вам в правильном направлении.
Ответ 4
Я использую решение, которое на первый взгляд выглядит вроде хаки, но делает трюк и не полагается на недокументированный apis:
/**
* Transition to state
*/
-(void)willTransitionToState:(UITableViewCellStateMask)state {
if(state & UITableViewCellStateShowingDeleteConfirmationMask)
_deleting = YES;
else if(!(state & UITableViewCellStateShowingDeleteConfirmationMask))
_deleting = NO;
[super willTransitionToState:state];
}
/**
* Reset cell transformations
*/
-(void)resetCellTransform {
self.transform = CGAffineTransformIdentity;
_background.transform = CGAffineTransformIdentity;
_content.transform = CGAffineTransformIdentity;
}
/**
* Move cell around if we are currently in delete mode
*/
-(void)updateWithCurrentState {
if(_deleting) {
float x = -20;
float y = 0;
self.transform = CGAffineTransformMakeTranslation(x, y);
_background.transform = CGAffineTransformMakeTranslation(-x, -y);
_content.transform = CGAffineTransformMakeTranslation(-x, -y);
}
}
-(void)setFrame:(CGRect)frame {
[self resetCellTransform];
[super setFrame:frame];
[self updateWithCurrentState];
}
-(void)layoutSubviews {
[self resetCellTransform];
[super layoutSubviews];
[self updateWithCurrentState];
}
В основном это сдвигает положение ячейки и корректирует видимые части.
WillTransitionToState просто устанавливает переменную экземпляра, указывающую, находится ли ячейка в режиме удаления. Переопределение setFrame было необходимо для поддержки поворота телефона на пейзаж и наоборот.
Где _background - фоновое представление моей ячейки, а _content - это представление, добавленное в contentView ячейки, содержащее все метки и т.д.
Ответ 5
Я не знаю, как "переместить кнопку удаления 10px влево". Тем не менее, вы можете анимировать пользовательское содержимое ячейки таблицы вокруг статической позиции кнопки неподвижного удаления, прослушивая сообщение willTransitionToState:
из подкласса UITableViewCell
, см. здесь.
Чтобы процитировать документы:
Подклассы UITableViewCell могут реализовать этот метод для анимации дополнительные изменения в ячейке, когда она меняется состояние. UITableViewCell вызывает этот метод всякий раз, когда ячейка переходы между состояниями, такие как из нормального состояния (по умолчанию) в режим редактирования. Пользовательская ячейка может установить и позиционировать любые новые появляются с новым состоянием. Клетка затем получает сообщение layoutSubviews (UIView), в котором он может располагаться эти новые взгляды в их окончательном местоположения для нового состояния. Подклассы должны всегда называть супер, когда переопределяя этот метод.
То, что вы ищете, это значение UITableViewCellStateShowingDeleteConfirmationMask
. Это один из тех случаев, когда создание подкласса UITableViewCell может быть лучше, поэтому из контроллера вы просто создаете экземпляр своей пользовательской ячейки. Затем ячейка может просто отрегулировать себя как animateLeft
и animateRight
и обрабатывать внутренние действия по настройке собственных подзонов.
Ответ 6
Я не знаю окончательного решения, но, насколько я пробовал, может оказаться полезным следующий код.
// subclass UITableViewCell
- (void)willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableCellStateShowingDeleteConfirmationMask)
{
for (UIView *subview in self.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"])
{
subview.hidden = YES;
subview.alpha = 0;
}
}
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableCellStateShowingDeleteConfirmationMask)
{
for (UIView *subview in self.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"])
{
subview.frame = CGRectMake(subview.frame.origin.x - 10, subview.frame.origin.y, subview.frame.size.width, subview.frame.size.height);
subview.hidden = NO;
[UIView beginAnimations:@"anim" context:nil];
subview.alpha = 1;
[UIView commitAnimations];
}
}
}
}