Pytanie w sprawie ios, uitableview, customization, objective-c – Zmiana koloru UITableViewCellDeleteConfirmationControl (przycisk Usuń) w UITableViewCell

4

Obecnie próbuję dostosować przycisk delte w UITableViewCell. Teraz mam coś takiego:

Teraz wszystko, czego potrzebuję, to zmienić kolor tego przycisku, nie chcę zmieniać jego zachowania ani zmieniać go na absolutnie niestandardowy. Jestem pewien, że jest to możliwe, bez tworzenia własnych kontrolek do usuwania wierszy w UITableView.

To mój kod:

- (void)layoutSubviews
{
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {
        if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
            UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
            deleteButtonView.backgroundColor = [UIColor greenColor];
        }
    }
}

Jak mogłem to zrobić?

Z góry dziękuję!

@DrummerB Nie chcę zmieniać żadnych zachowań, tylko kolor. Anatoliy Gatt
@DrummerB Czytam dużo o dostosowaniu tego przycisku, oczywiście moja komórka jest niestandardowa, już podklasuję UITableViewCell, ale nie rozumiem, jak po prostu zmienić kolor, większość czasu ludzie chcą zmienić animację lub cały widok tego przycisku. Anatoliy Gatt
Nie znam żadnego (udokumentowanego) sposobu dostępu do tego przycisku. Jedynym sposobem na dostosowanie go jest ustawienie jego tekstu. Możesz spróbować przejść przez wszystkie podglądy komórki i spróbować znaleźć przycisk (bardzo złe i nieelastyczne rozwiązanie!). Ale nawet jeśli go znajdziesz, UIButton nie ma właściwości odcień. Konieczne byłoby stworzenie przyciemnionego rozciągliwego obrazu tła w wybranym oprogramowaniu do edycji obrazów. DrummerB
Nie sądzę, że jest to możliwe bez niestandardowej podklasy UITableViewCell. Dlaczego jesteś pewien, że to możliwe? DrummerB

Twoja odpowiedź

6   odpowiedzi
1

To jest rozwiązanie:

- (void)layoutSubviews
{
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {
        if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
            UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
            UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Background"]];
            [deleteButtonView addSubview:image];
        }
    }
}
To podejście należy zmodyfikować dla systemu iOS 7. Zobacz moją odpowiedź powyżej, jak równieżstackoverflow.com/a/22350817/1758337 timothykc
1

Odpowiedź zgodna z IOS7 (nie tworzy niestandardowej klasy, ale rozszerza UITableViewCell:

@implementation UITableViewCell (customdelete)
- (void)layoutSubviews
{
    [super layoutSubviews];
    for (UIView *subview in self.subviews) {
        for(UIView *subview2 in subview.subviews){
            if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
                ((UIView*)[subview2.subviews firstObject]).backgroundColor=COLOR_RED;
//YOU FOUND THE VIEW, DO WHATEVER YOU WANT, I JUST RECOLOURED IT
            }
        }
    }
}
@end
nie działa po ios 7.1.2 yatanadam
Takie podejście działa. Może być konieczne dodanie tego do kontrolera UITableViewController, aby wyświetlić niestandardowy kolor ... - (void) tableView: (UITableView *) tableView willBeginEditingRowAtIndexPath: (NSIndexPath *) indexPath {[self.yourTableView reloadData]; } timothykc
nie działa dla mnie Ans
4

W podklasie UITableViewCell:

- (UIView*)recursivelyFindConfirmationButtonInView:(UIView*)view
{
    for(UIView *subview in view.subviews) {
        if([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationButton"]) return subview;
        UIView *recursiveResult = [self recursivelyFindConfirmationButtonInView:subview];
        if(recursiveResult) return recursiveResult;
    }
    return nil;
}

-(void)overrideConfirmationButtonColor
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIView *confirmationButton = [self recursivelyFindConfirmationButtonInView:self];
        if(confirmationButton) confirmationButton.backgroundColor = [UIColor orangeColor];
    });
}

Następnie w UITableViewDelegate:

-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    <#Your cell class#> *cell = (<#Your cell class#>*)[self.tableView cellForRowAtIndexPath:indexPath];
    [cell overrideConfirmationButtonColor];
}

To działa w systemie iOS 7.1.2

Niesamowite! działa dla mnie świetnie. marmor
5

UITableViewCellDeleteConfirmationControl nie jest klasą publiczną i nie można łatwo zmienić jego wyglądu.

Aby to zrobić, uważam, że musiałbyś przeglądać podpowiedzi komórki i zmieniać jej właściwości:

for (UIView *subview in self.subviews) {
    if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl") {
        // Set the background using an image.
    }
}

Oczywiście powinieneś być ostrożny w robieniu tego typu rzeczy, ponieważ jest on dość kruchy. Proponuję zamiast tego przetoczyć własne.

