iPhone Отключение кнопок UIActionSheet

Я хочу отключить кнопки на листе UIAction и включить их после выполнения определенного условия. Как мне этого добиться? Любые идеи?


person shrads    schedule 13.04.2009    source источник
comment
Я знаю, что трудно изменить чье-то мнение, но ты уверен, что действительно хочешь сделать это таким образом? Возможно, вместо этого вы хотите просто показать лист действий без отключенных кнопок, и когда какое-то условие истинно, вместо этого покажите другое (при необходимости скрыв другое)   -  person Ed Marty    schedule 13.04.2009
comment
См. Альтернативный ответ, который я собираю из многочисленных источников, в этом ответе SO   -  person Reuven    schedule 21.02.2012


Ответы (7)


Я обнаружил, что ответ Крейга не сработал для меня (в ОС 3.1). Немного покопавшись, я обнаружил, что подпредставления UIActionSheet на самом деле относятся к недокументированному классу UIThreePartButton

Во всяком случае, у меня это работает (реализовано как часть метода UIActionSheetDelegete)

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet  // before animation and showing view
{
    for (UIView* view in [actionSheet subviews])
    {
        if ([[[view class] description] isEqualToString:@"UIThreePartButton"])
        {
            if ([view respondsToSelector:@selector(title)])
            {
                NSString* title = [view performSelector:@selector(title)];
                if ([title isEqualToString:@"Button 1"] && [view respondsToSelector:@selector(setEnabled:)])
                {
                    [view performSelector:@selector(setEnabled:) withObject:NO];
                }
            }
        }
    }
}

Надеюсь, что это поможет кому-то другому, хотя я бы повторил вопрос Эда Марти о том, не лучше ли вам просто вообще исключить эти кнопки из списка действий, вместо того, чтобы делать это. Как всегда при использовании недокументированных функций, существует риск отклонения магазина приложений, хотя этот код написан так, чтобы корректно выйти из строя, если Apple снова изменит API в будущей версии ОС.

person cidered    schedule 14.12.2009
comment
Никогда не используйте description для сравнения классов. Правильный способ - использовать [view isKindOfClass:NSClassFromString(@"UIThreePartButton")]; - person Kornel; 17.12.2009
comment
Использование недокументированных классов, подобных этому, - верный способ получить отказ при отправке в App Store. - person PeyloW; 29.12.2009

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

В противном случае единственный способ справиться с этим - перебрать подпредставления листа, как сказал Крейг, и найти объекты UIButton. Я бы был осторожен при использовании заголовка кнопки, потому что заголовок может (и должен!) Быть локализован для разных языков. Так что сравнения с названием не так уж и надежны. Поскольку вы не создавали кнопку, вы также не знаете, каким будет tag или action для каждой кнопки, так что это тоже немного сложно.

Предположительно, кнопки появятся в массиве subviews в том порядке, в котором вы указали их для UIActionSheet, но поскольку это не задокументировано, нет гарантии, что они появятся в этом порядке или что они будут продолжать появляться в этом порядке в будущие выпуски Cocoa Touch SDK. Из-за этого я бы беспокоился в основном о том, чтобы меня отклонили в App Store за использование недокументированных функций.

person Alex    schedule 13.04.2009
comment
Вы не получите отказа от этой процедуры в App Store. Всегда есть шанс, что Apple изменит порядок подпросмотров, и ваше приложение может начать вести себя странно, но это не тот тип «недокументированной функциональности», который они запретили бы в магазине. - person Craig Otis; 14.04.2009
comment
Правда, это не то же самое, что частный API, но он частный в том смысле, что основан на эксперименте, а не на документации. Я бы очень не рекомендовал это делать. Я не уверен, что Apple не откажется от него - соглашение дает им полную свободу отклонять приложения по любой причине. - person Alex; 14.04.2009

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

person vaddieg    schedule 14.12.2009

Это, наверное, немного поздно. Но, как я понял, нужно создать UIButton (ы) и добавить их в подпредставление UIActionSheet. Убедитесь, что эти кнопки расположены сверху и полностью закрывают заменяемые кнопки UIActionSheet по умолчанию. Когда UIButton помещается над кнопкой UIActionSheet по умолчанию, его UIResponder имеет приоритет над кнопкой UIActionSheet UIResponder. Таким образом, вы можете отключать и включать эти кнопки в любом месте вашей логики UIViewController. Это может быть альтернативой доступу к частным методам SDK (как указано выше - UIThreePartButton), и Apple может отклонить ваше приложение. Я считаю, что это соответствует рекомендациям Apple.

т.е. настройте кнопки UIButtons для включения / отключения при возникновении определенных условий.

// Instantiate once within a method
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];

ПРИМЕЧАНИЕ. Это отлично работало в предыдущем приложении, которое я создал.

person mrapplehead    schedule 18.05.2011

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

См. Ниже, как я добавил кнопку с событием ретуши:

- (void)didPresentActionSheet:(UIActionSheet *)actionSheet{
CGRect rect = CGRectMake(0,0, 320, 480);
UIButton* anImage = [[UIButton alloc] init];
[anImage setTitle:@"GHello worl" forState:UIControlStateNormal];
[anImage setTitle:@"GHello worl dfasd" forState:UIControlStateHighlighted];
[anImage setTitle:@"GHello worl selected" forState:UIControlStateSelected];
//[anImage setBackgroundImage:[UIImage imageNamed:@"photo.png"] forState:UIControlStateNormal];
[anImage addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
rect = CGRectMake(0,0, 320, 220);
anImage.frame =rect;


[actionSheet.superview addSubview:anImage];



[anImage release];

}

person Shaikh Sonny Aman    schedule 06.07.2009

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

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

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

  • if logged in
    • My Profile
    • Выйти
  • if not logged in
    • Log in
person Mayoneez    schedule 18.10.2010

Вы можете попробовать [actionSheet valueForKey: @ "_ buttons"] в своем UIActionSheetDelegate следующим образом:

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
    for (UIButton *btn in [actionSheet valueForKey:@"_buttons"])
    {
        [btn setBackgroundImage:[UIImage imageNamed:@"btnActionSheetUp.png"]     forState:UIControlStateNormal];
        [btn setBackgroundImage:[UIImage imageNamed:@"btnActionSheetDown.png"] forState:UIControlStateHighlighted];
    }
}

Надеюсь, это не изменится в будущих выпусках sdk.

person richy    schedule 01.12.2011
comment
Это будет отклонено? В случае, если у вас много кнопок, UIActionSheet собирается установить прокрутку с кнопками, и тогда это не работает, вы знаете, как решить эту проблему? Спасибо! - person Oscar; 14.12.2011