Una manera sencilla de mostrar la ventana emergente 'Copy' en UITableViewCells como la libreta de direcciones de aplicaciones

StackOverflow https://stackoverflow.com/questions/2487844

Pregunta

¿Hay una manera sencilla de subclases de UITableViewCell para mostrar la ventana emergente 'Copiar' UIMenuController como en la aplicación de libreta de direcciones (ver captura de pantalla), después de la selección se lleva a cabo durante un tiempo?

libreta de direcciones

¿Fue útil?

Solución

El método antes de iOS 5 es conseguir instancia compartida del UIMenuController, establecer el objetivo rect y ver y llamar -setMenuVisible:animated:. Recuerde que para poner en práctica -canPerformAction:withSender: en su respuesta.


El método después de iOS 5 (previamente disponible como característica no documentada) es implementar estos 3 métodos en la fuente de datos (ver https://developer.apple.com/reference/uikit/uitableviewdelegate#1653389 ).

-(void)tableView:(UITableView*)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender;
-(BOOL)tableView:(UITableView*)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender;
-(BOOL)tableView:(UITableView*)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath*)indexPath; 

Otros consejos

En la actualidad existe la interfaz oficial para la visualización de menús celulares UITableView en IOS 5. Ejemplo (de la delegada tabla):

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
    return (action == @selector(copy:));
}

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
    if (action == @selector(copy:)){
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        [[UIPasteboard generalPasteboard] setString:cell.textLabel.text];
    }
}

He intentado modificar el controlador compartido del UIMenuController añadir mi propio elemento de menú, y yo era capaz de añadir y obtener el mensaje canPerformAction para ello, pero volviendo SI no ayudó; Yo no era capaz de hacer aparecer mi elemento de menú personalizado. De mis experimentos, parece que solamente copiar, cortar y pegar son compatibles. [ Editar Ya que esta fue publicada, he aprendido cómo añadir elementos de menú personalizado.]

Tenga en cuenta que esto sólo funciona si se implementan los tres métodos de delegado.

A continuación se muestra la sintaxis para copiar Swift detailTextLabel.

func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool {
    return (tableView.cellForRow(at: indexPath)?.detailTextLabel?.text) != nil
}

func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
    return action == #selector(copy(_:))
}

func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) {
    if action == #selector(copy(_:)) {
        let cell = tableView.cellForRow(at: indexPath)
        let pasteboard = UIPasteboard.general
        pasteboard.string = cell?.detailTextLabel?.text
    }
}

Su subclase UITableViewCell puede tener este aspecto

@interface MenuTableViewCell : UITableViewCell {
}
- (IBAction)copy:(id)sender;
- (void)showMenu;

@end


@implementation MenuTableViewCell

- (BOOL)canBecomeFirstResponder {
    return YES;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(copy:)) {
        return YES;
    }
    return NO;
}
- (IBAction)copy:(id)sender {
}
- (void)showMenu {
    [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
    [self becomeFirstResponder];
    [[UIMenuController sharedMenuController] update];
    [[UIMenuController sharedMenuController] setTargetRect:CGRectZero inView:self];
    [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];

}

@end

Y los métodos de delegado UITableView son como

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    MenuTableViewCell *cell = (MenuTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[MenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    MenuTableViewCell *cell = (MenuTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
    [cell showMenu];
}
 #pragma mark - COPY/PASTE Cell Text via Menu

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
    return (action == @selector(copy:));
}

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
    if (action == @selector(copy:))
    {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard];
        [pasteBoard setString:cell.textLabel.text];
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top