Я понимаю, что это старый пост, но у меня была похожая проблема, и я нашел решение, которое хорошо сработало для меня. Я применил методы, используемые в NSCookBook для создания UIAlertViews с блоками. Причина, по которой я пошел на это, заключалась в том, что я хотел использовать встроенные анимации, а не UIView + animateWithDuration: animations: завершение :. Существует большая разница между этими анимациями при переходе на iOS 7.
Вы создаете категорию для UITableView, а в файле реализации вы создаете внутренний закрытый класс, который будет вызывать блок обратно, назначая его в качестве делегата вашего табличного представления. Подвох в том, что до тех пор, пока не будет вызван блок, исходный делегат будет, так сказать, «потерян», поскольку новый делегат является объектом, который будет вызывать блок. Вот почему я поместил уведомление, чтобы отправить сообщение, когда блок был вызван, чтобы переназначить оригинальный UITableViewDelegate. Этот код был проверен и работает на моем конце.
// Header file
@interface UITableView (ScrollDelegateBlock)
-(void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath
atScrollPosition:(UITableViewScrollPosition)scrollPosition
animated:(BOOL)animated
scrollFinished:(void (^)())scrollFinished;
@end
// Implementation file
#import "UITableView+ScrollDelegateBlock.h"
#import <objc/runtime.h>
NSString *const BLOCK_CALLED_NOTIFICATION = @"BlockCalled";
@interface ScrollDelegateWrapper : NSObject <UITableViewDelegate>
@property (copy) void(^scrollFinishedBlock)();
@end
@implementation ScrollDelegateWrapper
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if (self.scrollFinishedBlock) {
[[NSNotificationCenter defaultCenter] postNotificationName:BLOCK_CALLED_NOTIFICATION object:nil];
self.scrollFinishedBlock();
}
}
@end
static const char kScrollDelegateWrapper;
static id<UITableViewDelegate>previousDelegate;
@implementation UITableView (ScrollDelegateBlock)
-(void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath
atScrollPosition:(UITableViewScrollPosition)scrollPosition
animated:(BOOL)animated
scrollFinished:(void (^)())scrollFinished {
previousDelegate = self.delegate;
ScrollDelegateWrapper *scrollDelegateWrapper = [[ScrollDelegateWrapper alloc] init];
scrollDelegateWrapper.scrollFinishedBlock = scrollFinished;
self.delegate = scrollDelegateWrapper;
objc_setAssociatedObject(self, &kScrollDelegateWrapper, scrollDelegateWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(blockCalled:)
name:BLOCK_CALLED_NOTIFICATION
object:nil];
}
/*
* Assigns delegate back to the original delegate
*/
-(void) blockCalled:(NSNotification *)notification {
self.delegate = previousDelegate;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:BLOCK_CALLED_NOTIFICATION
object:nil];
}
@end
Затем вы можете вызвать метод, как и любой другой, с блоком:
[self.tableView scrollToRowAtIndexPath:self.currentPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:YES
scrollFinished:^{
NSLog(@"scrollFinished");
}
];