Skip to content

Instantly share code, notes, and snippets.

@leoschweizer
Created April 29, 2015 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leoschweizer/667bf1476e25333459a2 to your computer and use it in GitHub Desktop.
Save leoschweizer/667bf1476e25333459a2 to your computer and use it in GitHub Desktop.
#import "CKSwitchComponent.h"
#import <ComponentKit/CKComponentSubclass.h>
#import <ComponentKit/CKComponentScope.h>
#import <ComponentKit/CKComponentController.h>
#import "CKComponentInternal.h"
void runOnMainQueueWithoutDeadlocking(void (^block)(void)) {
if ([NSThread isMainThread]) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
}
@interface CKSwitchComponentController : CKComponentController
@property (nonatomic, readwrite) UISwitch *switchView;
@end
@interface CKSwitchComponent ()
@property (nonatomic) BOOL isOnState;
@property (nonatomic) CKViewComponentAttributeValueMap viewAttributes;
@property (nonatomic) CKComponentAction userAction;
@end
@implementation CKSwitchComponentController
- (instancetype)init {
if (self = [super init]) {
runOnMainQueueWithoutDeadlocking(^{
self->_switchView = [[UISwitch alloc] init];
});
}
return self;
}
- (void)componentDidAcquireView {
[super componentDidAcquireView];
[self.view.subviews enumerateObjectsUsingBlock:^(UIView *subview, NSUInteger idx, BOOL *stop) {
[subview removeFromSuperview];
}];
[self.switchView addTarget:self action:@selector(onSwitchValueChanged:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:self.switchView];
}
- (void)didUpdateComponent {
[super didUpdateComponent];
CKSwitchComponent *switchComponent = (id)self.component;
CK::Component::AttributeApplicator::apply(self.switchView, {[UISwitch class], switchComponent.viewAttributes});
// Note: the isOn state can't be handled through the viewAttributes, since cancelling
// a switch action would then be a no-op (old and new viewAttributes are equal and thus
// not applied to the view; this is a force-apply so to speak)
[self.switchView setOn:switchComponent.isOnState];
}
- (void)onSwitchValueChanged:(id)sender {
CKSwitchComponent *switchComponent = (id)self.component;
CKComponentActionSend(switchComponent.userAction, self.component);
}
@end
@implementation CKSwitchComponent
+ (CKComponentSize)fixedSize {
static CKComponentSize size;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UISwitch *prototype = [[UISwitch alloc] init];
size = {
.width = prototype.frame.size.width,
.height = prototype.frame.size.height
};
});
return size;
}
+ (instancetype)newWithIsOn:(BOOL)isOn
viewAttributes:(const CKViewComponentAttributeValueMap &)viewAttributes
action:(CKComponentAction)action
{
CKComponentScope scope(self);
CKViewComponentAttributeValueMap attributes(viewAttributes);
CKSwitchComponent *c = [super newWithView:{
[UIView class]
}
size:[self fixedSize]];
c.isOnState = isOn;
c.viewAttributes = attributes;
c.userAction = action;
return c;
}
- (BOOL)isOn {
CKSwitchComponentController *controller = (id)self.controller;
return controller.switchView.isOn;
}
- (void)reset {
CKSwitchComponentController *controller = (id)self.controller;
runOnMainQueueWithoutDeadlocking(^{
controller.switchView.on = !controller.switchView.isOn;
});
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment