Я хочу отключить кнопки на листе UIAction и включить их после выполнения определенного условия. Как мне этого добиться? Любые идеи?
iPhone Отключение кнопок UIActionSheet
Ответы (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 в будущей версии ОС.
description
для сравнения классов. Правильный способ - использовать [view isKindOfClass:NSClassFromString(@"UIThreePartButton")];
- person Kornel; 17.12.2009
Есть ли обстоятельство, которое может измениться при открытом листе действий, что может привести к тому, что кнопка станет активной? Если нет, я думаю, что лучший подход - изменить кнопки, отображаемые на листе, в зависимости от вашего состояния.
В противном случае единственный способ справиться с этим - перебрать подпредставления листа, как сказал Крейг, и найти объекты UIButton
. Я бы был осторожен при использовании заголовка кнопки, потому что заголовок может (и должен!) Быть локализован для разных языков. Так что сравнения с названием не так уж и надежны. Поскольку вы не создавали кнопку, вы также не знаете, каким будет tag
или action
для каждой кнопки, так что это тоже немного сложно.
Предположительно, кнопки появятся в массиве subviews
в том порядке, в котором вы указали их для UIActionSheet
, но поскольку это не задокументировано, нет гарантии, что они появятся в этом порядке или что они будут продолжать появляться в этом порядке в будущие выпуски Cocoa Touch SDK. Из-за этого я бы беспокоился в основном о том, чтобы меня отклонили в App Store за использование недокументированных функций.
UIActionSheet не предназначен для настройки. Он должен отображать фактический набор доступных опций. Он не должен изменять доступность кнопки, когда она находится наверху. Просто удалите неиспользуемые кнопки или используйте вместо них настраиваемый вид
Это, наверное, немного поздно. Но, как я понял, нужно создать 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];
ПРИМЕЧАНИЕ. Это отлично работало в предыдущем приложении, которое я создал.
Если вы добавите представление к листу действий, оно не получит никаких событий. Вам нужно просмотреть обзор листа действий.
См. Ниже, как я добавил кнопку с событием ретуши:
- (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];
}
Я столкнулся с аналогичной проблемой, когда у меня был лист действий, который меняется в зависимости от некоторых условий. Я полностью пропустил варианты, которые неприменимы в листе действий, но в некоторых случаях я получаю лист действий только с одним вариантом. Это кажется немного глупым, поскольку я мог активировать этот выбор сразу, не отображая лист вообще.
Однако я также хочу, чтобы пользователи узнали, что нажатие определенной кнопки на экране дает им список вариантов, из которых они могут выбирать. Вот почему я хочу отображать лист действий также в тех случаях, когда у него есть только один выбор. Я думал об отключении неприменимых вариантов вместо того, чтобы убирать их из таблицы, но это тоже было неправильно.
Мой случай связан с наличием значка пользователя на настраиваемой нижней панели, и нажатие на него дает следующие варианты выбора:
- if logged in
- My Profile
- Выйти
- if not logged in
- Log in
Вы можете попробовать [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.