Skip to content

Instantly share code, notes, and snippets.

@nguyenhuy
Last active August 29, 2015 14:04
Show Gist options
  • Save nguyenhuy/a11d15c11200477b05a6 to your computer and use it in GitHub Desktop.
Save nguyenhuy/a11d15c11200477b05a6 to your computer and use it in GitHub Desktop.
Showing UIActivityIndicatorView on UISearchBar, depending on state of a request operation or session task
//
// UISearchBar+AFNetworking.h
//
// Created by Huy Nguyen on 7/15/14.
// Copyright (c) 2014 Huy Nguyen. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Availability.h>
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h>
@class AFURLConnectionOperation;
/**
This category adds methods to the UIKit framework's `UISearchBar` class. The methods in this category provide support for automatically adding an UIActivityIndicatorView, starting and stopping its animation depending on the loading state of a request operation or session task.
The implementation of this category is greatly inspired by UIActivityIndicatorView+AFNetworking.
*/
@interface UISearchBar (AFNetworking)
///----------------------------------
/// @name Animating for Session Tasks
///----------------------------------
/**
Binds the animating state to the state of the specified task.
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task activityIndicatorStyle:(UIActivityIndicatorViewStyle)style;
#endif
///---------------------------------------
/// @name Animating for Request Operations
///---------------------------------------
/**
Binds the animating state to the execution state of the specified operation.
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation activityIndicatorStyle:(UIActivityIndicatorViewStyle)style;
@end
#endif
//
// UISearchBar+AFNetworking.m
//
// Created by Huy Nguyen on 7/15/14.
// Copyright (c) 2014 Huy Nguyen. All rights reserved.
//
#import "UISearchBar+AFNetworking.h"
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import "AFHTTPRequestOperation.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#import "AFURLSessionManager.h"
#endif
#import <objc/runtime.h>
#import "UIView+SearchSubview.h"
@interface UISearchBar ()
@property(nonatomic, strong) UITextField *textField;
@property(nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
@property(nonatomic, strong) UIView *searchIconView;
@end
@implementation UISearchBar (AFNetworking)
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task activityIndicatorStyle:(UIActivityIndicatorViewStyle)style {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
if (task) {
if (task.state != NSURLSessionTaskStateCompleted) {
if (task.state == NSURLSessionTaskStateRunning) {
[self startAnimating];
} else {
[self stopAnimating];
}
[notificationCenter addObserver:self selector:@selector(startAnimatingSafely) name:AFNetworkingTaskDidResumeNotification object:task];
[notificationCenter addObserver:self selector:@selector(stopAnimatingSafely) name:AFNetworkingTaskDidCompleteNotification object:task];
[notificationCenter addObserver:self selector:@selector(stopAnimatingSafely) name:AFNetworkingTaskDidSuspendNotification object:task];
}
}
self.activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:style];
}
#endif
#pragma mark -
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation activityIndicatorStyle:(UIActivityIndicatorViewStyle)style {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
if (operation) {
if (![operation isFinished]) {
if ([operation isExecuting]) {
[self startAnimating];
} else {
[self stopAnimating];
}
[notificationCenter addObserver:self selector:@selector(startAnimatingSafely) name:AFNetworkingOperationDidStartNotification object:operation];
[notificationCenter addObserver:self selector:@selector(stopAnimatingSafely) name:AFNetworkingOperationDidFinishNotification object:operation];
}
}
self.activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:style];
}
#pragma mark -
- (UITextField *)textField {
return objc_getAssociatedObject(self, @selector(textField));
}
- (void)setTextField:(UITextField *)textField {
objc_setAssociatedObject(self, @selector(textField), textField, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIActivityIndicatorView *)activityIndicatorView {
return objc_getAssociatedObject(self, @selector(activityIndicatorView));
}
- (void)setActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView {
objc_setAssociatedObject(self, @selector(activityIndicatorView), activityIndicatorView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)searchIconView {
return objc_getAssociatedObject(self, @selector(searchIconView));
}
- (void)setSearchIconView:(UIView *)searchIconView {
objc_setAssociatedObject(self, @selector(searchIconView), searchIconView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)startAnimatingSafely {
dispatch_async(dispatch_get_main_queue(), ^{
[self startAnimating];
});
}
- (void)stopAnimatingSafely {
dispatch_async(dispatch_get_main_queue(), ^{
[self stopAnimating];
});
}
- (void)startAnimating {
[self setUpViews];
self.textField.leftView = self.activityIndicatorView;
[self.activityIndicatorView startAnimating];
}
- (void)stopAnimating {
[self setUpViews];
self.textField.leftView = self.searchIconView;
[self.activityIndicatorView stopAnimating];
}
- (void)setUpViews {
if (self.textField == nil) {
self.textField = [self subviewOfClass:[UITextField class]];
self.searchIconView = self.textField.leftView;
}
}
@end
#endif
//
// UIView+SearchSubview.h
//
// Created by Huy Nguyen on 7/15/14.
// Copyright (c) 2014 Huy Nguyen. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (SearchSubview)
- (id)subviewOfClass:(Class)class;
@end
//
// UIView+SearchSubview.m
//
// Created by Huy Nguyen on 7/15/14.
// Copyright (c) 2014 Huy Nguyen. All rights reserved.
//
#import "UIView+SearchSubview.h"
@implementation UIView (SearchSubview)
- (id)subviewOfClass:(Class)class {
for (UIView *subview in self.subviews) {
if ([subview isKindOfClass:class]) {
return subview;
}
UIView *secondLevelSubview = [subview subviewOfClass:class];
if (secondLevelSubview != nil) {
return secondLevelSubview;
}
}
return nil;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment