元の応答の始まり:
... 他の誰かがそれについてもっと言いたいことがあるかもしれませんが、ここでオブジェクトの関連付けを使用する必要がある理由がわかりません。通常のサブクラス化を使用して、ボタンに別のボタンをプロパティとして追加できます。これは、私がとるルートです。...
以下の編集:
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 プロパティを実装する必要はありませんでしたが、埋め込まれたデリゲートを接続するために余分な作業が必要になり、面倒でした。初期化時にデリゲートをラッパーに渡す方法があるかもしれませんが、機能させることができませんでした。