| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- //
- // CustomRadioGroup.m
- // JasonDevelop
- //
- // Created by Jason Lee on 3/10/14.
- // Copyright (c) jasondevelop. All rights reserved.
- //
- @import ObjectiveC.runtime;
- #import <stdarg.h>
- #import "CustomRadioGroup.h"
- #import "CommonUtil.h"
- #import "ImageUtil.h"
- @interface CustomRadioButton () {
- }
- @end
- @implementation CustomRadioButton
- @synthesize checked = _checked;
- - (instancetype)initWithFrame:(CGRect)frame normalImage:(UIImage *)normalImage highlightImage:(UIImage *)highlightImage {//소스레벨에서 로드하는 경우, 초기화
- if (self = [super initWithFrame:frame]) {
- _normalImage = normalImage;
- _highlightImage = highlightImage;
- [self setImage:_normalImage forState:UIControlStateNormal];
- [self setImage:_highlightImage forState:UIControlStateHighlighted];
- [self.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
- [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- }
- return self;
- }
- - (void)awakeFromNib {
- _normalImage = [self imageForState:UIControlStateNormal];
- _highlightImage = [self imageForState:UIControlStateHighlighted];
- _titleColorNormal = [self titleColorForState:UIControlStateNormal];
- _titleColorHighlight = [self titleColorForState:UIControlStateHighlighted] ? [self titleColorForState:UIControlStateHighlighted] : _titleColorNormal;
- [self.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
- [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- }
- - (void)setChecked:(BOOL)checked {//
- _checked = checked;
- if (_checked) {
- [self setImage:_highlightImage forState:UIControlStateNormal];
- [self setTitleColor:_titleColorHighlight forState:UIControlStateNormal];
- } else {
- [self setImage:_normalImage forState:UIControlStateNormal];
- [self setTitleColor:_titleColorNormal forState:UIControlStateNormal];
- }
- if (_value) {
- objc_setAssociatedObject(_value, ksCustomRadioButtonStatus, [NSNumber numberWithBool:_checked], OBJC_ASSOCIATION_COPY_NONATOMIC);
- }
- }
- - (BOOL)getRadioStatusFromValue {
- BOOL isChecked = NO;
- if (_value) {
- isChecked = [objc_getAssociatedObject(_value, ksCustomRadioButtonStatus) boolValue];
- }
- return isChecked;
- }
- - (void)didRadioButtonTouched:(id)sender {
- if (self.delegate) {
- self.checked = !self.checked;
- }
- if ([self.delegate respondsToSelector:@selector(didCheckRadioButton:)]) {
- [self.delegate didCheckRadioButton:self];
- }
- }
- @end
- @interface CustomBgRadioButton () {
- // UIImage *_bgNormalImage, *_bgHighlightImage;
- // UIEdgeInsets _bgInsets;
- }
- @end
- #define kfRoundWidth 1.0f
- @implementation CustomBgRadioButton
- @dynamic checked;
- - (instancetype)initWithFrame:(CGRect)frame bgNormalImage:(UIImage *)bgNormalImage bgHighlightImage:(UIImage *)bgHighlightImage rectForCapBg:(CGRect)rectForCapBg {
- if (self = [super initWithFrame:frame]) {
- _bgNormalImage = bgNormalImage;
- _bgHighlightImage = bgHighlightImage;
- _rectForCapBg = rectForCapBg;
- [self setBackgroundImage:_bgNormalImage forState:UIControlStateNormal];
- [self setBackgroundImage:_bgHighlightImage forState:UIControlStateHighlighted];
- [self setImage:_normalImage forState:UIControlStateNormal];
- [self setImage:_highlightImage forState:UIControlStateHighlighted];
- if (!CGRectEqualToRect(_rectForCapBg, CGRectZero)) {//rectForCap이 설정된 경우, 이미지를 리사이즈함.
- CGFloat top, left, bottom, right;
- top = CGRectGetMinY(_rectForCapBg);
- left = CGRectGetMinX(_rectForCapBg);
- bottom = CGRectGetHeight(_rectForCapBg);
- right = CGRectGetWidth(_rectForCapBg);
- _bgInsets = UIEdgeInsetsMake(top, left, bottom, right);
- [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
- [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
- } else {//rectForCap이 설정되지 않은 경우, 픽스된 사이즈로 이미지를 리사이즈함.
- _bgInsets = UIEdgeInsetsMake(kfRoundWidth, kfRoundWidth, kfRoundWidth, kfRoundWidth);
- [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
- [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
- }
- [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- }
- return self;
- }
- - (void)setBackgroundImageStretchForState:(UIControlState)state capInsets:(UIEdgeInsets)insets {
- UIImage *bimage = [self backgroundImageForState:state];
- bimage = [ImageUtil resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch img:bimage];
- [super setBackgroundImage:bimage forState:state];
- }
- - (void)awakeFromNib {
- _bgNormalImage = [self backgroundImageForState:UIControlStateNormal];
- _bgHighlightImage = [self backgroundImageForState:UIControlStateHighlighted];
- _normalImage = [self imageForState:UIControlStateNormal];
- _highlightImage = [self imageForState:UIControlStateHighlighted];
- _titleColorNormal = [self titleColorForState:UIControlStateNormal];
- _titleColorHighlight = [self titleColorForState:UIControlStateHighlighted] ? [self titleColorForState:UIControlStateHighlighted] : _titleColorNormal;
- if (!CGRectEqualToRect(_rectForCapBg, CGRectZero)) {//rectForCap이 설정된 경우, 이미지를 리사이즈함.
- CGFloat top, left, bottom, right;
- top = CGRectGetMinY(_rectForCapBg);
- left = CGRectGetMinX(_rectForCapBg);
- bottom = CGRectGetHeight(_rectForCapBg);
- right = CGRectGetWidth(_rectForCapBg);
- _bgInsets = UIEdgeInsetsMake(top, left, bottom, right);
- [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
- [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
- } else {//rectForCap이 설정되지 않은 경우, 픽스된 사이즈로 이미지를 리사이즈함.
- [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
- [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
- }
- [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- }
- - (void)setChecked:(BOOL)checked {
- _checked = checked;
- if (_checked) {
- [self setBackgroundImage:_bgHighlightImage forState:UIControlStateNormal];
- [self setTitleColor:_titleColorHighlight forState:UIControlStateNormal];
- if (_normalImage && _highlightImage) {
- [self setImage:_highlightImage forState:UIControlStateNormal];
- [self setImage:_normalImage forState:UIControlStateHighlighted];
- }
- } else {
- [self setBackgroundImage:_bgNormalImage forState:UIControlStateNormal];
- [self setTitleColor:_titleColorNormal forState:UIControlStateNormal];
- if (_normalImage && _highlightImage) {
- [self setImage:_normalImage forState:UIControlStateNormal];
- [self setImage:_highlightImage forState:UIControlStateHighlighted];
- }
- }
- [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
- [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
- if (self.value) {
- objc_setAssociatedObject(self.value, ksCustomRadioButtonStatus, [NSNumber numberWithBool:self.checked], OBJC_ASSOCIATION_COPY_NONATOMIC);
- }
- }
- @end
- @interface CustomRadioGroup () {
- NSMutableArray *_btns;
- CustomRadioButton *_btnChecked;
- UIImage *_imageNormal, *_imageHighlight, *_bgImageNormal, *_bgImageHighlight;
- BOOL _isFirstLoading;
- }
- @end
- @implementation CustomRadioGroup
- - (id)init {
- if (self = [super init]) {
- _btns = [NSMutableArray new];
- _isFirstLoading = YES;
- }
- return self;
- }
- - (id)initWithRadioButtons:(id)buttons, ... {//라디오 버튼 그룹을 만듬, 들어오는 버튼수만큰 멤버로 할당됨.
- if (self = [super init]) {
- if (buttons) {
- _btns = [NSMutableArray new];
- if ([buttons isKindOfClass:[CustomBgRadioButton class]]) {
- // _bgImageNormal = [UIImage imageNamed:@"tp_01_img_control_bg_black"];
- // _bgImageHighlight = [UIImage imageNamed:@"tp_01_img_control_bg_active"];
- [(UIButton *)buttons setBackgroundImage:_imageHighlight forState:UIControlStateHighlighted];
- } else if ([buttons isKindOfClass:[CustomBgRadioButton class]]) {
- _imageNormal = [UIImage imageNamed:@"common_radiobox_default"];
- _imageHighlight = [UIImage imageNamed:@"common_radiobox_checked"];
- [(UIButton *)buttons setImage:_imageHighlight forState:UIControlStateHighlighted];
- }
- [buttons addTarget:self action:@selector(someRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- [_btns addObject:buttons];
- _btnChecked = buttons; //첫번째 버튼을 선택상태로
- _btnChecked.checked = YES;
- va_list args;
- va_start(args, buttons);
- while ((buttons = va_arg(args, id)) != nil) {//루프 - 버튼을 그룹에 추가함.
- if ([buttons isKindOfClass:[CustomRadioButton class]]) {
- [buttons addTarget:self action:@selector(someRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- [_btns addObject:buttons];
- }
- }
- va_end(args);
- }
- }
- return self;
- }
- //Do not use in resusable table
- - (void)addRadioButton:(CustomRadioButton *)button {//라디오 그룹에 버튼을 추가함.
- CustomRadioButton *lBtn = [_btns lastObject];
- if ([button isKindOfClass:[CustomBgRadioButton class]]) {
- if (lBtn == nil) {//첫번째 버튼
- if (_isFirstLoading) {
- _bgImageNormal = [button backgroundImageForState:UIControlStateNormal];
- _bgImageHighlight = [button backgroundImageForState:UIControlStateHighlighted];
- _isFirstLoading = NO;
- }
- [button setBackgroundImage:_bgImageHighlight forState:UIControlStateNormal];
- [button setBackgroundImage:_bgImageNormal forState:UIControlStateHighlighted];
- _btnChecked = button;
- _btnChecked.checked = YES;
- } else {
- [button setBackgroundImage:_bgImageNormal forState:UIControlStateNormal];
- [button setBackgroundImage:_bgImageHighlight forState:UIControlStateHighlighted];
- }
- } else if ([button isKindOfClass:[CustomRadioButton class]]) {
- if (lBtn == nil) {//첫번째 버튼
- if (_isFirstLoading) {
- _imageNormal = [button imageForState:UIControlStateNormal];
- _imageHighlight = [button imageForState:UIControlStateHighlighted];
- _isFirstLoading = NO;
- }
- [button setImage:_imageHighlight forState:UIControlStateNormal];
- [button setImage:_imageNormal forState:UIControlStateHighlighted];
- _btnChecked = button;
- _btnChecked.checked = YES;
- } else {
- [button setImage:_imageNormal forState:UIControlStateNormal];
- [button setImage:_imageHighlight forState:UIControlStateHighlighted];
- }
- }
- [button addTarget:self action:@selector(someRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
- [_btns addObject:button];
- }
- - (void)reset {
- [_btns removeAllObjects];
- }
- - (id)valueForChecked {//선택된 Object를 반환함.
- return _btnChecked.value;
- }
- - (id)titleForChecked {//선택된 타이틀을 반환함.
- return _btnChecked.titleLabel.text;
- }
- - (NSInteger)count {
- return _btns.count;
- }
- - (NSArray *)rdoBtns {
- return _btns;
- }
- - (void)someRadioButtonTouched:(id)sender {//특정 라디오버튼이 선택된 경우, 값을 설정함.
- if (_btnChecked == sender)
- return;
- CustomRadioButton *btnSender = (CustomRadioButton *)sender;
- for (CustomRadioButton *btn in _btns) {
- if ([btnSender isEqual:btn]) {
- _btnChecked = btnSender;
- _btnChecked.checked = YES;
- } else {
- btn.checked = NO;
- }
- }
- if ([self.delegate respondsToSelector:@selector(didSomeRadioButtonTouched:)]) {
- [self.delegate didSomeRadioButtonTouched:sender];
- }
- }
- @end
- @interface CustomRadioReusableGroup () <CustomRadioButtonDelegate> {
- NSMutableArray *_valueArray;
- }
- @end
- @implementation CustomRadioReusableGroup
- - (instancetype)init {
- if (self = [super init]) {
- _valueArray = [[NSMutableArray alloc] init];
- }
- return self;
- }
- - (void)addRadioButton:(CustomRadioButton *)rbtn {
- if ([_valueArray containsObject:rbtn.value]) {//동일한 오브젝트에 대한 validate
- return;
- }
- rbtn.delegate = self;
- [_valueArray addObject:rbtn.value];
- }
- - (NSArray *)values {
- return _valueArray;
- }
- - (void)someRadioButtonTouched:(CustomRadioButton *)touchedRbtn {
- for (id avalue in _valueArray) {
- if ([touchedRbtn.value isEqual:avalue]) {
- touchedRbtn.checked = YES;
- continue;
- }
- if ([objc_getAssociatedObject(avalue, ksCustomRadioButtonStatus) boolValue]) {
- objc_setAssociatedObject(avalue, ksCustomRadioButtonStatus, [NSNumber numberWithBool:NO], OBJC_ASSOCIATION_COPY_NONATOMIC);
- }
- }
- [_tableView reloadData];
- if ([self.delegate respondsToSelector:@selector(didSomeReuableRadioButtonTouched:)]) {
- [self.delegate didSomeReuableRadioButtonTouched:touchedRbtn];
- }
- }
- - (void)reset {
- [_valueArray removeAllObjects];
- }
- - (id)valueForChecked {
- id resultValue = nil;
- for (id avalue in _valueArray) {
- if ([objc_getAssociatedObject(avalue, ksCustomRadioButtonStatus) boolValue]) {
- resultValue = avalue;
- }
- }
- return resultValue;
- }
- #pragma mark - CustomRadioButton Delegate
- - (void)didCheckRadioButton:(id)sender {
- [self someRadioButtonTouched:sender];
- }
- @end
|