Let me first state, that this is not a matter of getting my selector name right, nor setting up the button target in loadView, nor any other suggestion I've seen in the last 4 hours of browsing. I should also explain I am not using nibs, nor IB.
These buttons have been working for the bulk of development.
Then poof! It's not just the buttons. My table views do not scroll. Pressing the cells in the table views do not invoke the actions that I had setup.
It seems I've broken the responder chain entirely; or something to that effect.
To try and narrow down the source of the problem a created a window-based project; stripped out everything that xCode generates; deleted the nib; and copied in several methods from my original app delegate and my rootViewController.
It's the RVT that contains the subView that contains the buttons. Fairly straight forward. Same effect. I've literally stripped out all functional code but the following source in appDelegate.m:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setDelegate:self];
if(window == nil)
window = [[UIWindow alloc] init];
window.autoresizesSubviews = YES;
if(controller == nil)
controller = [[Controller alloc] init];
window.rootViewController = controller;
[window makeKeyAndVisible];
return YES;
}
-(void)dealloc {
[window release];
[controller release];
[super dealloc];
}
And in Controller:
- (void)buttonResponse {
NSLog(#"Button touched up inside!!!!!");
}
- (void)loadView {
[super loadView];
//test
button = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Button" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = [image size];
CGRect buttonFrame = CGRectMake(0,0,imageSize.width + 100, BUTTONBAR_H + 100);
button.frame = buttonFrame;
[button setImage:image forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"" forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(buttonResponse) forControlEvents: UIControlEventTouchUpInside];
UIView *view = self.view;
CGRect viewFrame = view.frame; //self.view is valid and takes up available screen
[self.view addSubview:button];
[self.view bringSubviewToFront:button];
//end test
[self.view setNeedsDisplay];
}
- (void)dealloc {
[button release];
[super dealloc];
}
I know it's gotta be something really simple. But I can't see it. I would prefer to leave my hair in place. I'm wondering if that's going to happen as I continue to learn the quirks.
Does loadView ever get called? Put a NSLog (or a breakpoint) in loadView just as a sanity check.
Also, from UIViewController Documentation:
If you override this method (loadView) in order to create your views manually,
you should do so and assign the root view of your hierarchy to the
view property. (The views you create should be unique
instances and should not be shared with any other view controller
object.) Your custom implementation of this method should not call super.
If you want to perform any additional initialization of your views, do
so in the viewDidLoad method. In iOS 3.0 and later, you
should also override the viewDidUnload method to release any
references to the view or its contents.
Try putting all the button code in viewDidLoad:
- (void)buttonResponse:(id)sender {
NSLog(#"Button touched up inside!!!!!");
}
- (void)loadView {
// Dont call super (according to the UIViewController docs)
// [super loadView];
// self.view = ... however your setting up self.view
// self.view.frame = CGRectMake....
// self.view.etc...
[self.view setNeedsDisplay];
}
- (void)viewDidLoad {
[super viewDidLoad];
button = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Button" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = [image size];
CGRect buttonFrame = CGRectMake(0,0,imageSize.width + 100, BUTTONBAR_H + 100);
button.frame = buttonFrame;
[button setImage:image forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"" forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(buttonResponse:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
[self.view bringSubviewToFront:button];
}
- (void)dealloc {
[button release];
[super dealloc];
}
Related
SOLUTION: it was stupidly simple, I overlooked the need to declare the method for my button function in this implementation, the fix was simply adding this in the right spot (inside the implementation... duh!)
-(void)bugButton { //do stuff }
Found some code for a button that looked like what I wanted. After adding & compiling the button crashes my app when tapped, any idea why? Heres the entire cell, pretty new to making these so its hacked together from other stuff, the button stuff is near the top. I do have the method in a different place (and have used boring PSButtonCell's successfully so I know that the method works)
#interface harpButtonCell : PSTableCell <PreferencesTableCustomView> {
}
#end
#implementation harpButtonCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(id)reuseIdentifier specifier:(id)specifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier specifier:specifier];
if (self) {
// icon
UIImage *bugImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#/Bug.png", kSelfBundlePath]];
UIButton *bugbutton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 75, 75)];
[bugbutton setImage:bugImage forState:UIControlStateNormal];
[bugbutton addTarget:self action:#selector(bugButton) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:bugbutton];
/*
UIImage *paypalImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#/Paypal.png", kSelfBundlePath]];
UIButton *paypalbutton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 75, 75)];
[paypalbutton setImage:paypalImage forState:UIControlStateNormal];
[paypalbutton addTarget:self action:#selector(paypalButton) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:paypalbutton];*/
//int width = self.contentView.bounds.size.width;
}
return self;
}
- (instancetype)initWithSpecifier:(PSSpecifier *)specifier {
return [self initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"harpButtonCell" specifier:specifier];
}
- (void)setFrame:(CGRect)frame {
frame.origin.x = 0;
[super setFrame:frame];
}
- (CGFloat)preferredHeightForWidth:(CGFloat)arg1{
return 100.0f;
}
- (CGFloat)preferredHeightForWidth:(CGFloat)width inTableView:(id)tableView {
return [self preferredHeightForWidth:width];
}
#end
It seems that you don't implement the action of button, try to add the action in the cell:
-(void)bugButton{
NSLog(#"you clicked on button");
}
I have a scrollview(timesScrollView) which is added as a subview on a view(dropDownView).The view is hidden until a particular button is pressed, when that button is pressed view will appear.
(IBAction)how_many_times_btn_click:(id)sender{
if(howMany==false){
for(UIView *view in dropDownView.subviews)
{
[view removeFromSuperview];
}
howMany=true;
duration=false;
how_many_times_btn.backgroundColor=[UIColor colorWithRed:130/255.0f green:189/255.0f blue:31/255.0f alpha:1.0f];
durationBtn.backgroundColor=[UIColor colorWithRed:62/255.0f green:67/255.0f blue:79/255.0f alpha:1.0f];
startBtn.backgroundColor=[UIColor colorWithRed:62/255.0f green:67/255.0f blue:79/255.0f alpha:1.0f];
dropDownView.hidden=NO;
dropDownView.frame=CGRectMake(0, 0, self.view.frame.size.width,70);
dropDownView.backgroundColor=[UIColor colorWithRed:37/255.0f green:42/255.0f blue:54/255.0f alpha:1.0f];
//dropDownView.backgroundColor=[UIColor whiteColor];
targetLbl=[[UILabel alloc]init];
targetLbl.frame=CGRectMake(0, 30, dropDownView.frame.size.width,30);
targetLbl.text=#"TARGET";
targetLbl.textColor=[UIColor whiteColor];
targetLbl.font=[UIFont boldSystemFontOfSize:22];
targetLbl.textAlignment=NSTextAlignmentCenter;
how_many_Lbl=[[UILabel alloc]init];
how_many_Lbl.frame=CGRectMake(0, targetLbl.frame.origin.y+targetLbl.frame.size.height, dropDownView.frame.size.width, 20);
how_many_Lbl.textAlignment=NSTextAlignmentCenter;
how_many_Lbl.text=#"HOW MANY TIMES WILL YOU DO IT?";
how_many_Lbl.textColor=[UIColor colorWithRed:65/255.0f green:71/255.0f blue:80/255.0f alpha:1.0f];
how_many_Lbl.font=[UIFont systemFontOfSize:10.0f];
hideViewBtn=[UIButton buttonWithType:UIButtonTypeCustom];
hideViewBtn.frame=CGRectMake(dropDownView.frame.size.width-30,20,20,20);
[hideViewBtn setImage:[UIImage imageNamed:#"Close Icon [ x ]"] forState:UIControlStateNormal];
[hideViewBtn addTarget:self action:#selector(hideView) forControlEvents:UIControlEventTouchUpInside];
//hideViewBtn.backgroundColor=[UIColor whiteColor];
self.timesScroll=[[LTInfiniteScrollView alloc] initWithFrame:CGRectMake(0, how_many_Lbl.frame.origin.y+how_many_Lbl.frame.size.height+16, dropDownView.frame.size.width, 102)];
//self.timesScroll.backgroundColor=[UIColor whiteColor];
self.timesScroll.verticalScroll=NO;
self.timesScroll.dataSource=self;
self.timesScroll.maxScrollDistance=5;
self.timesScroll.contentInset=UIEdgeInsetsMake(0, self.timesScroll.frame.size.width/2-31, 0,self.timesScroll.frame.size.width/2-31 );
self.timesScroll.userInteractionEnabled=YES;
self.timesScroll.exclusiveTouch=YES;
dropDownView.frame=CGRectMake(0, 0, self.view.frame.size.width,_timesScroll.frame.origin.y+_timesScroll.frame.size.height+20);
[self viewWillAppear:YES];
[dropDownView addSubview:targetLbl];
[dropDownView addSubview:how_many_Lbl];
[dropDownView addSubview:hideViewBtn];
[dropDownView addSubview:_timesScroll];
}
else
{
[self hideView];
}
}
The method above is what I am using to create view.
Now my problem is that when that particular button(how_many_times_btn) is pressed again all views are first removed then added as you can see and scrollview starts from initial position but I want it show from where I left it last time how_many_times_btn was clicked.
Hope you can understand What I am trying to say....if not I am happy to elaborate furthur.
you can get the last position by delegate methods
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
nslog(#"%f %f",scrollView.contentOffset.x,scrollView.contentOffset.y);
}
and store the x and y value and set
scrollView.contentOffset = CGPointMake(x,y);
You can save contentOffsetto one variable of CGPoint. And use this variable 's value later to scroll the UIScrollview.
Something like below line of code :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
contentOffset = scrollView.contentOffset;
}
When button pressed write below line of code:
self.timesScroll .contentOffset = contentOffset;
I'm using LTInfiniteScrollview in which there is a method 'reloadDataWithInitialIndex'
-(void)reloadDataWithInitialIndex:(NSInteger)initialIndex
{
for (UIView *view in self.scrollView.subviews) {
[view removeFromSuperview];
}
self.views = [NSMutableDictionary dictionary];
self.visibleViewCount = [self.dataSource numberOfVisibleViews];
self.totalViewCount = [self.dataSource numberOfViews];
[self updateSize];
_currentIndex = initialIndex;
self.scrollView.contentOffset = [self contentOffsetForIndex:_currentIndex];
[self reArrangeViews];
[self updateProgress];}
This method is called in 'viewWillAppear'
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.viewSize = CGRectGetWidth(self.view.frame) / Number_of_visibleViews;
self.timesScroll.delegate=self;
[self.timesScroll reloadDataWithInitialIndex:howIndex];}
I just passed previous index value here.
Edit: The UIActivityIndicatorView thinks it isn't on the screen... all values show that it isn't, but when you look at screen, it is there.
So... this is sort of driving me insane.
I am using https://github.com/fphilipe/PHFComposeBarView
I am editing it so that I can put a UIActivityIndicatorView in place of the button on the right when loading...
As it stands, I can perfectly start animating the UIActivityIndicatorView... but when I have to stopAnimating it, it won't stop and it won't disappear.
I have hidesWhenStopped = true and I know that everything is happening on the main thread.
In fact, when I use println or NSLog, I see that the UIActivityIndicatorView thinks that it is hidden... when it clearly is not.
Anyone know why it might not be working?
Edit: I even tried to mitigate this by instead having the UIActivityIndicatorView always be animated and just add it to the view or remove it from its superview... Again, when I needed to remove it, it wouldn't work...
- (void)startLoading {
dispatch_async(dispatch_get_main_queue(), ^{
[[self loadIndicator] startAnimating];
});
}
- (void)stopLoading {
dispatch_async(dispatch_get_main_queue(), ^{
[[self loadIndicator] stopAnimating];
});
}
#synthesize button = _button;
- (UIButton *)button {
if (!_button) {
_button = [PHFComposeBarView_Button buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake([self bounds].size.width - kHorizontalSpacing - kButtonRightMargin - kButtonTouchableOverlap,
[self bounds].size.height - kButtonBottomMargin - kButtonHeight,
2 * kButtonTouchableOverlap,
kButtonHeight);
[_button setFrame:frame];
[_button setTitleEdgeInsets:UIEdgeInsetsMake(0.5f, 0, 0, 0)];
[_button setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleTopMargin];
[_button setTitle:[self buttonTitle] forState:UIControlStateNormal];
UIColor *disabledColor = [UIColor colorWithHue:240.0f/360.0f saturation:0.03f brightness:0.58f alpha:1.0f];
[_button setTitleColor:disabledColor forState:UIControlStateDisabled];
UIColor *enabledColor = [UIColor colorWithHue:211.0f/360.0f saturation:1.0f brightness:1.0f alpha:1.0f];
[_button setTitleColor:enabledColor forState:UIControlStateNormal];
[_button addTarget:self action:#selector(didPressButton) forControlEvents:UIControlEventTouchUpInside];
UILabel *label = [_button titleLabel];
[label setFont:[UIFont boldSystemFontOfSize:kFontSize]];
}
return _button;
}
#synthesize loadIndicator = _loadIndicator;
- (UIActivityIndicatorView *)loadIndicator {
if (!_loadIndicator) {
UIButton *rightButton = [self button];
_loadIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake([rightButton frame].origin.x + [rightButton frame].size.width / 2.0f - [rightButton frame].size.height / 2.0f, [rightButton frame].origin.y, [rightButton frame].size.height, [rightButton frame].size.height)];
[_loadIndicator setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleTopMargin];
_loadIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
_loadIndicator.hidesWhenStopped = true;
}
return _loadIndicator;
}
That should be the relevant code...
In my ViewController:
var composeBarView: PHFComposeBarView {
var viewBounds = self.view
var frame = CGRectMake(0, viewBounds.frame.height - PHFComposeBarViewInitialHeight, viewBounds.frame.width, PHFComposeBarViewInitialHeight)
var composeBarView = PHFComposeBarView(frame: frame)
composeBarView.maxLinesCount = 6
composeBarView.placeholder = "Write some text"
composeBarView.buttonTitle = "Reply"
composeBarView.delegate = self
composeBarView.buttonTintColor = UIColor(hexString: "056A85")
composeBarView.textView.backgroundColor = UIColor.whiteColor()
return composeBarView
}
Because you're using a computed property, not a lazy property, so each time you call self.composeBarView you're creating a new instance. Your code uses the passed view to start animating, but to stop animating you're always creating a new view which obviously hasn't been displayed yet.
Change your code to:
lazy var composeBarView: PHFComposeBarView = {
var viewBounds = self.view
var frame = CGRectMake(0, viewBounds.frame.height - PHFComposeBarViewInitialHeight, viewBounds.frame.width, PHFComposeBarViewInitialHeight)
var composeBarView = PHFComposeBarView(frame: frame)
composeBarView.maxLinesCount = 6
composeBarView.placeholder = "Write some text"
composeBarView.buttonTitle = "Reply"
composeBarView.delegate = self
composeBarView.textView.backgroundColor = UIColor.whiteColor()
return composeBarView
}()
Forgive me if this is trivial, I am still honing my programing skills. I am trying to set this button as a target. Should be easy but I dont know why it's not working! I inserted a NSLog to test and the method is not being called! Thanks for your help.
//ShareView.h
#property (strong,nonatomic) UIButton *cancelBtn;
//ShareView.m
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIImage *shareImage = [UIImage imageNamed:#"shareBox.png"];
[self setFrame:CGRectMake(10, 170, shareImage.size.width, shareImage.size.height)];
self.shareIV = [[UIImageView alloc] initWithImage:shareImage];
self.shareIV.userInteractionEnabled = YES;
[self addSubview:self.shareIV];
[self shareBtnsInit];
[self.shareIV addSubview:self.cancelBtn];
self.userInteractionEnabled = YES;
}
return self;
}
-(void)shareBtnsInit{
UIImage *cancelImg = [UIImage imageNamed:#"cancel27.png"];
self.cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.cancelBtn setImage:cancelImg forState:UIControlStateNormal];
[self.cancelBtn setFrame:CGRectMake(277, 3, cancelImg.size.width, cancelImg.size.height)];
}
//MainViewController.m
-(IBAction)settingsButtonPressed:(id)sender{
self.shareVC = [[ShareView alloc] initWithFrame:CGRectMake(0, 0, 0,0)];
[self.view addSubview: self.shareVC];
[self.shareVC.cancelBtn addTarget:self action:#selector(settingsCancel:) forControlEvents:UIControlEventTouchUpInside];
}
-(IBAction)settingsCancel:(id)sender{
NSLog(#"TEST!!!");
[self.shareVC removeFromSuperview];
}
Based on comments, your settingsButtonPressed: method wasn't being called, so the button you were looking for the action on was never being set up.
Try adding [self.cancelBtn addTarget:self action:#selector(settingsCancel:) forControlEvents:UIControlEventTouchUpInside]; to your shareBtnsInit method.
Here's more information on making UIButtons programatically: How do I create a basic UIButton programmatically?
[self.cancelBtn addTarget:MainViewController action:#selector(settingsCancel:) forControlEvents:UIControlEventTouchUpInside];
In ShareView you have to import class in which you want your event should get triggered.
Here in ShareView you can import MainViewController class and can use it.
I have a grid of UIButtons. When I hit an 'edit' button, I want a delete button to appear over each of these buttons, which when pressed, deletes the button (and associated data). A bit like apple's home screen, when you hold down a button and it starts to wiggle with an X in the corner.
According to this post: Subclass UIButton to add a property I can use Associative References to add a property to each of my buttons. I've tried to add a UIButton as a property of my custom UIButton but I can't seem to get it to appear and have the feeling this isn't the right way to go. Here's my custom button main:
#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
And here's where I add the buttons programmatically:
//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];
}
Is there an easier more sensible way to do this? Or am I on the right track?
ORIGINAL RESPONSE BEGAN:
... Someone else may have more to say about that, but I'm not sure why you'd need to use object association here. You can certainly add another button to your button as a property using regular subclassing, which is the route that I would take. ...
EDITS BELOW:
I thought that I had subclassed a UI control directly, but I realized that I was mistaken when I went to look for the code. #Joe rightly pointed out in the comments that there are issues with directly subclassing UI controls.
I was able to implement something like the functionality you described without using Associated Objects, by creating a wrapper class to hold the button and its related delete button. It works, but it's not very flexible, so I would generally recommend #Joe's method as a better solution.
Here's the relevant code:
I threw all of the code into the appDelegate to keep it simple. I don't recommend that in real life.
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
This solution did not require me to implement all of the UI properties, but it did require extra work to hook up the embedded delegates, which is cumbersome. There may be a way to pass the delegates into the wrapper at initialization, but I couldn't make it work.