2012-04-17 2 views
2

나는 UIButton의 그리드가 있습니다. '편집'버튼을 누르면 삭제 버튼이 각 버튼 위에 나타나게됩니다.이 버튼을 누르면 버튼 (및 관련 데이터)이 삭제됩니다. 사과의 홈 화면과 비슷합니다. 버튼을 누르고 있으면 구석에있는 X로 흔들 리기 시작합니다.삭제 기능을 사용하여 사용자 지정 UIButton 클래스 만들기

이 게시물에 따르면 : Subclass UIButton to add a property 연관성있는 참조를 사용하여 각 버튼에 속성을 추가 할 수 있습니다. 내 사용자 지정 UIButton의 속성으로 UIButton을 추가하려고 시도했지만 표시 할 수없고 이것이 올바른 방법이 아니라고 느낄 수는 없습니다. 내가 프로그래밍 버튼을 추가 할 경우 여기에

#import "UIButton+Property.h" 
#import <objc/runtime.h> 

@implementation UIButton(Property) 

static char UIB_DELETEBUTTON_KEY; 

@dynamic deleteButton; 


- (void)setDeleteButton:(UIButton *)deleteButton { 
    deleteButton = [UIButton buttonWithType:UIButtonTypeInfoDark]; 
    deleteButton.frame = CGRectMake(100, 100, 50, 50); 
    objc_setAssociatedObject(self, &UIB_DELETEBUTTON_KEY, deleteButton, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

- (UIButton *)deleteButton { 
    return (UIButton *)objc_getAssociatedObject(self, &UIB_DELETEBUTTON_KEY); 
} 

@end 

을 그리고 :

//Create a custom button for each custom book doc 
for (int i = 0; i < [customBookDocs count]; ++i) { 
    BookDoc *customBookDoc = [customBookDocs objectAtIndex:i]; 
    NSString *bookTitle = customBookDoc.book.title; 

    //create a button for each book 
    CGRect frame = CGRectMake(xCoord, yCoord, 200, 200); 
    UIButton *bookButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    bookButton.bookDoc = customBookDoc; 
    [bookButton setFrame:frame]; 
    [bookButton setTitle:bookTitle forState:UIControlStateNormal]; 
    [bookButton addTarget:self action:@selector(bookButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
    xCoord += 250; 

    [self.view addSubview:bookButton]; 
    [self.view addSubview:bookButton.deleteButton]; 
} 

이 작업을 수행하려면 쉽게 분별있는 방법이 여기 내 사용자 지정 버튼이 메인인가? 아니면 올바른 방향으로 가고 있습니까?

... 다른 사람이 그것에 대해 말할 더있을 수 있습니다,하지만 난 당신이 여기에 개체 연결을 사용할 필요가 줄 이유는 확실하지 않다 :

+1

삭제 버튼을 실제로 설정하지 않았습니다. 또한 연관 메서드는 어쨌든 설정 한 삭제 단추를 무시합니다. – Joe

답변

1

ORIGINAL 응답하기 시작했다. 물론 서브 클래 싱을 사용하는 버튼으로 다른 버튼을 속성으로 추가 할 수 있습니다. 이는 내가 취할 경로입니다. ...

은 아래 편집 :

내가 직접 UI 컨트롤을 서브 클래스했다고 생각했지만, 내가 코드를 찾아 갔을 때 나는 내가 잘못 것을 깨달았다. @Joe는 주석에서 직접 UI 컨트롤을 서브 클래 싱하는 데 문제가 있다는 지적을 올바르게 지적했습니다.

관련 객체를 사용하지 않고 설명 된 기능과 같이 버튼을 보유 할 래퍼 클래스와 관련 삭제 버튼을 구현하여 구현할 수있었습니다. 작동하지만 매우 유연하지 않으므로 일반적으로 @ Joe의 방법을 더 나은 솔루션으로 추천합니다.

내가 AppDelegate에에 모든 코드를 던졌다 간단하게하기 :

다음은 관련 코드입니다. 나는 실제 삶에서 그걸 추천하지 않는다.

AppDelegate.m :

@implementation AppDelegate 

@synthesize window = _window; 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 

    self.window.backgroundColor = [UIColor whiteColor]; 

    UIButton *toggleDeleteButtons = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [toggleDeleteButtons setFrame:CGRectMake(20, 45, 280, 45)]; 
    [toggleDeleteButtons setTitle:@"Toggle Delete" forState:UIControlStateNormal]; 
    [toggleDeleteButtons addTarget:self action:@selector(toggleDeleteButtonAction) forControlEvents:UIControlEventTouchUpInside]; 
    [[self window] addSubview:toggleDeleteButtons]; 

    ButtonWrapper *myButtonWrapper = [[ButtonWrapper alloc] init]; 
    [[myButtonWrapper button] setFrame:CGRectMake(20, 100, 200, 45)]; 
    [[myButtonWrapper button] setTitle:@"This is my button" forState:UIControlStateNormal]; 
    [[myButtonWrapper deleteButton] addTarget:self action:@selector(buttonDeleteRequested:) forControlEvents:UIControlEventTouchUpInside]; 
    [[myButtonWrapper deleteButton] setTag:0]; 
    [[self window] addSubview:[myButtonWrapper button]]; 
    buttonWrapper1 = myButtonWrapper; 

    // Added instance called anotherButtonWrapper with tag 1, as above 

    // Added instance called stillAnotherButtonWrapper with tag 2, as above 

    [self.window makeKeyAndVisible]; 
    return YES; 
} 

- (void)toggleDeleteButtonAction { 
    static BOOL deleteButtonsShown; 

    [buttonWrapper1 showDeleteButton:!deleteButtonsShown]; 
    [buttonWrapper2 showDeleteButton:!deleteButtonsShown]; 
    [buttonWrapper3 showDeleteButton:!deleteButtonsShown]; 
    deleteButtonsShown = !deleteButtonsShown; 
} 

- (void)buttonDeleteRequested:(UIButton *)deleteButton { 
    // delete the specified button here 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Delete" message:[NSString stringWithFormat:@"Delete was pressed on button %i",[deleteButton tag]]delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [alert show]; 
} 

ButtonWrapper.m :

@implementation ButtonWrapper 

@synthesize button; 
@synthesize deleteButton; 

- (ButtonWrapper *)init { 
    ButtonWrapper *newWrapper = [ButtonWrapper alloc]; 

    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [myButton setFrame:CGRectZero]; 

    UIButton *myDeleteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [myDeleteButton setFrame:CGRectMake(0, 0, 100, 40)]; 
    [myDeleteButton setTitle:@"Delete" forState:UIControlStateNormal]; 
    [myDeleteButton setHidden:TRUE]; 
    [myButton addSubview:myDeleteButton]; 

    [newWrapper setButton:myButton]; 
    [newWrapper setDeleteButton:myDeleteButton]; 

    return newWrapper; 
} 

- (void)showDeleteButton:(BOOL)showButton { 
    if (showButton) { 
     [[self deleteButton] setHidden:FALSE]; 
     [[self deleteButton] setEnabled:TRUE]; } 
    else { 
     [[self deleteButton] setHidden:TRUE]; 
     [[self deleteButton] setEnabled:FALSE]; 
    } 
} 
@end 

이 솔루션은 UI의 모든 속성을 구현하기 위해 저를 필요로하지 않았다, 그러나 후크하는 추가 작업이 필요 않은 임베디드 델리게이트는 성가신 일이다. 대리자를 초기화 할 때 래퍼에 전달할 수있는 방법이 있지만 작동하지 못합니다.

+1

UIButton은 클래스 클러스터의 일부이므로 연관 참조가 더 적합합니다. – Joe

+0

+1 @Joe. UICutton 대신 UIControl을 서브 클래 싱하는 경향이 있습니다. 왜냐하면 기본 버튼이 너무 어설프 어서 많은 것을 잃지 않고 버튼 기능을 다시 얻으 려하지 않기 때문입니다. – jrturton

+0

일반적으로 UIButton을 하위 클래스로 분류하는 것은 나쁜 생각이며 기본 동작을 복제하려면 많은 코드가 필요하다는 것을 읽었습니다. 그게 내가 연관 참조를 시도한 이유는 정확히 내가 거기에서 뭘하는지 모르겠지만 ...하지만 나는 그것을 이해할 수 없다면 UIButton을 서브 클래 싱하는 것으로 돌아갈 수있다. – Smikey

관련 문제