2009-07-22 7 views

Répondre

-2

boutons thees sont subviews de UIActionSheet et leur classe est UIThreePartButton

Vous pouvez les obtenir et faire tout ce que vous voulez:

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

Je vous suggère de ne pas utiliser cette méthode comme ceux-ci sont privés du SDK. Apple pourrait rejeter votre application. La meilleure alternative serait de ne pas montrer ces boutons du tout au lieu de les désactiver – lostInTransit

+0

Il n'y a pas de méthodes privées dans ce code)) Only public :) Parfois, j'utilise des méthodes privées dans mes applications. Je les utilise une fois-deux fois dans l'application et Apple n'a pas rejeté ces applications – oxigen

+5

Il ne s'agit pas seulement d'être rejeté par Apple, l'utilisation de l'API privée montre un manque de respect pour vos clients.Les API privées sont privées car Apple les verrouille toujours, donc si et quand elles changent, votre application va se casser. View traversal comme vous avez décrit ci-dessus a causé un certain nombre d'applications à casser sous 3.0, si bien que Apple a appelé cela dans les notes de publication et a dit de ne pas le faire. –

0

Ceci est probablement un peu en retard. Mais, la façon dont j'ai compris est de créer UIButton (s) et les ajouter à la sous-vue UIActionSheet. Assurez-vous que ces boutons sont placés sur le dessus et recouvrez complètement le (s) bouton (s) UIActionSheet par défaut à remplacer. Lorsque UIButton est placé sur le bouton UIActionSheet par défaut, son UIResponder est prioritaire sur le bouton UIActionSheet UIResponder. Donc, ce faisant, vous pouvez désactiver et activer ces boutons comme vous le souhaitez n'importe où dans votre logique UIViewController. Cela peut être une alternative à l'accès aux méthodes privées au SDK (comme ci-dessus - UIThreePartButton) et Apple pourrait rejeter votre application. Je crois que cela suit les lignes directrices d'Apple.

à savoir

// 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

Sur la base d'un certain nombre de fil, j'ai agrégés une réponse dans une catégorie sur UIActionSheet, l'ajout d'un setButton: méthode toState comme suit. Hope it helps:

@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

Grande solution, très simple, facile à utiliser et fait de la bonne manière d'ingénierie. +1 – Darrarski

2

version légèrement améliorée de Reuven [hélas je ne peux pas ajouter un commentaire à sa parce que je n'ai pas la « réputation » encore ...].

@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 

Le précédent respondsToSelector: vérification était étrangère, parce que nous contrôlons déjà UIButton (qui est une sous-classe UIControl, qui tout le soutien setEnabled] Conformément aux NSArrays d'Apple, j'ai aussi changé en « atIndex » et NSUInteger. L'approche globale semble fonctionner correctement, mais notez que l'ordre des sous-vues de bouton correspond exactement à l'ordre des index des boutons lorsque la feuille d'action a été construite, ce qui n'est pas strictement documenté n'importe où AFAIK

+0

BTW, selon [this] (http://stackoverflow.com/questions/5262428/uiactionsheet-buttonindex-values-faulty-when-using-more-than-6-custom-buttons), les index des boutons * * Ne faites pas de haywire quand vous avez trop d'éléments dans votre feuille d'action. Donc, cela va bousiller cette approche (pour désactiver) si vous avez beaucoup. – tiritea

1

Les solutions fournies ne fonctionnent pas k sur iOS 8. Si quelqu'un n'utilise pas le UIAlertController pour cela (ce qui est la méthode recommandée par Apple), voici comment j'ai modifié la réponse de @ Reuven pour iOS 8:

(la deuxième phase est basée sur this donc répondre)

- (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 version 3.0:

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) 
Questions connexes