2009-07-22 24 views

Respuesta

-2

Thees botones son subvistas de UIActionSheet y su clase es UIThreePartButton

Puede obtener ellos y hacer todo lo que desea:

UIActionSheet *a = [[UIActionSheet alloc]initWithTitle:@"" delegate: nil cancelButtonTitle: @"c" destructiveButtonTitle: @"d" otherButtonTitles: @"ot", nil]; 
    [a showInView: window]; 

    for(UIView *v in [a subviews]) 
    { 
     if([[v description] hasPrefix: @"<UIThreePartButton"]) 
     { 
      v.hidden = YES; //hide 
      //((UIButton*)v).enabled = NO; // disable 

     } 
    } 
+3

yo sugeriría que no utiliza este método ya que estos son privados para el SDK. Apple podría rechazar tu aplicación. La mejor alternativa sería no mostrar estos botones en lugar de deshabilitarlos – lostInTransit

+0

No hay métodos privados en este código)) Solo público :) A veces uso métodos privados en mis aplicaciones. Los uso una vez dos veces en la aplicación y Apple no rechazó estas aplicaciones – oxigen

+5

No solo es rechazado por Apple, el uso de API privada muestra una falta de respeto por sus clientes.Las API privadas son privadas porque Apple las sigue bloqueando, por lo que si cambian, su aplicación se romperá. El recorrido de la vista como describió anteriormente hizo que una serie de aplicaciones rompieran por debajo de 3.0, tanto que Apple lo mencionó en las notas de la versión y dijo que no hiciera esto. –

0

Esto es probablemente un poco tarde. Pero, la forma en que descubrí es crear UIButton (s) y agregarlos a la subvista UIActionSheet. Asegúrese de que estos botones estén en la parte superior y cubra por completo los botones UIActionSheet predeterminados para reemplazar. Cuando el UIButton se coloca sobre el botón predeterminado UIActionSheet, su UIResponder tiene prioridad sobre UIActionSheet button UIResponder. Entonces, al hacerlo, puede deshabilitar y habilitar esos botones como quiera en cualquier parte de su lógica UIViewController. Esta puede ser una alternativa para acceder a los métodos privados del SDK (como anteriormente, UIThreePartButton) y Apple podría rechazar su aplicación. Creo que esto sigue las pautas de Apple.

es decir

// Instantiate once 
if (self.actionSheet==nil) { 
    UIActionSheet *as = [[UIActionSheet alloc] 
         initWithTitle:@"" 
         delegate:self 
         cancelButtonTitle:@"Cancel" 
         destructiveButtonTitle:@"Load Data" 
         otherButtonTitles:@"Update Data",nil]; 

    //[actionSheet showInView:self.view]; 
    self.loadUIButton.frame = CGRectMake(24.0f,25.0f,275.f,46.0f); 
    [as addSubview: self.loadUIButton]; 
    self.updateUIButton.frame = CGRectMake(24.0f,78.0f,275.f,46.0f); 
    [as addSubview: self.updateUIButton]; 
    //[actionSheet addSubview: self.cancelUIButton]; 
    //[as showFromToolbar: self.navigationController.toolbar]; 
    self.actionSheet = as; 
    [as release]; 
} 
[self.actionSheet showFromToolbar: self.navigationController.toolbar]; 
17

Basado en un número de hilo, he agregarse una respuesta en una categoría en UIActionSheet, la adición de un botón SET: método tostate como sigue. creo que sirve:

@interface UIActionSheet(ButtonState) 
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enbaled; 
@end 

@implementation UIActionSheet(ButtonState) 
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enabled { 
    for (UIView* view in self.subviews) 
    { 
     if ([view isKindOfClass:[UIButton class]]) 
     { 
      if (buttonIndex == 0) { 
       if ([view respondsToSelector:@selector(setEnabled:)]) 
       { 
        UIButton* button = (UIButton*)view; 
        button.enabled = enabled; 
       } 
      } 
      buttonIndex--; 
     } 
    } 
} 
@end 
+0

Gran solución, muy simple, fácil de usar y hecho de la manera correcta. +1 – Darrarski

2

versión ligeramente mejorada de Reuven [por desgracia no puedo dejar un comentario a su porque no tengo la 'reputación' aún ...].

@interface UIActionSheet (ButtonEnabled) 
- (void)setButtonAtIndex:(NSUInteger)index Enabled:(BOOL)enabled; 
@end 

@implementation UIActionSheet (ButtonEnabled) 
- (void)setButtonAtIndex:(NSUInteger)index Enabled:(BOOL)enabled 
{ 
    for (UIView* view in self.subviews) { 
     if ([view isKindOfClass:[UIButton class]]) { 
      if (index-- == 0) { 
       [(UIButton*)view setEnabled:enabled]; 
       break; 
      } 
     } 
    } 
} 
@end 

El respondsToSelector anterior: cheque era extraña, porque ya estamos comprobando para UIButton (que es una subclase uicontrol, que todo el apoyo setEnabled] De acuerdo con NSArrays de Apple, también ha cambiado a "atIndex" y NSUInteger. , pero eso es cosmético en su mayoría

El enfoque general parece funcionar bien, pero tenga en cuenta que supone que el orden de las subvistas de los botones coincide exactamente con el orden de los índices del botón cuando se construyó la hoja de acción, que no es estrictamente documentado en cualquier lugar AFAIK.

+0

Por cierto, de acuerdo con [este] (http://stackoverflow.com/questions/5262428/uiactionsheet-buttonindex-values-faulty-when-using-more-6-custom-buttons), el botón indexa * no te vuelvas loco cuando tienes demasiados elementos en tu hoja de acción. Entonces eso arruinará este enfoque (para deshabilitar) si tiene que hacer muchos. – tiritea

1

Las soluciones proporcionadas no funcionan k en iOS 8. En caso de que alguien no esté usando el UIAlertController para esto (que es la manera recomendada por Apple), así es como modifiqué la respuesta de @ Reuven para trabajar con iOS 8:

(la segunda fase está basada en this así responder)

- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enabled { 

    SEL selector = NSSelectorFromString(@"_alertController"); 

    //iOS 8 
    if ([self respondsToSelector:selector]) { 

     UIAlertController *alertController = [self valueForKey:@"_alertController"]; 

     if ([alertController isKindOfClass:[UIAlertController class]]){ 

      UIAlertAction *action = alertController.actions[buttonIndex]; 

      [action setEnabled:enabled]; 

     } 

    //iOS 7 
    }else{ 

     for (UIView* view in self.subviews){ 

      if ([view isMemberOfClass:NSClassFromString(@"UIAlertButton")]) { 

       if (buttonIndex == 0) { 

        if ([view respondsToSelector:@selector(setEnabled:)]){ 

         UIButton* button = (UIButton*)view; 

         button.enabled = enabled; 

        } 

       } 

       buttonIndex--; 

      } 

     } 

    } 

} 
1

Swift 3.0 versión:

let actionSheet = UIAlertController(title:nil, message:nil, preferredStyle:UIAlertControllerStyle.actionSheet) 


actionSheet.addAction(UIAlertAction(title:"Modify", style:UIAlertActionStyle.default, handler:{ action in 
    // Do your thing here 
})) 

let disabledDelete = UIAlertAction(title:"Cannot delete this item", style:UIAlertActionStyle.destructive, handler:nil) 
disabledDelete.isEnabled = false 
actionSheet.addAction(disabledDelete) 

actionSheet.addAction(UIAlertAction(title:"Cancel", style:UIAlertActionStyle.cancel, handler:nil)) 

self.present(actionSheet, animated:true, completion:nil) 
Cuestiones relacionadas