#ios #xcode #uibutton
#iOS #xcode #uibutton
Вопрос:
Еще одна проблема, над которой я ломаю голову. Я создал UIButton программно. Его единственная цель — стоять поверх другой кнопки, которая была нажата на полсекунды. Нижняя кнопка — это картинка, верхняя кнопка — корзина для мусора. Вы можете увидеть, что я пытаюсь сделать здесь: у меня есть изображение, и чтобы удалить его, вам нужно нажать на него некоторое время.
if (CGRectContainsPoint(self.capturedImageOneSmall.frame, tapAndHoldPoint)) {
aboutToDeleteImageTrashCan = [[UIButton alloc] init];
aboutToDeleteImageTrashCan.frame = self.capturedImageOneSmall.frame;
[aboutToDeleteImageTrashCan setBackgroundImage:[UIImage imageNamed:@"LogoTrashcan"] forState:UIControlStateNormal];
[aboutToDeleteImageTrashCan addTarget:self action:@selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside];
aboutToDeleteImageTrashCan.tag = 1;
[self.scrollView addSubview:aboutToDeleteImageTrashCan];
Когда я вызываю свой метод для удаления обеих кнопок, исчезает только изображение, корзина остается и даже все еще доступна для нажатия.
- (void)deleteImage:(UIButton *)sender
{
if (aboutToDeleteImageTrashCan.tag == 1) {
[self.capturedImageOneSmall removeFromSuperview]; //this works!
self.capturedImageOneSmall = nil;
capturedImageOneData = nil;
}
[aboutToDeleteImageTrashCan performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:NO]; //this doesn't!
aboutToDeleteImageTrashCan = nil;
У вас, ребята, есть какие-нибудь идеи?
Комментарии:
1. Вероятно, он устанавливает его равным нулю перед удалением из super view, но, чтобы быть уверенным, попробуйте это без performSelector, чтобы увидеть, исчезнет ли он.
2. Спасибо за ваш ответ @afonso. Но я перепробовал все, как [aboutToDeleteImageTrashCan removeFromSuperview], просто установив его равным нулю, пытаясь использовать aboutToDeleteImageTrashCan.hidden = ДА, … Он просто остается там.
3. Извините, я не могу больше помочь. Но, еще одна вещь, ваш aboutToDeleteImageTrashCan — это переменная экземпляра, верно? Почему и как вы вызываете это напрямую? Разве это не должно быть self.aboutToDeleteImageTrashCan? Или, в методе удаления, отправитель?
4. Да, извините за это. Изменил это сейчас. Все еще нет прогресса.
Ответ №1:
Можете ли вы показать вывод этого оператора, когда вы размещаете его прямо перед строкой, содержащей вызов ‘performSelectorOnMainThread’:
NSLog(aboutToDeleteImageTrashCan: %@, aboutToDeleteImageTrashCan);
Комментарии:
1. Извините за поздний ответ, это чемпионат мира, и Бельгия выиграла вчера 🙂 На выходе написано: 2014-07-02 11:11:40,523 Колеса [5022:60b] self.aboutToDeleteImageTrashCan, <UIButton: 0x14575090; frame = (3091 50; 160 120); альфа = 0,5; непрозрачный = НЕТ; тег = 1; слой = <CALayer: 0x1459bfe0>>
2. Хорошо, итак, глядя на этот фрейм, кажется, что ваша метка даже не видна для начала, поэтому удаление также будет незаметным. Это также означает, что вы не отправляете removeFromSuperview объекту, который вы видите на экране (поскольку x-origin фрейма равен 3091, что, скорее всего, за кадром). Пожалуйста, покажите код, в котором присваивается ‘aboutToDeleteImageTrashCan’ (т. Е. «aboutToDeleteImageTrashCan = [UIView alloc] init];» или что-то в этом роде).
3. В том-то и дело, что мое приложение имеет 5000 пикселей по горизонтали
scrollView
. Я вижу кнопку, она там, где она должна быть, в 3091x. Вы можете увидеть распределение кнопки в моем главном вопросе. Спасибо4. Где abouttodeleteimagetrash может быть объявлен? Вы уверены, что выделенный объект — это тот же объект, который получает сообщение removeFromSuperview? Можете ли вы распечатать их оба с помощью NSLog, чтобы проверить, совпадают ли их адреса памяти?
5. Он объявлен в моем файле .h:
@property (strong, nonatomic) IBOutlet UIButton *aboutToDeleteImageTrashCan;
Я думаю, только один объект.
Ответ №2:
Да, видите, что у них разные адреса памяти? (0x15eb5e80 и 0x15eb7940). Я подозреваю, что у вас есть один объект, поступающий из interface builder, а затем вы создаете другой ярлык и присваиваете его aboutToDeleteImageTrashCan. Таким образом, у вас может быть две метки в одном и том же месте, поэтому удаление одной из них будет незаметным, так как под ней находится другая. И поскольку у вас больше нет (прямой) ссылки на ярлык из interface-builder, трудно заставить его исчезнуть.
Поэтому, если вы не укажете строку alloc / init, я подозреваю, что ваша проблема будет решена.
Ответ №3:
Почему вы вызываете performSelectorOnMainThread:с объектом:waitUntilDone:? Это не имеет смысла (по крайней мере, без дополнительного контекста). В любом случае, вы указываете NO для waituntildone, поэтому это означает, что эта работа запланирована к выполнению в конце цикла выполнения, к этому времени у вас уже есть abouttodeleteimagetrash может быть равен нулю.
Если по какой-то причине вы действительно хотите, чтобы это removeFromSuperview произошло в конце цикла выполнения, просто отправьте его в очередь выполнения:
dispatch_async(dispatch_get_main_queue(), ^{
[aboutToDeleteImageTrashCan removeFromSuperview];
});
Комментарии:
1. Спасибо за ваше время. Я начал с простого removeFromSuperview, пробовал всевозможные вещи, чтобы заставить кнопку исчезнуть, но безуспешно. Параметр performSelectorOnMainThread:withObject:waitUntilDone: был моей последней попыткой. Кстати, ваш ответ также не удаляет его.