Кнопка удаления UITableViewCell закрывается

ОБНОВИТЬ:

Благодаря информации от "Evgeny S" я смог определить, что то, что закрывает кнопку удаления, является фоном ячейки. У меня была следующая функция, вызванная в начале инициализации ячейки:

- (void) setupGradientsWithHeight:(int) the_height
{
    CAGradientLayer* gradient = [CAGradientLayer layer];

    gradient.frame  = CGRectMake(self.bounds.origin.x,
                                 self.bounds.origin.y,
                                 self.bounds.size.width,
                                 the_height);

    gradient.colors = [NSArray arrayWithObjects:
                       (id)[UIColor colorWithRed:218.0f/255.0f
                                           green:218.0f/255.0f
                                            blue:220.0f/255.0f
                                           alpha:1.0].CGColor,
                       (id)[UIColor colorWithRed:180.0f/255.0f
                                           green:180.0f/255.0f
                                            blue:184.0f/255.0f
                                           alpha:1.0].CGColor,nil];

    UIView* bgview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];

    [bgview.layer addSublayer:gradient];
    [self setBackgroundView:bgview];
}

Проблема решается НЕ добавлением backgroundview. Однако мне интересно, как это можно решить, сохраняя градиентный фон для каждой ячейки?

Может произойти одно из двух. Когда появляется кнопка удаления, вид фона либо смещается, а затем обратно, либо его размер уменьшается, а затем возвращается. Я попытался возиться с компонентом ширины «self.bounds.size.width» для рамки градиента, но я до сих пор не понимаю, как это может повлиять на вещи, потому что эта функция вызывается только один раз при инициализации ячейки.

ОРИГИНАЛЬНЫЙ ПОСТ:

Я создал приложение в Xcode4 под iOS6 SDK, но после загрузки в новую среду (Xcode5 и iOS7 SDK) столкнулся с проблемой. Обратите внимание, что я устранил все ошибки сборки и предупреждения, появившиеся при переходе.

У меня есть таблица с некоторыми ячейками. После входа в режим редактирования, если щелкнуть красную кнопку-переключатель, чтобы инициировать режим удаления для ячейки, начнется анимация и появится кнопка «Удалить», но ненадолго, а затем внезапно снова скрыта.

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

Я пытался удалить как можно больше своего «пользовательского кода», я удалил функции, которые я переопределил, и попытался вернуть все в исходное состояние, насколько это возможно, но безрезультатно.

В какой-то момент я увидел странное сообщение в выходном журнале: «попытка установить свайп для удаления ячейки, когда она у нас уже есть… это не очень хорошо». По какой-то причине сообщение появляется дольше, и я не могу вспомнить, что я делал в то время.

Любые мысли или рекомендации о том, что может быть причиной этого?

http://www.youtube.com/watch?v=vCAGzSaOwp4


person dtmland    schedule 21.09.2013    source источник
comment
Без подробностей реализации вашей пользовательской ячейки очень сложно угадать проблему...   -  person Tamás Zahola    schedule 22.09.2013
comment
Эта проблема была исправлена ​​в iOS 7.0.3.   -  person smileyborg    schedule 22.10.2013
comment
Я продолжал сталкиваться с этой проблемой в iOS 7.0.4.   -  person Awesomeness    schedule 23.01.2014


Ответы (12)


Это одна из бесчисленных ошибок в iOS 7.

По какой-то причине backgroundView перемещается iOS поверх кнопки удаления. Вы можете обойти это, создав подкласс вашего backgroundView и реализовав функцию setFrame вашего производного представления следующим образом:

- (void)setFrame:(CGRect)frame
{
    if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) {
        // background view covers delete button on iOS 7 !?!
        [super setFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height)];
    } else {
        [super setFrame:frame];
    }
}

В качестве примечания: вы можете избежать необходимости в отдельном подслое, создав подкласс и реализуя layerClass в своем производном представлении:

+ (Class)layerClass
{
    return [CAGradientLayer class];
}
person chris    schedule 27.09.2013
comment
Отличное решение. Это способ предотвратить повторное закрытие кнопки удаления. В iOS6 раньше элемент управления удалением слева менялся с (-) на (I), но теперь строка скользит. Есть ли простой способ сохранить способ iO6 в iOS7, или мне просто нужно смириться с тем, что часть моей строки будет скрыта, когда она скользит. - person Brad Thomas; 03.10.2013
comment
Не могли бы вы объяснить это немного кратко. Как создать подкласс фонового представления в пользовательской ячейке и ячейке по умолчанию. - person Rinku; 29.11.2013

Я исправил это, найдя вид кнопки удаления и переместив его на передний план. Я сделал это в layoutSubviews в подклассе UITableViewCell.

Вот небольшой фрагмент кода, который должен дать вам представление о том, как это сделать:

- (void)layoutSubviews
{
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {

        for (UIView *subview2 in subview.subviews) {

            if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) { // move delete confirmation view

            [subview bringSubviewToFront:subview2];

        }
    }
}
person Si.    schedule 07.10.2013
comment
Я пробовал это, и я знаю, что код работает, но моя кнопка удаления все еще исчезает. - person Inbl; 03.03.2014

Я столкнулся с проблемой, когда мой UITableView находился в режиме редактирования, и после удаления 2-3 строк я получаю сообщение «попытка установить пролистывание для удаления ячейки, когда у нас уже есть одна… это не кажется хорошим», а затем Взаимодействие пользователя со всеми ячейками, кроме одной, отключается.

Я решил эту проблему с помощью