Proponujęprzesłanie raportu o błędzie do Apple, aby poprosić o możliwość łatwiejszej edycji.

Och, w końcu znalazłem rozwiązanie, teraz opublikuję kod) Anatoliy Gatt
Zaktualizowałbym post teraz, abyś mógł zobaczyć, co zrobiłem. Anatoliy Gatt
Ale nie widzę żadnych wyników, nawet gdy próbuję dodać widok podrzędny, taki jak przycisk, nie zrobi tego, ale UILabel pasuje tam idealnie. Anatoliy Gatt
2

Oto jak:

aktywuj przycisk usuwania przy machnięciu

// upewnij się, że masz następujące metody w kontrolerze uitableview

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"You hit the delete button.");
}

ustaw niestandardową etykietę tekstową zamiast usunąć.

-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"Your Label";
}

ustaw kolor niestandardowy dla części przycisku 1 - ostrzeżenie, to technicznie wymaga szturchnięcia prywatnym API Apple. Nie można jednak modyfikować widoku podrzędnego za pomocą publicznego wyszukiwania metod, które jest częścią UIKIT.

Utwórz klasę komendyview (zobacz takżehttps://stackoverflow.com/a/22350817/1758337 )

- (void)layoutSubviews
{
    [super layoutSubviews];
    for (UIView *subview in self.subviews) {
        //iterate through subviews until you find the right one...
        for(UIView *subview2 in subview.subviews){
            if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
                //your color
                ((UIView*)[subview2.subviews firstObject]).backgroundColor=[UIColor blueColor];
            }
        }
    }    
}

Kolejna uwaga: nie ma gwarancji, że to podejście będzie działać w przyszłych aktualizacjach. Uważaj również, aby wspomnieć o prywatnym lub używać goUITableViewCellDeleteConfirmationView klasa może prowadzić do odrzucenia AppStore.

ustaw kolor niestandardowy dla części przycisku 2

z powrotem w kontrolerze użytkownika

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    [YourTableView reloadData];
}

(Alternatywny kolor nie zostanie wywołany, dopóki następnym razem nie zostanie wywołany layoutSubviews na tablecell, więc zapewniamy, że nastąpi to przez ponowne załadowanie wszystkiego.)

2

przykład silyevska jest doskonały ... ale sześć miesięcy później pojawił się iOS 8 i już nie działa on poprawnie.

Teraz musisz poszukać widoku podrzędnego o nazwie „_UITableViewCellActionButton„i ustaw kolor tła tego.

Poniżej znajduje się zmodyfikowana wersja kodu Silyevska, którego użyłem w mojej aplikacji.

Natrochę mojegoUITableView Nie chciałem, aby użytkownik mógł przesuwać, aby usunąć, ale jazrobił chcą, aby coś (ikona kłódki) pojawiło się, gdy się przesuwają.

Aby to zrobić, dodałembReadOnly zmienna do mojej klasy UITableViewCell

@interface NoteTableViewCell : UITableViewCell

. . . 

@property (nonatomic) bool bReadOnly;

-(void)overrideConfirmationButtonColor;

@end

i dodałem kod silyevska do mojego pliku .m:

- (UIView*)recursivelyFindConfirmationButtonInView:(UIView*)view
{
    for(UIView *subview in view.subviews) {

        if([NSStringFromClass([subview class]) rangeOfString:@"UITableViewCellActionButton"].location != NSNotFound)
            return subview;

        UIView *recursiveResult = [self recursivelyFindConfirmationButtonInView:subview];
        if(recursiveResult)
            return recursiveResult;
    }
    return nil;
}

-(void)overrideConfirmationButtonColor
{
    if (!bReadOnly)
        return;

    dispatch_async(dispatch_get_main_queue(), ^{
        UIView *confirmationButton = [self recursivelyFindConfirmationButtonInView:self];
        if(confirmationButton)
        {
            confirmationButton.backgroundColor = [UIColor lightGrayColor];

            UIImageView* imgPadLock = [[UIImageView alloc] initWithFrame:confirmationButton.frame];
            imgPadLock.image = [UIImage imageNamed:@"icnPadlockBlack.png"];
            imgPadLock.contentMode = UIViewContentModeCenter;     //  Don't stretch the UIImage in our UIImageView

            //  Add this new UIImageView in the UIView which contains our Delete button
            UIView* parent = [confirmationButton superview];
            [parent addSubview:imgPadLock];
        }
    });
}

Musiałem także zmienić kod, który wypełniaUITableVieww przeciwnym razie etykieta „Usuń” pojawi się równie dobrze jak ikona kłódki:

-(NSString*)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Note* note = [listOfNotes objectAtIndex:indexPath.row];
    if ( /* Is the user ,is allowed to delete this cell..? */ )
        return @"Delete";

    return @"      ";
}

Nadal jest brzydki i opiera się na założeniach, że to się nie zmieni, gdy pojawi się iOS 9.

Powiązane pytania