[myTableView setEditing:NO animated:NO];
[myTableView setEditing:YES animated:NO];

после каждого удаления.

Этот обходной путь сработал в моем случае.

person iSaalis    schedule 23.10.2013

Вы можете использовать colorWithPatternImage, но для меня было проще использовать self.layer.content. Например :

cell.layer.contents = (id)[UIImage imageNamed:@"singleRow.png"].CGImage;

Таким образом, изображение не растягивается и не обязательно должно быть точного размера. Таким образом, кнопка удаления не закрывается фоновым изображением ячейки. Между прочим: эти настраиваемые градиентные фоны, кажется, не соответствуют базовому внешнему виду iOS 7. Как вы думаете, это может быть основанием для отказа в одобрении приложения?

person Eran Katsav    schedule 28.09.2013

Я столкнулся с подобной проблемой, и у меня есть работа, которая помещает кнопку «Удалить» поверх содержимого моей ячейки, но анимация немного уродлива. Когда это сделано, кнопка видна и делает правильные вещи.

Создайте собственный подкласс UITableViewCell и добавьте следующий код:

-(void)didTransitionToState:(UITableViewCellStateMask)state
{
    if (state & UITableViewCellStateShowingDeleteConfirmationMask ) {
        [self sendSubviewToBack:self.contentView];

    }

    [super didTransitionToState:state];
}

Будут оценены улучшения этого подхода или других указателей.

person ahalls    schedule 27.09.2013

Очиститель, общее решение

Предполагая, что приложение только для iOS7 с техникой, аналогичной той, что была опубликована Крисом выше, я считаю, что подход здесь: https://stackoverflow.com/a/19416870/535054 станет чище.

При таком подходе вам не нужно создавать подклассы backgroundView, которые могут быть разными для разных ячеек.

Поместите код в ответ, на который я ссылался выше, в корень вашей пользовательской иерархии ячеек таблицы и во все ячейки вашей таблицы (которые наследуются от нее), получите исправление всякий раз, когда они используют backgroundView или свойства selectedBackgroundView.

person idStar    schedule 17.10.2013
comment
Наглядное изображение того, что происходит, доступно в этой статье с описанием исправления: sohail.io/2013/10/21/ - person idStar; 22.10.2013

Я все еще вижу эту проблему после обновления до XCode 5.0.1, но я использовал другой обходной путь, который заключается в использовании логического имени changeTitle, установленного в NO в willBeginEditingRowAtIndexPath и установленного в YES в editingStyleForRowAtIndexPath, если мы не находимся в режиме удаления строк .

Затем я использую эту переменную, чтобы дополнить заголовок кнопки дополнительными пробелами в titleForDeleteConfirmationButtonForRowAtIndexPath.

-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && changeTitle) {
        return @"        Delete";
    }
    return @"Delete";
}

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

person michael839187431    schedule 26.10.2013

Вы можете избежать этой проблемы, установив нужный фон для uitableview и установив cell.backgroudColor = [UIColor clearColor]; и cell.contentView.backgroundColor = [UIColor clearColor];

person Evgeny S    schedule 23.09.2013
comment
Это заставляет меня двигаться в правильном направлении, спасибо. Я обновил свой ответ, включив в него подозрительный код. Есть информация о новых деталях? - person dtmland; 24.09.2013
comment
Я заменил этот код: UIView *view = [[UIView alloc] initWithFrame:self.frame]; view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@cell_background_normal.png]]; self.backgroundView = вид; со следующим кодом: [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@cell_background_normal.png]]]; в настройке моей пользовательской ячейки, и это помогло. - person Evgeny S; 24.09.2013
comment
Я все еще не уверен, как я могу использовать это в своем коде, поскольку у меня есть CAGradientLayer, который нужно добавить. В любом случае, я отказался от градиента, поскольку, когда я удаляю его, кнопка удаления видна, а простой белый вид ячеек в любом случае соответствует шаблону дизайна iOS7. Спасибо за вашу помощь! - person dtmland; 25.09.2013

Если вы запустили проект в iOS 6 SDK и используете раскадровки, проблема может заключаться в ограничениях. Попробуйте удалить все ограничения ячеек и вернуться к предложенным. Это может решить проблемы с кнопкой удаления. У меня были такие проблемы в двух разных проектах, и они были решены описанным способом.

person Vladimir Shutyuk    schedule 27.10.2013

И еще один обходной путь:

- (void) layoutSubviews {
    [super layoutSubviews];

    if ([ [ [UIDevice currentDevice] systemVersion] compare: @"7.0" options: NSNumericSearch] != NSOrderedAscending) {
        if (iOS7 == YES) {
            self.backgroundView.frame = CGRectMake(0, self.backgroundView.frame.origin.y,
                                                   self.backgroundView.frame.size.width, self.backgroundView.frame.size.height);
    }
}
person Igor Kulagin    schedule 25.11.2013

вот лучший способ, просто убедитесь, что вы подкласс UITableviewController для повышения производительности, и добавьте этот код

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {

[super setEditing:editing animated:animated];

CGRect frame = self.tableView.frame;

if(editing){
    [self.tableView setFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height)];
    //other codes to run if needed
}else{
    [self.tableView setFrame:frame];
    //other codes to run if needed
}

}

person Bob Godwin    schedule 04.12.2013

person    schedule
comment
к сожалению, это не сработало для меня, с пользовательскими отформатированными ячейками это сделало текст в моих ячейках невидимым. -рр - person Richie Hyatt; 16.10.2013